make_CRANtidote: Suppress stupid CRAN notes, and facilitate use of Suggested...

make_CRANtidoteR Documentation

Suppress stupid CRAN notes, and facilitate use of Suggested packages

Description

Sigh... CRAN will reject packages with NOTE "no visible binding for global variable" from R CMD check— not WARNING, just NOTE. This is stupid because of false-positives whenever mlocal, cq, or indeed evalq or local, are called :/. Arguing with CRAN is about as productive as trying to teach a dead fish to climb trees. So, call make_CRANtidote instead, to get a bit of code that you can paste at the end of your package's .onLoad to suppress the non-problem. Your package does not need to import mvbutils to use that code.

It works by creating a dummy for each of those variables in the namespace environment, specifically a function that causes an error (stop) with the message "CRANtidote failure". It has to be a function, since as-CRAN checks look not just for variables, but for functions. Sigh.

The dummy function should never be called, and if you see that "CRANtidote failure" error message, then the dummy has masked something important. Unwanted side-effects are unlikely, but possible: here's two examples. First, when I initially tried this with mvbutils itself, it noticed that .onAttach was mentioned directly somewhere, and helpfully tried to add that— causing failure on attach(), since R tried to run a non-function .onAttach. So .onAttach is now specifically excluded to avoid this, and will need tweaking manually in your code. There might be other special things only created/needed after .onLoad that need similar attention.

The second side-effect might be more common, but is easily fixed. Suppose you requireNamespace a package (which is OK, even according to CRAN and even if it lives in a different repo, as long as it's listed in "Suggests"), but you don't want to always refer to its members by name, e.g. otherpak::funcaroo. Of course, R says you're Supposed To do the latter, but that is not always cozza increased verbosity and decreased code clarity; and e.g. what about operators a la %dopar% in parallel? Then, just call locally_import("otherpak") instead of requireNamespace("otherpak"). It will create a local copy (an "import") of all exportees in "otherpak", by default just in the frame it is called from (so the copy disappears as soon as your code finishes). The local copies will mask any dummies created by make_CRANtidote, so things should work as you expect.

locally_import might be generally useful for packages in "Suggests", even without make_CRANtidote (if you don't care about CRAN), since it saves on precious colons— and it does eliminate the unlikely-but-logically-possible problem that a synonymous function from some completely different attached package might mask the version you are hoping to call (and without locally_import, the colonless version would only work if you attach(otherpak) anyway). You can also "import" just some selected functions.

Usage

make_CRANtidote( checkout)
locally_import( pkg, funs=getNamespaceExports( pkg), to=parent.frame())

Arguments

checkout

Result of a call to check.pkg; AFAIK, it doesn't matter here whether the CRAN argument is set.

pkg

name of a package, presumably listed in "Suggests" but not necessarily

funs

which things to "import" from pkg. Default is everything that's exported by pkg. Usually it's only functions that might be imported, but I think it's conceivable that non-functions might be exported— which is fine, despite the name funs.

to

environment to create the "imports" in. The default is whatever frame locally_import is called from— so the copy will almost always be temporary. In the somewhat unlikely event that you are calling locally_import inside lapply or similar, you might need to specify e.g. to=environment().

Value

make_CRANtidote returns a character vector of class cat, which will display nicely so that you can cut-and-paste it into your .onLoad. locally_import returns TRUE or FALSE, like requireNamespace.

Examples

## Not run: 
if( FALSE && is_very_annoying( CRAN)){ # to avoid CRAN trying to run this despite dont-run :/
  test <- check.pkg( 'mypak')
  make_CRANtidote( test)
  # Some function defined in your own package.
  # This example is complete nonsense--- its only purpose is to show syntax!
  mypakfun <- function( x){
      locally_import( 'doParallel') # everything from 'doParallel'
      locally_import( 'otherpak', c( 'funcaroo', 'bo_diddley')) # just those 2
      # Look mum no double-colons
      thrub <- funcaroo( x %dopar% y)
    return( bo_diddley( thrub))
  }
}

## End(Not run)

mvbutils documentation built on May 25, 2026, 5:09 p.m.