1

Based on this Q&A , this code defines a package containing an active binding to the value 1. It passes devtools::check():

my_function <- function() 1

#' return 1
#' @usage my_active_binding
#' @name my_active_binding
NULL

.onLoad <- function(libname, pkgname) {
  ns <-  asNamespace(pkgname)
  makeActiveBinding("my_active_binding", my_function,  env = ns)
  namespaceExport(ns, "my_active_binding")
}

However if my active binding fails by default (in my use case it should be used in a specific context), then devtools::check() is not happy anymore.

Edit: actually if I use print() or message() rather than stop() I run into the same issues

my_function <- function() stop("stop!!!")

#' stop!!!
#' @usage my_active_binding
#' @name my_active_binding
NULL

.onLoad <- function(libname, pkgname) {
  ns <-  asNamespace(pkgname)
  makeActiveBinding("my_active_binding", my_function,  env = ns)
  namespaceExport(ns, "my_active_binding")
}

See below :

-- R CMD check results ---------------------------------- abtest 0.0.0.9000 ----
Duration: 21s

> checking DESCRIPTION meta-information ... WARNING
  Non-standard license specification:
    GPL3
  Standardizable: FALSE

> checking S3 generic/method consistency ... WARNING
  Error in (function ()  : stop!!!
  Calls: <Anonymous> -> Filter -> unlist -> lapply -> FUN -> <Anonymous>
  Ex�cution arr�t�e
  See section 'Generic functions and methods' in the 'Writing R
  Extensions' manual.

> checking for code/documentation mismatches ... WARNING
  Error in (function ()  : stop!!!
  Calls: <Anonymous> ... Filter -> unlist -> lapply -> FUN -> get -> <Anonymous>
  Ex�cution arr�t�e

> checking dependencies in R code ... NOTE
  Error in (function ()  : stop!!!
  Ex�cution arr�t�e

> checking foreign function calls ... NOTE
  Error in (function ()  : stop!!!
  Calls: <Anonymous> -> lapply -> FUN -> get -> <Anonymous>
  Ex�cution arr�t�e
  See chapter 'System and foreign language interfaces' in the 'Writing R
  Extensions' manual.

> checking R code for possible problems ... NOTE
  Error in (function ()  : stop!!!
  Calls: <Anonymous> ... withCallingHandlers -> do.call -> <Anonymous> -> get -> <Anonymous>
  Ex�cution arr�t�e

> checking Rd \usage sections ... NOTE
  Error in (function ()  : stop!!!
  Calls: <Anonymous> ... Filter -> unlist -> lapply -> FUN -> get -> <Anonymous>
  Ex�cution arr�t�e
  The \usage entries for S3 methods should use the \method markup and not
  their full name.
  See chapter 'Writing R documentation files' in the 'Writing R
  Extensions' manual.

0 errors v | 3 warnings x | 4 notes x
Erreur : R CMD check found WARNINGs
Ex�cution arr�t�e

Exited with status 1.

How can I do to integrate this active binding in my package and satisfy devtools::check() / R CMD check ?

moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
  • Interesting. Well, much of the code that runs during checks is in the `tools` package. The code that runs during "checking dependencies in R code" is in `tools:::.check_packages_used`. At around lines 137 or so it does `exprs <- lapply(ls(envir = code_env, all.names = TRUE), ...)` and loops over all variables in the environment and `get()`s their values to find the function bodies. This seems to be what's trigger the evaluation of the binding. – MrFlick Aug 26 '20 at 02:45
  • Would is be sufficient to only throw an error during interactive sessions? `my_function <- function() if (interactive()) stop("stop!!!")` Not sure what the intention is. – MrFlick Aug 26 '20 at 02:58
  • Thanks, I used `my_function` to print `sys.calls()` to have a better picture of what's going on, and it's all tools indeed. I made a horrible hack that might do the trick if there's no clean way : `my_function <- if(identical(sys.call(1)[[1:2]], quote(tools))) NULL else stop("stop!!!")`. i.e., if the parent call calls a function from the tool namespace, return NULL – moodymudskipper Aug 26 '20 at 02:58
  • oh yes it will definitely be interactive only – moodymudskipper Aug 26 '20 at 02:59
  • Dodging the R checks by looking at the call stack is clever. Wonder if that would pass manual review on CRAN. I think checking for interactive would be safer and it seems to get rid of the errors, but it does get triggered with RStudio autocomplete. – MrFlick Aug 26 '20 at 03:02
  • Can you develop your last sentence about autocomplete? I don't understand. – moodymudskipper Aug 26 '20 at 03:06
  • It might not be relevant, but typing `package::my_fu` etc, each time you type a letter you get the stop message. The binding seem to be reevaluated each time. But oddly that doesn't seem to happen without the double colons. So maybe never mind. – MrFlick Aug 26 '20 at 03:09
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/220466/discussion-between-moody-mudskipper-and-mrflick). – moodymudskipper Aug 26 '20 at 03:31
  • 1
    FWIW the cli package has an exported active binding called `symbol`. It is exported via the `NAMESPACE` file and defined in `.onLoad()`: https://github.com/r-lib/cli I should also say, that I would not do this again today, because it is a pain in the neck. I would just make it a regular function instead. – Gabor Csardi Aug 26 '20 at 07:18

0 Answers0