Skip to content

Commit

Permalink
Implement support for package lazy data
Browse files Browse the repository at this point in the history
Fixes klmr#219.
  • Loading branch information
klmr committed Oct 24, 2021
1 parent f1ca6e6 commit 766e164
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 2 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Suggests:
rlang,
roxygen2 (>= 7.0.2),
shiny,
stringr,
testthat (>= 3.0.3)
Enhances:
rstudioapi
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# box (development version)

* Feature: Support lazy data loading for packages (#219)
* Enhancement: Improve error messages for invalid `use` declarations (#253)
* Feature: Add `purge_cache` function (@kamilzyla, #236)

Expand Down
19 changes: 18 additions & 1 deletion R/env.r
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,28 @@ import_into_env = function (to_env, to_names, from_env, from_names) {
) {
makeActiveBinding(to_names[i], fun, to_env)
} else {
assign(to_names[i], get(from_names[i], from_env), envir = to_env)
assign(to_names[i], env_get(from_env, from_names[i]), envir = to_env)
}
}
}

env_get = function (env, name) {
UseMethod('env_get')
}

# Method for package namespace environments. This distinction is necessary since
# lazydata in packages can’t be loaded via `get`.
env_get.environment = function (env, name) {
getExportedValue(env, name)
}

`env_get.box$mod` =
`env_get.box$ns` = function (env, name) {
# Explicitly allow inherited values, which is used to support re-exporting
# imports in modules.
get(name, envir = env)
}

active_binding_function = if (as.integer(version$major) >= 4L) {
function (sym, env) activeBindingFunction(sym, env)
} else {
Expand Down
2 changes: 1 addition & 1 deletion R/use.r
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ mod_export_names = function (info, mod_ns) {
}

`mod_export_names.box$pkg_info` = function (info, mod_ns) {
getNamespaceExports(mod_ns)
c(getNamespaceExports(mod_ns), ls(getNamespaceInfo(mod_ns, 'lazydata')))
}

#' @rdname importing
Expand Down
17 changes: 17 additions & 0 deletions tests/testthat/test-pkg.r
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,20 @@ test_that('S3 lookup works for partial exports', {
expected = roxygen2::roxy_tag_parse(x)
expect_equal(actual, expected)
})

test_that('packages with lazydata can be loaded', {
# Data inside ‘datasets’ is available via `get`.
expect_error(box::use(datasets), NA)
expect_error(get('mtcars', asNamespace('datasets')), NA)

# ‘stringr’ uses lazydata; `get` doesn’t work.
expect_error(box::use(stringr), NA)
expect_error(get('fruit', asNamespace('stringr')))
expect_in('fruit', ls(stringr))
expect_type(stringr$fruit, 'character')

# Test that attach lists work
expect_error(box::use(stringr[ff = fruit, ...]), NA)
expect_equal(ff, stringr$fruit)
expect_equal(words, stringr$words)
})

0 comments on commit 766e164

Please sign in to comment.