Skip to content

Commit 99ffba7

Browse files
Now getGlobalsAndPackages() fixes the environment() of FUN(), if needed
1 parent f2aa978 commit 99ffba7

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: future
2-
Version: 1.34.0-9116
2+
Version: 1.34.0-9117
33
Title: Unified Parallel and Distributed Processing in R for Everyone
44
Imports:
55
digest,

R/globals.R

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,46 @@ getGlobalsAndPackages <- function(expr, envir = parent.frame(), tweak = tweakExp
236236
## To please R CMD check
237237
a <- `future.call.arguments` <- NULL
238238
rm(list = c("a", "future.call.arguments"))
239+
240+
## If ...future.FUN() in globals, then ...
241+
if ("...future.FUN" %in% names(globals)) {
242+
envFUN <- environment(globals[["...future.FUN"]])
243+
## Update environment of FUN(), unless it's a primitive function
244+
## or a function in a namespace
245+
if (!is.null(envFUN) && !isNamespace(envFUN)) {
246+
expr <- substitute({
247+
"# future::getGlobalsAndPackages(): FUN() uses '...' internally "
248+
"# without having an '...' argument. This means '...' is treated"
249+
"# as a global variable. This may happen when FUN() is an "
250+
"# anonymous function. "
251+
"# "
252+
"# If an anonymous function, we will make sure to restore the "
253+
"# function environment of FUN() to the calling environment. "
254+
"# We assume FUN() an anonymous function if it lives in the "
255+
"# global environment, which is where globals are written. "
256+
penv <- env <- environment(...future.FUN)
257+
repeat {
258+
if (identical(env, globalenv()) || identical(env, emptyenv()))
259+
break
260+
penv <- env
261+
env <- parent.env(env)
262+
}
263+
if (identical(penv, globalenv())) {
264+
environment(...future.FUN) <- environment()
265+
} else if (!identical(penv, emptyenv()) && !is.null(penv) && !isNamespace(penv)) {
266+
parent.env(penv) <- environment()
267+
}
268+
rm(list = c("env", "penv"), inherits = FALSE)
269+
a
270+
}, list(a = expr))
271+
}
272+
}
273+
239274
expr <- substitute({
240-
## covr: skip=1
241275
"# future::getGlobalsAndPackages(): wrapping the original future"
242276
"# expression in do.call(), because function called uses '...' "
243277
"# as a global variable "
278+
## covr: skip=1
244279
do.call(function(...) a, args = `future.call.arguments`)
245280
}, list(a = expr))
246281
if (debug) {

0 commit comments

Comments
 (0)