diff --git a/NEWS.md b/NEWS.md index 6a5ba22..a0c9fb3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # pkgload (development version) +* Fix handling of active bindings inside a package during unloading (#255, @klmr). + + # pkgload 1.3.3 * pkgload now depends unconditionally on pkgbuild (#249). diff --git a/R/namespace-env.R b/R/namespace-env.R index 0cec5da..1636a5b 100644 --- a/R/namespace-env.R +++ b/R/namespace-env.R @@ -234,7 +234,12 @@ unregister_namespace <- function(name = NULL) { # unloaded, it might lead to decompress errors if unloaded or to # inconsistencies if reloaded (the bindings are resolved in the new # namespace). - eapply(ns_env(name), force, all.names = TRUE) + # + # We take precautions not to trigger active bindings in case these + # have side effects such as throwing an error. + ns <- ns_env(name) + active_bindings <- env_binding_are_active(ns) + env_get_list(ns, names(active_bindings)[!active_bindings]) # Remove the item from the registry env_unbind(ns_registry_env(), name) diff --git a/tests/testthat/test-load.R b/tests/testthat/test-load.R index b0e657d..eecbc84 100644 --- a/tests/testthat/test-load.R +++ b/tests/testthat/test-load.R @@ -76,6 +76,12 @@ test_that("unloading or reloading forces bindings", { ) }) +test_that("unloading or reloading does not call active bindings", { + on.exit(unload("testActiveBindings")) + + expect_no_error(load_all(test_path("testActiveBindings"))) +}) + test_that("reloading a package unloads deleted S3 methods", { x <- structure(list(), class = "pkgload_foobar") diff --git a/tests/testthat/testActiveBindings/DESCRIPTION b/tests/testthat/testActiveBindings/DESCRIPTION new file mode 100644 index 0000000..4e064a9 --- /dev/null +++ b/tests/testthat/testActiveBindings/DESCRIPTION @@ -0,0 +1,6 @@ +Package: testActiveBindings +Title: Test package with active bindings +License: MIT +Author: Konrad Rudolph +Maintainer: Konrad Rudolph +Version: 1.0 diff --git a/tests/testthat/testActiveBindings/NAMESPACE b/tests/testthat/testActiveBindings/NAMESPACE new file mode 100644 index 0000000..449a7e5 --- /dev/null +++ b/tests/testthat/testActiveBindings/NAMESPACE @@ -0,0 +1,3 @@ +# Generated by roxygen2: do not edit by hand + +export(bar) diff --git a/tests/testthat/testActiveBindings/R/bindings.r b/tests/testthat/testActiveBindings/R/bindings.r new file mode 100644 index 0000000..d9eedea --- /dev/null +++ b/tests/testthat/testActiveBindings/R/bindings.r @@ -0,0 +1,5 @@ + +makeActiveBinding("foo", function() rlang::abort("foo"), environment()) + +#' @export +makeActiveBinding("bar", function() rlang::abort("bar"), environment())