From 121566e809d334a00a3a87da8f100713781968fa Mon Sep 17 00:00:00 2001 From: Henrik Bengtsson Date: Sat, 7 May 2022 17:19:07 -0700 Subject: [PATCH] TESTS: add test for name clashing of globals in local() environments [#608] --- DESCRIPTION | 2 +- NEWS | 2 +- R/globals.R | 2 ++ R/options.R | 3 +++ tests/globals,locals.R | 43 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/globals,locals.R diff --git a/DESCRIPTION b/DESCRIPTION index 2cf76e1f..26aa0ec8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: future -Version: 1.25.0-9013 +Version: 1.25.0-9014 Title: Unified Parallel and Distributed Processing in R for Everyone Imports: digest, diff --git a/NEWS b/NEWS index 9678fc2c..87168018 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ Package: future =============== -Version: 1.25.0-9013 [2022-05-07] +Version: 1.25.0-9014 [2022-05-07] SIGNIFICANT CHANGES: diff --git a/R/globals.R b/R/globals.R index 0e1afb11..9777e3cb 100644 --- a/R/globals.R +++ b/R/globals.R @@ -101,6 +101,8 @@ getGlobalsAndPackages <- function(expr, envir = parent.frame(), tweak = tweakExp globals <- globalsOf( ## Passed to globals::findGlobals() expr, envir = envir, substitute = FALSE, tweak = tweak, + ## Requires globals (>= 0.14.0.9004); ignored otherwise + locals = getOption("future.globals.globalsOf.locals", FALSE), ## Passed to globals::findGlobals() via '...' dotdotdot = "return", method = globals.method, diff --git a/R/options.R b/R/options.R index c54b2041..cafa3e2e 100644 --- a/R/options.R +++ b/R/options.R @@ -308,6 +308,9 @@ update_package_options <- function(debug = FALSE) { ## Prototyping in future 1.23.0: update_package_option("future.output.windows.reencode", mode = "logical", debug = debug) + ## Prototyping in future 1.26.0: + update_package_option("future.globals.globalsOf.locals", mode = "logical", debug = debug) + ## SETTINGS USED FOR DEPRECATING FEATURES ## future 1.22.0: update_package_option("future.globals.keepWhere", mode = "logical", debug = debug) diff --git a/tests/globals,locals.R b/tests/globals,locals.R new file mode 100644 index 00000000..e53e2a51 --- /dev/null +++ b/tests/globals,locals.R @@ -0,0 +1,43 @@ +source("incl/start.R") +library("listenv") +oopts <- c(oopts, options( + future.globals.resolve = TRUE, + future.globals.onMissing = "error" +)) + +okeep <- list() + +message("*** Globals inside local() environments ...") + +for (strategy in supportedStrategies()) { + message(sprintf("- plan('%s') ...", strategy)) + plan(strategy) + + ## Closures with local globals of the same name + g <- local({ a <- 1; function() a }) + h <- local({ a <- 2; function() a }) + truth <- h() + g() + print(truth) + + ## Fixed in future (>= 1.25.0-9013) with globals (>= 0.14.0.9004) + ## Previously, 'a' of h() would overwrite 'a' of g(), resulting + ## in g() == 2, rather than g() == 1. + ## https://github.com/HenrikBengtsson/future/issues/608 + if (is.null(getOption("future.globals.keepWhere")) && packageVersion("globals") >= "0.14.0.9004") { + okeep <- options(future.globals.keepWhere = TRUE) + } + f <- future(h() + g()) + v <- value(f) + print(v) + + if (!strategy %in% c("sequential", "multicore") || (packageVersion("globals") >= "0.14.0.9004") && getOption("future.globals.keepWhere", FALSE)) { + stopifnot(identical(v, truth)) + options(okeep) + } else { + stopifnot(identical(v, h() + h())) + } +} ## for (strategy ...) + +message("*** Globals inside local() environments ... DONE") + +source("incl/end.R")