[med-svn] [r-cran-future] 01/03: New upstream version 1.6.2

Andreas Tille tille at debian.org
Mon Oct 23 17:55:59 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository r-cran-future.

commit ecf10d9dc7f0db31b35e02b474e173a44bb989f5
Author: Andreas Tille <tille at debian.org>
Date:   Mon Oct 23 19:43:31 2017 +0200

    New upstream version 1.6.2
---
 DESCRIPTION                        |   8 +++---
 MD5                                |  40 +++++++++++++-------------
 NAMESPACE                          |   1 +
 NEWS                               |  18 ++++++++++++
 R/ClusterFuture-class.R            |   7 ++---
 R/Future-class.R                   |   3 +-
 R/backtrace.R                      |   9 ++++--
 R/options.R                        |   2 +-
 R/tweak.R                          |  31 +++++++++++++-------
 R/utils.R                          |  57 +++++++++++++++++++------------------
 R/zzz.plan.R                       |   2 +-
 build/vignette.rds                 | Bin 425 -> 426 bytes
 inst/doc/future-1-overview.html    |   2 +-
 inst/doc/future-1-overview.md.rsp  |   2 +-
 man/future.options.Rd              |   2 +-
 man/plan.Rd                        |   9 +++---
 tests/backtrace.R                  |  27 ++++++++++++++++++
 tests/objectSize.R                 |   4 ++-
 tests/plan.R                       |   4 +++
 tests/utils.R                      |  33 +++++++++++++++++++++
 vignettes/future-1-overview.md.rsp |   2 +-
 21 files changed, 184 insertions(+), 79 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
index 9020688..201a726 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,7 +1,7 @@
 Package: future
-Version: 1.6.1
+Version: 1.6.2
 Title: Unified Parallel and Distributed Processing in R for Everyone
-Imports: digest, globals (>= 0.10.2), listenv (>= 0.6.0), parallel,
+Imports: digest, globals (>= 0.10.3), listenv (>= 0.6.0), parallel,
         utils
 Suggests: R.rsp, markdown
 VignetteBuilder: R.rsp
@@ -29,8 +29,8 @@ URL: https://github.com/HenrikBengtsson/future
 BugReports: https://github.com/HenrikBengtsson/future/issues
 RoxygenNote: 6.0.1
 NeedsCompilation: no
-Packaged: 2017-09-09 03:46:22 UTC; hb
+Packaged: 2017-10-16 21:58:40 UTC; hb
 Author: Henrik Bengtsson [aut, cre, cph]
 Maintainer: Henrik Bengtsson <henrikb at braju.com>
 Repository: CRAN
-Date/Publication: 2017-09-09 14:52:37 UTC
+Date/Publication: 2017-10-16 22:57:04 UTC
diff --git a/MD5 b/MD5
index 194d4a4..2f96347 100644
--- a/MD5
+++ b/MD5
@@ -1,11 +1,11 @@
-88ab6edf52c8321e82435363248e7794 *DESCRIPTION
-136c0763e91559628c93dd45a7005ebb *NAMESPACE
-30c6ca2cc1c6dbf9b51938b7c0d34746 *NEWS
-5c414ed9302ea14ce03113003c6cdb2f *R/ClusterFuture-class.R
+5b1ae3f02d8611de049e70e7e6dc21b9 *DESCRIPTION
+7d6ac9ec46bcca6e0f1c9d100aa3bb09 *NAMESPACE
+c4852f7037f55100dbd23567ade8895a *NEWS
+690cf8aa536324fc21a038b878c49fbc *R/ClusterFuture-class.R
 25eb4e4c173145fa8dc98ffe50a352b0 *R/ClusterRegistry.R
 5330c624a1a8e1a17da56d44c3c71c72 *R/ConstantFuture-class.R
 57612b9c4a5965bbd55226b149f75735 *R/DEPRECATED.R
-6bb33f2db9231dfe8aea1daca60a66a3 *R/Future-class.R
+5558ec3c7a146ccaeb8b9854b6cdf38d *R/Future-class.R
 3a7018fa40706bbbc80e1972f8c5ef20 *R/FutureError-class.R
 c885fb70124ad447ee40f790ebfa1454 *R/FutureGlobals-class.R
 619d6434d29e79e468fcbde6a887817a *R/FutureRegistry.R
@@ -16,7 +16,7 @@ f8cb8f189a38870c91a256b033004acf *R/MultiprocessFuture-class.R
 f1c08954d0788f9b790aaea1fa0cb4b6 *R/as.cluster.R
 83b5826ba5553a8334a4728b8f096d5a *R/availableCores.R
 d957edb0e324e83a1bf957a661eb0a23 *R/availableWorkers.R
-a44339cfd90f7d2ca7525446ed35b62d *R/backtrace.R
+30d9798b23069dce285d2b16943f4241 *R/backtrace.R
 dd0d3d02a95c675d93bd30d8138cffff *R/cluster.R
 eea4e0cb9e96f0cb0a510476eee7ef08 *R/constant.R
 21e1147f4add566ba1cea876b5d3109c *R/future.R
@@ -36,7 +36,7 @@ b5d17e298ed318968c3b45a754e3152b *R/multicore.R
 3144b7092008bf757f97984c7018f1e1 *R/multiprocess.R
 5b4aea4d72b8c9bd3a05b784dde704b4 *R/multisession.R
 0ca5e9c5c788b38246c025d1650c29bd *R/nbrOfWorkers.R
-b59289bd556933c03b2e994d961a92ec *R/options.R
+40f5ba683e2b82cc74b50432393f2e4a *R/options.R
 96b0a255d72b99278999aa8fad8ab955 *R/plan_OP.R
 f7d31d5b8bc089af79373dd8b9021c9e *R/remote.R
 2af8d22fdd25ec5700a8a8aaafe258ca *R/resolve.R
@@ -45,20 +45,20 @@ db685ac795c66040d7f820fefcf5e5a5 *R/resolved.R
 225f984078d92ece8d6f56dc2a928158 *R/sequential.R
 825b96f24ad1a79e1f8d02dd4f921fbd *R/sessionDetails.R
 3ed78632adcd9e9e37fbb2388adf4ddd *R/signalEarly.R
-b4573b7471cbc764e97798e63be5ce94 *R/tweak.R
+8eaa75dcb3ee634418464df6e4b46f2d *R/tweak.R
 cb7361a19698a4c77d0e51d5b80bd081 *R/tweakExpression.R
 5be8fd50a0eb136864afc69519066c4d *R/tweak_OP.R
-ed16e04164a37b2e606008ad51bf99fe *R/utils.R
+1116f5849a35279a1a76329f37fbce0d *R/utils.R
 73be516a4466ee3d21f721fd4e40cc4f *R/values.R
 16c3ca1d6edf4ed7e9a191755531cd44 *R/whichIndex.R
 ddc48c6f16b7d85f3a3abfb7938afd6f *R/zzz.R
-94bcafc3d8f1703feba7b7f42e232e5c *R/zzz.plan.R
-ff9ac56d90c3279a89a8e2b755ef7601 *build/vignette.rds
+7e44dcbce179a470420f84f954bb8e3f *R/zzz.plan.R
+6b100406554ea3024d93123b82a76a7d *build/vignette.rds
 f615957051c16ab204dab55cf45ec170 *demo/00Index
 47f62f9433fb92c1e8245c6e919336e2 *demo/fibonacci.R
 68470d445b899ca10d30fef6e4638d26 *demo/mandelbrot.R
-c0f7eae3869f6ccadaeee885d48411d7 *inst/doc/future-1-overview.html
-830efe4418dd98d2c322ca6910820c77 *inst/doc/future-1-overview.md.rsp
+a0efbf56fdd377d39aba12a6e281a0ba *inst/doc/future-1-overview.html
+724b867dac1af7bc05bfd0b1ffa46b88 *inst/doc/future-1-overview.md.rsp
 5be8acaa8cb677a3f8ccf725eeb8c1b2 *inst/doc/future-2-issues.html
 a7627bebdea7629c7c87f941fdc6e26f *inst/doc/future-2-issues.md.rsp
 5f28dc8a09460fa467a4b23a9200d91b *inst/doc/future-3-topologies.html
@@ -82,7 +82,7 @@ e2f5ebe12ea08dde1d29ac54a5cd3ea8 *man/availableWorkers.Rd
 577342e28a4397af240077cfe079fa4c *man/backtrace.Rd
 5c1b80859b14f145354c875942ebe3bf *man/cluster.Rd
 8a8dd6a0ae32aba2f50e4b438cb60e4b *man/future.Rd
-037abe36c9eddbb29d5dca48b5a89bd3 *man/future.options.Rd
+c5bc22f84475ff4037abd60047e1b3c6 *man/future.options.Rd
 bdb5ed06a66c5d2d26ac207cb007a628 *man/futureOf.Rd
 b9a5c0fb77d6be3564179b25ac1b122e *man/future_lapply.Rd
 4d365d5b4666ea7f1e32402fc4175f5e *man/futures.Rd
@@ -100,7 +100,7 @@ f164c1bcbcc990b53b3c3f4e60f7a5b3 *man/grapes-label-grapes.Rd
 91e9d5428ba21326efd68481ec09bf35 *man/multiprocess.Rd
 a68ddbf53293739aae4c407bc4c450ae *man/multisession.Rd
 1b46683e11efe3a19ec538271bd96a9c *man/nbrOfWorkers.Rd
-b54b71bcd0856dc0a3ef2b11861d69a5 *man/plan.Rd
+9e8e59ebecb5a14961f1e8e40d5e2590 *man/plan.Rd
 0e9265cff7b5a98e4ccd4fe831d84a95 *man/private_length.Rd
 b695ad86222f10f461b382957678e025 *man/remote.Rd
 4c3f8a7e398b842641b73234978fc8f6 *man/requestCore.Rd
@@ -124,7 +124,7 @@ a81713c8b714cff38af45ba68a733932 *tests/FutureGlobals.R
 88c743d5b06f005e5b22b32ffc34f729 *tests/as.cluster.R
 68a584d21d55d9380702d3fc9e9a1225 *tests/availableCores.R
 7e776c43a35e5a4c3ec33f91e324414d *tests/availableWorkers.R
-665abf9fc09c8dbcaae4dbf9f2515a66 *tests/backtrace.R
+7000b08bb60d7898fcac625024bc3d4f *tests/backtrace.R
 27bcb4f9f9fc0fe7f589e7e2c985df5d *tests/cluster.R
 748ce966bb4fd9af41b2544ea74fe4ba *tests/constant.R
 98ffc71da89ce76e29f4378eb1da30e0 *tests/demo.R
@@ -165,8 +165,8 @@ dd6c1a242f70de57c8b4cfae8708f28f *tests/multisession.R
 7912309132cdd7676fbb4a072047733f *tests/nbrOfWorkers.R
 c521abb9142baf89e4cdf1a13fd9fcdd *tests/nested_futures,mc.cores.R
 a2e6432c332b4a7dfebeef93b521085a *tests/nested_futures.R
-8d116f6bac49ac2ed64b92f7a1c941b6 *tests/objectSize.R
-2e0dcced84c825950da3f109790a3410 *tests/plan.R
+ccb27e01ef763f65c5ce4c571dc5b13e *tests/objectSize.R
+e0ed66214f615e2de5c8cb03de316afa *tests/plan.R
 ef3c27448710c6e2f57f2d6a3b3fc622 *tests/remote.R
 f97146e6891c43e50671382dc0fb250a *tests/requestCore.R
 03197f27e44cfa4a217efa9f22523d41 *tests/requestNode.R
@@ -177,10 +177,10 @@ e92b81a321852bb88dc44d86d8eaf559 *tests/resolve.R
 2039fd0201b583dc625c2d938c041957 *tests/startup.R
 11f3f8007dd49fbb886b5928ed799823 *tests/transparent.R
 a61d28dc4231679167ba9e1934412cc9 *tests/tweak.R
-a60f478eeb974dea72fe008d33d6e453 *tests/utils.R
+243f656000d8b6c71b34c4ed02fb3dc3 *tests/utils.R
 9ad5052290b053b8d5891e1a1ca637ad *tests/uuid.R
 ed8892a82f5133d60c146afa2646feea *tests/whichIndex.R
-830efe4418dd98d2c322ca6910820c77 *vignettes/future-1-overview.md.rsp
+724b867dac1af7bc05bfd0b1ffa46b88 *vignettes/future-1-overview.md.rsp
 a7627bebdea7629c7c87f941fdc6e26f *vignettes/future-2-issues.md.rsp
 4e8983ff33bd203c056ab316e5195a9d *vignettes/future-3-topologies.md.rsp
 69c2c9f7f41deee3a7a57829ba33dcf6 *vignettes/future-4-startup.md.rsp
diff --git a/NAMESPACE b/NAMESPACE
index bda046e..8983210 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -143,6 +143,7 @@ importFrom(parallel,splitIndices)
 importFrom(parallel,stopCluster)
 importFrom(utils,capture.output)
 importFrom(utils,file_test)
+importFrom(utils,getS3method)
 importFrom(utils,head)
 importFrom(utils,object.size)
 importFrom(utils,read.table)
diff --git a/NEWS b/NEWS
index cf4ca63..ed03c94 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,24 @@
 Package: future
 ===============
 
+Version: 1.6.2 [2017-10-16]
+
+NEW FEATURES:
+
+ o Now plan() accepts also strings such as "future::cluster".
+
+ o Now backtrace(x[[el]]) works also for non-environment 'x':s, e.g. lists.
+
+BUG FIXES:
+
+ o When measuring the size of globals by scanning their content, for certain
+   types of classes the inferred lengths of these objects were incorrect
+   causing internal subset out-of-range issues.
+
+ o print() for Future would output one global per line instead of
+   concatenating the information with commas.
+
+
 Version: 1.6.1 [2017-09-08]
 
 NEW FEATURES:
diff --git a/R/ClusterFuture-class.R b/R/ClusterFuture-class.R
index c133bad..9bb9539 100644
--- a/R/ClusterFuture-class.R
+++ b/R/ClusterFuture-class.R
@@ -233,10 +233,9 @@ resolved.ClusterFuture <- function(x, timeout = 0.2, ...) {
   ## is _not_ the case for MPI clusters.  /HB 2017-03-06
   con <- node$con
   if (!is.null(con)) {
-    ## WORKAROUND: Non-integer timeouts (at least < 2.0 seconds) may
-    ## result in infinite waiting, cf. 
-    ## https://stat.ethz.ch/pipermail/r-devel/2016-October/073218.html
-    if (.Platform$OS.type != "windows") {
+    ## WORKAROUND: Non-integer timeouts (at least < 2.0 seconds) may result in
+    ## infinite waiting (PR17203).  Fixed in R devel r73470 (2017-10-05).
+    if (.Platform$OS.type != "windows" && getRversion() < "3.5.0") {
       timeout <- round(timeout, digits = 0L)
     }
     res <- socketSelect(list(con), write = FALSE, timeout = timeout)
diff --git a/R/Future-class.R b/R/Future-class.R
index b3fbf9c..1f24ae9 100644
--- a/R/Future-class.R
+++ b/R/Future-class.R
@@ -137,7 +137,8 @@ print.Future <- function(x, ...) {
     g <- head(g, n = 5L)
     gSizes <- head(gSizes, n = 5L)
     g <- sprintf("%s %s of %s", sapply(g, FUN = function(x) class(x)[1]), sQuote(names(g)), sapply(gSizes, FUN = asIEC))
-    if (ng > 5L) g <- sprintf("%s ...", g)
+    if (ng > length(g)) g <- c(g, "...")
+    g <- hpaste(g, maxHead = 5L, maxTail = 0L)
     cat(sprintf("Globals: %d objects totaling %s (%s)\n", ng, asIEC(gTotalSize), g))
   } else {
     cat("Globals: <none>\n")
diff --git a/R/backtrace.R b/R/backtrace.R
index 0dbfc7f..37f6286 100644
--- a/R/backtrace.R
+++ b/R/backtrace.R
@@ -12,8 +12,13 @@ backtrace <- function(future, envir = parent.frame(), ...) {
   expr <- substitute(future)
 
   if (!is.null(expr)) {
-    target <- parse_env_subset(expr, envir = envir, substitute = FALSE)
-    future <- get_future(target, mustExist = TRUE)
+    future <- tryCatch({
+      target <- parse_env_subset(expr, envir = envir, substitute = FALSE)
+      get_future(target, mustExist = TRUE)
+    }, simpleError = function(ex) {
+      eval(expr, envir = envir)
+    })
+    stopifnot(inherits(future, "Future"))    
   }
 
   if (!resolved(future)) {
diff --git a/R/options.R b/R/options.R
index 5874683..a0f6973 100644
--- a/R/options.R
+++ b/R/options.R
@@ -9,7 +9,7 @@
 #'  \item{\option{future.plan}:}{Default future strategy plan used unless otherwise specified via \code{\link{plan}()}. This will also be the future plan set when calling \code{plan("default")}.  If not specified, this option may be set when the \pkg{future} package is \emph{loaded} if command-line option \code{--parallel=ncores} (short \code{-p ncores}) is specified; if \code{ncores > 1}, then option \option{future.plan} is set to \code{multiprocess} otherwise \code{sequential} (in addi [...]
 #'  \item{\option{future.globals.onMissing}:}{Action to take when non-existing global variables ("globals" or "unknowns") are identified when the future is created.  If \code{"error"}, an error is generated immediately.  If \code{"ignore"}, no action is taken and an attempt to evaluate the future expression will be made.  The latter is useful when there is a risk for false-positive globals being identified, e.g. when future expression contains non-standard evaluation (NSE).  (Default: \c [...]
 #'  \item{\option{future.globals.method}:}{Method used to identify globals. For details, see \code{\link[globals]{globalsOf}()}. (Default: \code{"ordered"})}
-#'  \item{\option{future.globals.maxSize}:}{Maximum allowed total size (in bytes) of global variables identified. Used to prevent too large exports. (Default: \code{500 * 1024 ^ 2} = 500 MiB)}
+#'  \item{\option{future.globals.maxSize}:}{Maximum allowed total size (in bytes) of global variables identified. Used to prevent too large exports. If set of \code{+Inf}, then the check for large globals is skipped. (Default: \code{500 * 1024 ^ 2} = 500 MiB)}
 #'  \item{\option{future.globals.resolve}:}{If \code{TRUE}, globals that are \code{\link{Future}} objects (typically created as \emph{explicit} futures) will be resolved and have their values (using \code{value()}) collected.  Because searching for unresolved futures among globals (including their content) can be expensive, the default is not to do it and instead leave it to the run-time checks that assert proper ownership when resolving futures and collecting their values. (Default: \co [...]
 #'  \item{\option{future.resolve.recursive}:}{An integer specifying the maximum recursive depth to which futures should be resolved. If negative, nothing is resolved.  If \code{0}, only the future itself is resolved.  If \code{1}, the future and any of its elements that are futures are resolved, and so on. If \code{+Inf}, infinite search depth is used. (Default: \code{0})}
 #'  \item{\option{future.wait.timeout}:}{Maximum waiting time (in seconds) for a free worker before a timeout error is generated. (Default: \code{30 * 24 * 60 * 60} (= 30 days))}
diff --git a/R/tweak.R b/R/tweak.R
index e175efd..3094c5f 100644
--- a/R/tweak.R
+++ b/R/tweak.R
@@ -17,18 +17,29 @@ tweak <- function(strategy, ..., penvir = parent.frame()) UseMethod("tweak")
 
 #' @export
 tweak.character <- function(strategy, ..., penvir = parent.frame()) {
-  ## Search attached packages and the 'future' package
-  ## for a future function with this name
-  envirs <- list(penvir, future = getNamespace("future"), NULL)
-  for (envir in envirs) {
-    ## Reached the end? Nothing found.
-    if (is.null(envir)) {
+  parts <- strsplit(strategy, split = "::", fixed = TRUE)[[1]]
+  nparts <- length(parts)
+  if (nparts == 2) {
+    envir <- getNamespace(parts[[1]])
+    s <- parts[[2]]
+    if (!exists(s, mode = "function", envir = envir, inherits = TRUE)) {
       stop("No such strategy for futures: ", sQuote(strategy))
     }
-
-    if (exists(strategy, mode = "function", envir = envir, inherits = TRUE)) {
-      strategy <- get(strategy, mode = "function", envir = envir, inherits = TRUE)
-      break
+    strategy <- get(s, mode = "function", envir = envir, inherits = TRUE)
+  } else {
+    ## Search attached packages and the 'future' package
+    ## for a future function with this name
+    envirs <- list(penvir, future = getNamespace("future"), NULL)
+    for (envir in envirs) {
+      ## Reached the end? Nothing found.
+      if (is.null(envir)) {
+        stop("No such strategy for futures: ", sQuote(strategy))
+      }
+  
+      if (exists(strategy, mode = "function", envir = envir, inherits = TRUE)) {
+        strategy <- get(strategy, mode = "function", envir = envir, inherits = TRUE)
+        break
+      }
     }
   }
 
diff --git a/R/utils.R b/R/utils.R
index 5711f7b..957587b 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -475,44 +475,45 @@ objectSize <- function(x, depth = 3L) {
 
   ## Nothing more to do?
   if (depth == 1) return(size)
-  
+
   .scannedEnvs <- new.env()
   scanned <- function(e) {
-    for (name in names(.scannedEnvs)) if (identical(e, .scannedEnvs[[name]])) return(TRUE)
+    for (name in names(.scannedEnvs))
+      if (identical(e, .scannedEnvs[[name]])) return(TRUE)
     FALSE
   }
-
-  objectSize.FutureGlobals <- function(x, ...) {
-    size <- attr(x, "total_size")
-    if (!is.na(size)) return(size)
-    objectSize.list(x, ...)
-  }
   
-  objectSize.list <- function(x, depth) {
-    # Nothing to do?
+  objectSize_list <- function(x, depth) {
+    ## Nothing to do?
     if (depth <= 0) return(0)
+
+    if (inherits(x, "FutureGlobals")) {
+      size <- attr(x, "total_size")
+      if (!is.na(size)) return(size)
+    }
+
     depth <- depth - 1L
     size <- 0
 
     ## Use the true length that corresponds to what .subset2() uses
     nx <- .length(x)
-    
+
     for (kk in seq_len(nx)) {
       ## NOTE: Use non-class dispatching subsetting to avoid infinite loop,
       ## e.g. x <- packageVersion("future") gives x[[1]] == x.
       x_kk <- .subset2(x, kk)
       if (is.list(x_kk)) {
-        size <- size + objectSize.list(x_kk, depth = depth)
+        size <- size + objectSize_list(x_kk, depth = depth)
       } else if (is.environment(x_kk)) {
-        if (!scanned(x_kk)) size <- size + objectSize.env(x_kk, depth = depth)
+        if (!scanned(x_kk)) size <- size + objectSize_env(x_kk, depth = depth)
       } else {
         size <- size + unclass(object.size(x_kk))
       }
     }
     size
-  } ## objectSize.list()
+  } ## objectSize_list()
   
-  objectSize.env <- function(x, depth) {
+  objectSize_env <- function(x, depth) {
     # Nothing to do?
     if (depth <= 0) return(0)
     depth <- depth - 1L
@@ -557,11 +558,11 @@ objectSize <- function(x, depth = 3L) {
       if (missing(x_kk)) next
       
       if (is.list(x_kk)) {
-        size <- size + objectSize.list(x_kk, depth = depth)
+        size <- size + objectSize_list(x_kk, depth = depth)
       } else if (is.environment(x_kk)) {
 ##        if (!inherits(x_kk, "Future") && !scanned(x_kk)) {
         if (!scanned(x_kk)) {
-          size <- size + objectSize.env(x_kk, depth = depth)
+          size <- size + objectSize_env(x_kk, depth = depth)
         }
       } else {
         size <- size + unclass(object.size(x_kk))
@@ -569,16 +570,16 @@ objectSize <- function(x, depth = 3L) {
     }
   
     size
-  } ## objectSize.env()
+  } ## objectSize_env()
 
   ## Suppress "Warning message:
   ##   In doTryCatch(return(expr), name, parentenv, handler) :
-  ##   restarting interrupted promise evaluation
+  ##   restarting interrupted promise evaluation"
   suppressWarnings({
     if (is.list(x)) {
-      size <- size + objectSize.list(x, depth = depth - 1L)
+      size <- size + objectSize_list(x, depth = depth - 1L)
     } else if (is.environment(x)) {
-      size <- size + objectSize.env(x, depth = depth - 1L)
+      size <- size + objectSize_env(x, depth = depth - 1L)
     }
   })
 
@@ -683,6 +684,7 @@ as_lecyer_cmrg_seed <- function(seed) {
 #' 
 #' @keywords internal
 #' @rdname private_length
+#' @importFrom utils getS3method
 .length <- function(x) {
   nx <- length(x)
   
@@ -692,12 +694,13 @@ as_lecyer_cmrg_seed <- function(seed) {
   if (length(classes) == 1L && classes == "list") return(nx)
 
   ## Identify all length() methods for this object
-  mthds <- sprintf("length.%s", classes)
-  keep <- lapply(mthds, FUN = exists, mode = "function", inherits = TRUE)
-  keep <- unlist(keep, use.names = FALSE)
+  for (class in classes) {
+    fun <- getS3method("length", class, optional = TRUE)
+    if (!is.null(fun)) {
+      nx <- length(unclass(x))
+      break
+    }
+  }
 
-  ## If found, don't trust them
-  if (any(keep)) nx <- length(unclass(x))
-  
   nx
 } ## .length()
diff --git a/R/zzz.plan.R b/R/zzz.plan.R
index 6334ddf..953aa8d 100644
--- a/R/zzz.plan.R
+++ b/R/zzz.plan.R
@@ -168,7 +168,7 @@ plan <- local({
         if (inherits(strategy[[ii]], "lazy")) {
           .Defunct(msg = "Future strategy 'lazy' is defunct. Lazy evaluation can no longer be set via plan(). Instead, use f <- future(..., lazy = TRUE) or v %<-% { ... } %lazy% TRUE.")
         } else if (inherits(strategy[[ii]], "lazy")) {
-          .Defunct(msg = "Future strategy 'eager' is defunct. Please use 'sequential' instead, which works identical.")
+          .Defunct(msg = "Future strategy 'eager' is defunct. Please use 'sequential' instead, which works identically.")
         }
       }
 
diff --git a/build/vignette.rds b/build/vignette.rds
index bf89cf7..8e854da 100644
Binary files a/build/vignette.rds and b/build/vignette.rds differ
diff --git a/inst/doc/future-1-overview.html b/inst/doc/future-1-overview.html
index 9528192..c5a9020 100644
--- a/inst/doc/future-1-overview.html
+++ b/inst/doc/future-1-overview.html
@@ -250,7 +250,7 @@ Resolving...
 </code></pre>
 
 <p>With asynchronous futures, the current/main R process does <em>not</em> block, which means it is available for further processing while the futures are being resolved
-in separates processes running in the background.  In other words, futures provide a simple but yet powerful construct for parallel and / or distributed processing in R.</p>
+in separate processes running in the background.  In other words, futures provide a simple but yet powerful construct for parallel and / or distributed processing in R.</p>
 
 <p>Now, if you cannot be bothered to read all the nitty-gritty details about futures, but just want to try them out, then skip to the end to play with the Mandelbrot demo using both parallel and non-parallel evaluation.</p>
 
diff --git a/inst/doc/future-1-overview.md.rsp b/inst/doc/future-1-overview.md.rsp
index 847e8b9..b9d490e 100644
--- a/inst/doc/future-1-overview.md.rsp
+++ b/inst/doc/future-1-overview.md.rsp
@@ -61,7 +61,7 @@ So why are futures useful?  Because we can choose to evaluate the future express
 [1] 3.14
 ```
 With asynchronous futures, the current/main R process does _not_ block, which means it is available for further processing while the futures are being resolved
-in separates processes running in the background.  In other words, futures provide a simple but yet powerful construct for parallel and / or distributed processing in R.
+in separate processes running in the background.  In other words, futures provide a simple but yet powerful construct for parallel and / or distributed processing in R.
 
 
 Now, if you cannot be bothered to read all the nitty-gritty details about futures, but just want to try them out, then skip to the end to play with the Mandelbrot demo using both parallel and non-parallel evaluation.
diff --git a/man/future.options.Rd b/man/future.options.Rd
index bb6529e..3acffa4 100644
--- a/man/future.options.Rd
+++ b/man/future.options.Rd
@@ -33,7 +33,7 @@ Below are all \R options that are currently used by the \pkg{future} package and
  \item{\option{future.plan}:}{Default future strategy plan used unless otherwise specified via \code{\link{plan}()}. This will also be the future plan set when calling \code{plan("default")}.  If not specified, this option may be set when the \pkg{future} package is \emph{loaded} if command-line option \code{--parallel=ncores} (short \code{-p ncores}) is specified; if \code{ncores > 1}, then option \option{future.plan} is set to \code{multiprocess} otherwise \code{sequential} (in additio [...]
  \item{\option{future.globals.onMissing}:}{Action to take when non-existing global variables ("globals" or "unknowns") are identified when the future is created.  If \code{"error"}, an error is generated immediately.  If \code{"ignore"}, no action is taken and an attempt to evaluate the future expression will be made.  The latter is useful when there is a risk for false-positive globals being identified, e.g. when future expression contains non-standard evaluation (NSE).  (Default: \code [...]
  \item{\option{future.globals.method}:}{Method used to identify globals. For details, see \code{\link[globals]{globalsOf}()}. (Default: \code{"ordered"})}
- \item{\option{future.globals.maxSize}:}{Maximum allowed total size (in bytes) of global variables identified. Used to prevent too large exports. (Default: \code{500 * 1024 ^ 2} = 500 MiB)}
+ \item{\option{future.globals.maxSize}:}{Maximum allowed total size (in bytes) of global variables identified. Used to prevent too large exports. If set of \code{+Inf}, then the check for large globals is skipped. (Default: \code{500 * 1024 ^ 2} = 500 MiB)}
  \item{\option{future.globals.resolve}:}{If \code{TRUE}, globals that are \code{\link{Future}} objects (typically created as \emph{explicit} futures) will be resolved and have their values (using \code{value()}) collected.  Because searching for unresolved futures among globals (including their content) can be expensive, the default is not to do it and instead leave it to the run-time checks that assert proper ownership when resolving futures and collecting their values. (Default: \code{ [...]
  \item{\option{future.resolve.recursive}:}{An integer specifying the maximum recursive depth to which futures should be resolved. If negative, nothing is resolved.  If \code{0}, only the future itself is resolved.  If \code{1}, the future and any of its elements that are futures are resolved, and so on. If \code{+Inf}, infinite search depth is used. (Default: \code{0})}
  \item{\option{future.wait.timeout}:}{Maximum waiting time (in seconds) for a free worker before a timeout error is generated. (Default: \code{30 * 24 * 60 * 60} (= 30 days))}
diff --git a/man/plan.Rd b/man/plan.Rd
index c4164e7..8c2adda 100644
--- a/man/plan.Rd
+++ b/man/plan.Rd
@@ -113,8 +113,8 @@ print(y)
 str(list(a = a, b = b, c = c)) ## All NAs
 
 
-# A multicore future
-plan(multicore)
+# A multicore future (specified as a string)
+plan("multicore")
 f <- future({
   a <- 7
   b <- 3
@@ -131,8 +131,9 @@ str(list(a = a, b = b, c = c)) ## All NAs
 ## The same code works in package tests.
 \donttest{
 
-# A multisession future
-plan(multisession)
+# A multisession future (specified via a string variable)
+strategy <- "future::multisession"
+plan(strategy)
 f <- future({
   a <- 7
   b <- 3
diff --git a/tests/backtrace.R b/tests/backtrace.R
index 0446672..8afce6b 100644
--- a/tests/backtrace.R
+++ b/tests/backtrace.R
@@ -22,6 +22,33 @@ print(calls)
 message("*** backtrace( ) - implicit future ... DONE")
 
 
+message("*** backtrace( ) - subsetting ...")
+
+env <- new.env()
+env[["a"]] %<-% { 42L; stop("Woops") }
+env[["b"]] %<-% { 42L; stop("Woops") }
+calls <- backtrace(env[["b"]])
+print(calls)
+stopifnot(is.list(calls))
+
+lenv <- listenv::listenv()
+lenv[[1]] %<-% { 42L; stop("Woops") }
+lenv[[2]] %<-% { 42L; stop("Woops") }
+calls <- backtrace(lenv[[2]])
+print(calls)
+stopifnot(is.list(calls))
+
+ll <- list()
+ll[[1]] <- future({ 42L; stop("Woops") })
+ll[[2]] <- future({ 42L; stop("Woops") })
+vs <- values(ll, signal = FALSE)
+calls <- backtrace(ll[[2]])
+print(calls)
+stopifnot(is.list(calls))
+
+message("*** backtrace( ) - subsetting ... DONE")
+
+
 message("*** backtrace( ) - exceptions ...")
 
 message("- No condition ...")
diff --git a/tests/objectSize.R b/tests/objectSize.R
index 4dd7d86..c88c385 100644
--- a/tests/objectSize.R
+++ b/tests/objectSize.R
@@ -30,7 +30,9 @@ objs <- list(
   env,
   env2,
   env3,
-  fcn
+  fcn,
+  as.FutureGlobals(list(a = 3.14, b = 1:100)),
+  list(x = as.FutureGlobals(list(a = 3.14, b = 1:100)))
 )
 
 for (kk in seq_along(objs)) {
diff --git a/tests/plan.R b/tests/plan.R
index cc5d65d..6e50a80 100644
--- a/tests/plan.R
+++ b/tests/plan.R
@@ -197,6 +197,10 @@ plan(list("sequential", "sequential"))
 a %<-% { b %<-% 42; b }
 stopifnot(a == 42)
 
+plan(list("future::sequential", "sequential"))
+a %<-% { b %<-% 42; b }
+stopifnot(a == 42)
+
 message("*** plan() by functions and character names ... DONE")
 
 
diff --git a/tests/utils.R b/tests/utils.R
index 8b9addb..d5b80e2 100644
--- a/tests/utils.R
+++ b/tests/utils.R
@@ -63,6 +63,39 @@ message("*** asIEC() ... DONE")
 
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# .length()
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+message("*** .length() ...")
+.length <- future:::.length
+
+objs <- list(
+  a = 1:3,
+  b = as.list(1:3),
+  c = structure(as.list(1:3), class = c("foo", "list")),
+  d = data.frame(a = 1:3),
+  e = as.environment(list(a = 1:3))
+)
+truth <- c(a = 3L, b = 3L, c = 3L, d = 1L, e = 1L)
+
+## Special case: length(x) == 5, but .length(x) == 2
+## BUG FIX: https://github.com/HenrikBengtsson/future/issues/164
+if (requireNamespace("tools")) {
+  objs[["f"]] <- structure(list("foo", length = 5L), class = "pdf_doc")
+  truth["f"] <- 2L
+}
+
+for (name in names(objs)) {
+  obj <- objs[[name]]
+  len <- length(obj)
+  .len <- .length(obj)
+  cat(sprintf("%s: length = %d, .length = %d, expected = %d\n",
+              name, len, .len, truth[name]))
+  stopifnot(.len == truth[name])
+}
+
+message("*** .length() ... DONE")
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # debug()
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 message("*** mdebug() ...")
diff --git a/vignettes/future-1-overview.md.rsp b/vignettes/future-1-overview.md.rsp
index 847e8b9..b9d490e 100644
--- a/vignettes/future-1-overview.md.rsp
+++ b/vignettes/future-1-overview.md.rsp
@@ -61,7 +61,7 @@ So why are futures useful?  Because we can choose to evaluate the future express
 [1] 3.14
 ```
 With asynchronous futures, the current/main R process does _not_ block, which means it is available for further processing while the futures are being resolved
-in separates processes running in the background.  In other words, futures provide a simple but yet powerful construct for parallel and / or distributed processing in R.
+in separate processes running in the background.  In other words, futures provide a simple but yet powerful construct for parallel and / or distributed processing in R.
 
 
 Now, if you cannot be bothered to read all the nitty-gritty details about futures, but just want to try them out, then skip to the end to play with the Mandelbrot demo using both parallel and non-parallel evaluation.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-future.git



More information about the debian-med-commit mailing list