[Rd] suppress *specific* warnings?
Duncan Murdoch
murdoch.duncan at gmail.com
Thu Oct 25 12:51:25 CEST 2012
On 12-10-25 5:28 AM, Martin Maechler wrote:
> Sorry guys, for coming late,
> but *please* don't go there.
>
> I've been there years ago,
> and found later why the approach is flawed "by design" :
>
> Internationalization / Localization:
>
> - If the warning comes from a "standard R" function,
> the warning is almost surely different in a (say) German
> locale, and your pattern won't be detected.
>
> - Ditto if from a recommended package.
>
> - If it is a warning that is not translated then it may be that
> it is just not *YET* translated.
I think the other Martin's suggestion addressed this: he matched the
translated message, not the English original.
Duncan Murdoch
>
> The really dangerous thing about matching error / warning
> messages -- I had done it in the past with the error message I
> caught via tryCatch() --
> is that
> - in your tests the code will work perfectly.
> - on CRAN the code will work perfectly, as "they" also use
> the English (or C) locale.
>
> So, by doing this you are distributing code that "almost always"
> works ... in your environment if you are US, UK or similarly
> based.
>
> Indeed, a *really* dangerous practice.
>
> Martin Maechler, ETH Zurich
>
>
>
>
>>>>>> Martin Morgan <mtmorgan at fhcrc.org>
>>>>>> on Tue, 23 Oct 2012 05:28:48 -0700 writes:
>
> > On 10/22/2012 09:57 AM, luke-tierney at uiowa.edu wrote:
> >> On Sun, 21 Oct 2012, Martin Morgan wrote:
> >>
> >>> On 10/21/2012 12:28 PM, Ben Bolker wrote:
> >>>>
> >>>> Not desperately important, but nice to have and possibly of use to
> >>>> others, is the ability to suppress specific warnings rather than
> >>>> suppressing warnings indiscriminately. I often know of a specific
> >>>> warning that I want to ignore (because I know that's it's a false
> >>>> positive/ignorable), but the current design of suppressWarnings() forces
> >>>> me to ignore *any* warnings coming from the expression.
> >>>>
> >>>> I started to write a new version that would check and, if supplied
> >>>> with a regular expression, would only block matching warnings and
> >>>> otherwise would produce the warnings as usual, but I don't quite know
> >>>> enough about what I'm doing: see ??? in expression below.
> >>>>
> >>>> Can anyone help, or suggest pointers to relevant
> >>>> examples/documentation (I've looked at demo(error.catching), which isn't
> >>>> helping me ... ?)
> >>>>
> >>>> suppressWarnings2 <- function(expr,regex=NULL) {
> >>>> opts <- options(warn = -1)
> >>>> on.exit(options(opts))
> >>>
> >>> I'm not really sure what the options(warn=-1) is doing there, maybe its for
> >>> efficiency to avoid generating a warning message (as distinct from signalling
> >>
> >> The sources in srs/library/base/conditions.R have
> >>
> >> suppressWarnings <- function(expr) {
> >> ops <- options(warn = -1) ## FIXME: temporary hack until R_tryEval
> >> on.exit(options(ops)) ## calls are removed from methods code
> >> withCallingHandlers(expr,
> >> warning=function(w)
> >> invokeRestart("muffleWarning"))
> >> }
> >>
> >> I uspect we have still not entirely eliminated R_tryEval in this context
> >> but I'm not sure. Will check when I get a chance.
> >>
> >>> a warning). I think you're after something like
> >>>
> >>> suppressWarnings2 <-
> >>> function(expr, regex=character())
> >>> {
> >>> withCallingHandlers(expr, warning=function(w) {
> >>> if (length(regex) == 1 && length(grep(regex, conditionMessage(w)))) {
> >>> invokeRestart("muffleWarning")
> >>> }
> >>> })
> >>> }
> >>
> >> A problem with using expression matching is of course that this fails
> >> with internationalized messages. Ideally warnings should be signaled as
> >> warning conditions of a particular class, and that class can be used
> >> to discriminate. Unfortunately very few warnings are designed this way.
>
> > Probably specific messages, rather than patterns, would be handled and then
>
> > suppressWarnings2 <- function(expr, messages = character())
> > {
> > opts <- options(warn = -1)
> > on.exit(options(ops))
> > withCallingHandlers(expr, warning=function(w) {
> > if (conditionMessage(w) %in% messages)
> > invokeRestart("muffleWarning")
> > })
> > }
>
> > gives one the illusion of speaking many languages
>
> > suppressWarnings2(log(-1), gettext("NaNs introduced", domain="R"))
>
> > Martin
>
> >>
> >> Best,
> >>
> >> luke
> >>
> >>>
> >>> If the restart isn't invoked, then the next handler is called and the warning
> >>> is handled as normal. So with
> >>>
> >>> f <- function() {
> >>> warning("oops")
> >>> 2
> >>> }
> >>>
> >>> there is
> >>>
> >>>> suppressWarnings2(f())
> >>> [1] 2
> >>> Warning message:
> >>> In f() : oops
> >>>> suppressWarnings2(f(), "oops")
> >>> [1] 2
> >>>
> >>> For your own code I think a better strategy is to create a sub-class of
> >>> warnings that can be handled differently
> >>>
> >>> mywarn <-
> >>> function(..., call.=TRUE, immediate.=FALSE, domain=NULL)
> >>> {
> >>> msg <- .makeMessage(..., domain=domain, appendLF=FALSE)
> >>> call <- NULL
> >>> if (call.)
> >>> call <- sys.call(1L)
> >>> class <- c("silencable", "simpleWarning", "warning", "condition")
> >>> cond <- structure(list(message=msg, call=call), class=class)
> >>> warning(cond)
> >>> }
> >>>
> >>> suppressWarnings3 <-
> >>> function(expr)
> >>> {
> >>> withCallingHandlers(expr, silencable=function(w) {
> >>> invokeRestart("muffleWarning")
> >>> })
> >>> }
> >>>
> >>> then with
> >>>
> >>> g <- function() {
> >>> mywarn("oops")
> >>> 3
> >>> }
> >>>
> >>>> suppressWarnings3(f())
> >>> [1] 2
> >>> Warning message:
> >>> In f() : oops
> >>>> g()
> >>> [1] 3
> >>> Warning message:
> >>> In g() : oops
> >>>> suppressWarnings3(g())
> >>> [1] 3
> >>>
> >>>> withCallingHandlers(expr, warning = function(w) {
> >>>> ## browser()
> >>>> if (is.null(regex) || grepl(w[["message"]],regex)) {
> >>>> invokeRestart("muffleWarning")
> >>>> } else {
> >>>> ## ? what do I here to get the warning issued?
> >>>> ## browser()
> >>>> ## computeRestarts() shows "browser",
> >>>> ## "muffleWarning", and "abort" ...
> >>>> options(opts)
> >>>> warning(w$message)
> >>>> ## how can I get back from here to the calling point
> >>>> ## *without* muffling warnings ... ?
> >>>> }
> >>>> })
> >>>> }
> >>>>
> >>>> suppressWarnings2(sqrt(-1))
> >>>> suppressWarnings2(sqrt(-1),"abc")
> >>>>
> >>>> It seems to me I'd like to have a restart option that just returns to
> >>>> the point where the warning was caught, *without* muffling warnings ...
> >>>> ? But I don't quite understand how to set one up ...
> >>>>
> >>>> Ben Bolker
> >>>>
> >>>> ______________________________________________
> >>>> R-devel at r-project.org mailing list
> >>>> https://stat.ethz.ch/mailman/listinfo/r-devel
> >>>>
> >>>
> >>>
> >>>
> >>
>
>
> > --
> > Computational Biology / Fred Hutchinson Cancer Research Center
> > 1100 Fairview Ave. N.
> > PO Box 19024 Seattle, WA 98109
>
> > Location: Arnold Building M1 B861
> > Phone: (206) 667-2793
>
> > ______________________________________________
> > R-devel at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
More information about the R-devel
mailing list