[R-pkg-devel] tryCatch() doesn't capture errors due to && or || with R CMD check --as-cran
Lionel Henry
||one| @end|ng |rom r@tud|o@com
Thu Sep 1 18:47:36 CEST 2022
Hi Martin,
I'm not sure I understand what you mean regarding suppressed warnings
in testthat.
- All warnings are reported to users by `devtools::test()`, with
accompanying backtraces. They are not hidden.
- R CMD check doesn't report warnings emitted from files in `tests/`.
If you need some sort of warning to surface as errors, warnings, or
notes in R CMD check, it should be possible to come up with
something. This could take the form of special classes of conditions
that R CMD check would catch and emit corresponding diagnostics
for. We would change testthat to make sure all such conditions are
properly emitted during checks.
Best,
Lionel
On 9/1/22, Martin Maechler <maechler using stat.math.ethz.ch> wrote:
>>>>>> Etienne Bacher
>>>>>> on Thu, 01 Sep 2022 13:55:15 +0000 writes:
>
>> Dear all,
>
>> Calling && or || with LHS or (if evaluated) RHS of length greater than one
>> gives an error in the devel version of R and a warning since R 4.2.0. With
>> R 4.2.1, I can capture this warning with tryCatch(). However, R CMD check
>> with R-devel fails because of this new behavior, meaning that tryCatch()
>> doesn't work.
>
> Very much on purpose, even though we (the R Core team) may not
> have said so loudly.
>
> The problem is that too many "smart" people, including the
> authors of certain widely used testing packages do call
> tryCatch(), or suppressWarnings() and similar to eliminate
> warnings and errors in a situation we really *do* want these to
> be shown.
>
> For instance, we, the Matrix package authors, have planned to
> deprecate certain usages of as(*, "<someMatrixClass>") and
> give deprecation warnings -- see help(Deprecated) -- so the
> users and package authors can see the undesired usages and
> eventually update their code.
>
> No, because of too much use of suppressWarnings() they *NEVER
> EVER* see *any* deprecation warnings for all their own code
> which silences these warnings and for all (often 100%) of their
> tests where they use the famous test...t package ...
>
> An additional reason for such a non-suppressible error is that
> when you find such warnings/errors in package testing of
> packages with many dependencies, if the warning/error is raised
> and you *do* see it, it may *still* not at all be easy to see
> from which of the (sometimes 20--100) packages that are in use
> the problem is caused.
>
> I hope you understand that such "obnoxious" behavior is
> rational and desirable in such rare cases.
>
> Best regards,
> Martin
>
>
> --
> Martin Maechler
> ETH Zurich and R Core team
>
>> For example, take this function:
>>
>> foo <- function() {
>> tryCatch(
>> if (c(TRUE, TRUE) || c(TRUE, TRUE)) 1,
>> warning = function(w) {
>> print(w)
>> NULL
>> },
>> error = function(e) {
>> print(e)
>> NULL
>> }
>> )
>> }
>>
>> With R 4.2.1, this correctly gives a warning and returns NULL when I run
>> this locally:
>> > foo()
>> <simpleWarning in c(TRUE, TRUE) || c(TRUE, TRUE): 'length(x) = 2 > 1' in
>> coercion to 'logical(1)'>
>> NULL
>>
>> And if I change the environment variables to return an error instead of
>> the warning, it correctly gives an error and returns NULL:
>> > Sys.setenv(
>> `_R_CHECK_LENGTH_1_CONDITION_` = "true",
>> `_R_CHECK_LENGTH_1_LOGIC2_` = "true"
>> )
>> >foo()
>> <simpleError in c(TRUE, TRUE) || c(TRUE, TRUE): 'length(x) = 2 > 1' in
>> coercion to 'logical(1)'>
>> NULL
>>
>> This behavior is expected. But if I put this function in a package, add a
>> test for it, and run R CMD check "." --as-cran (or
>> rcmdcheck::rcmdcheck(args = "--as-cran")), then I get an error that I
>> paste at the end of this email because it's quite long. I thought that
>> tryCatch() would capture this error, even when using R CMD check with
>> R-devel, but this is not the case. Is this an expected behavior or a bug?
>>
>> If you want to reproduce this error, I made a tiny package here:
>> https://github.com/etiennebacher/testpackage. You can simply clone the
>> repo and run R CMD check on it.
>>
>> If it matters, I'm using R 4.2.1 on Windows 10.
>>
>> Thanks in advance,
>>
>> Etienne
>>
>>
>> ----------- FAILURE REPORT --------------
>> --- failure: length > 1 in coercion to logical ---
>> --- srcref ---
>> :
>> --- package (from environment) ---
>> compiler
>> --- call from context ---
>> do.call(ffun, args)
>> --- call from argument ---
>> .Primitive("||")(c(TRUE, TRUE), c(TRUE, TRUE))
>> --- R stacktrace ---
>> where 1: do.call(ffun, args)
>> where 2: mode(e)
>> where 3: mode(e) %in% constModes
>> where 4: checkConst(do.call(ffun, args))
>> where 5: doTryCatch(return(expr), name, parentenv, handler)
>> where 6: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>> where 7: tryCatchList(expr, names[-nh], parentenv, handlers[-nh])
>> where 8: doTryCatch(return(expr), name, parentenv, handler)
>> where 9: tryCatchOne(tryCatchList(expr, names[-nh], parentenv,
>> handlers[-nh]),
>> names[nh], parentenv, handlers[[nh]])
>> where 10: tryCatchList(expr, classes, parentenv, handlers)
>> where 11: tryCatch(checkConst(do.call(ffun, args)), error = function(e)
>> NULL,
>> warning = function(w) NULL)
>> where 12: constantFoldCall(e, cntxt)
>> where 13: constantFold(test, cntxt, loc = cb$savecurloc())
>> where 14: h(e, cb, cntxt)
>> where 15: tryInline(call, cb, cntxt)
>> where 16: cmpCall(e, cb, cntxt)
>> where 17: cmp(e, cb, cntxt, setloc = FALSE)
>> where 18: genCode(a, pcntxt, loc = cb$savecurloc())
>> where 19: cb$putconst(genCode(a, pcntxt, loc = cb$savecurloc()))
>> where 20: cmpCallArgs(args, cb, cntxt, nse)
>> where 21: cmpCallSymFun(fun, args, call, cb, cntxt)
>> where 22: cmpCall(e, cb, cntxt)
>> where 23: cmp(subexp, cb, cntxt, setloc = FALSE)
>> where 24: h(e, cb, cntxt)
>> where 25: tryInline(call, cb, cntxt)
>> where 26: cmpCall(e, cb, cntxt)
>> where 27: cmp(e, cb, cntxt, setloc = FALSE)
>> where 28: genCode(body(f), ncntxt, loc = loc)
>> where 29: cmpfun(f)
>> where 30: doTryCatch(return(expr), name, parentenv, handler)
>> where 31: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>> where 32: tryCatchList(expr, classes, parentenv, handlers)
>> where 33: tryCatch(cmpfun(f), error = function(e) {
>> notifyCompilerError(paste(e$message, "at", deparse(e$call)))
>> f
>> })
>> where 34: compiler:::tryCmpfun(function ()
>> {
>> tryCatch(if (c(TRUE, TRUE) || c(TRUE, TRUE))
>> 1, warning = function(w) {
>> print(w)
>> NULL
>> }, error = function(e) {
>> print(e)
>> NULL
>> })
>> })
>> where 35: lazyLoadDBinsertVariable(vars[i], from, datafile, ascii,
>> compress,
>> envhook)
>> where 36: makeLazyLoadDB(ns, dbbase, compress = compress, set.install.dir
>> = set.install.dir)
>> where 37: code2LazyLoadDB(package, lib.loc = lib.loc, keep.source =
>> keep.source,
>> keep.parse.data = keep.parse.data, compress = compress,
>> set.install.dir = set.install.dir)
>> where 38: tools:::makeLazyLoading("testpackage",
>> "C:/Users/etienne/AppData/Local/Temp/Rtmp8QXtOL/file41b43ee61605/testpackage.Rcheck/00LOCK-TESTPA~1/00new",
>>
>> keep.source = FALSE, keep.parse.data = FALSE, set.install.dir =
>> "C:/Users/etienne/AppData/Local/Temp/Rtmp8QXtOL/file41b43ee61605/testpackage.Rcheck/testpackage")
>>
>> --- value of length: 2 type: logical ---
>> [1] TRUE TRUE
>> --- function from context ---
>> function (what, args, quote = FALSE, envir = parent.frame())
>> {
>> if (!is.list(args))
>> stop("second argument must be a list")
>> if (quote)
>> args <- lapply(args, enquote)
>> .Internal(do.call(what, args, envir))
>> }
>> <bytecode: 0x0000021b0a155e20>
>> <environment: namespace:base>
>> --- function search by body ---
>> Function do.call in namespace base has this body.
>> ----------- END OF FAILURE REPORT --------------
>> Fatal error: length > 1 in coercion to logical
>>
>
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>
More information about the R-package-devel
mailing list