import icon indicating copy to clipboard operation
import copied to clipboard

Feature request: recursive `import::into/from` when `.into` is an environment (but not `environment()`)

Open mmuurr opened this issue 3 months ago • 1 comments

I'm aware of #34, but I'm curious if there's any appetite for allowing import::into() and import::from() to work recursively when .into is supplied and (i) is an environment and (ii) not environment(). The use case I have in mind is when we capture the imports into a 'module-like' object, rather than attaching individual module contents into the current frame. So, e.g.,:

utils.R:

log <- function(...) cat(sprintf(...), sep = "\n")

na2 <- function(x, replacement = NA) {
  x[is.na(x)] <- replacement
  x
}

maths.R:

utils <- import::from("utils.R", .all = TRUE, .into = new.env())

square <- function(x, .na = NA) {
  utils$na2(x, .na)^2
}

Now at the console:

maths <- import::from("maths.R", .all = TRUE, .into = new.env())
ls(maths)
# [1] "log"        "na2"        "square"     "triangular" "utils"

... utils, log, and na2 are all in the environment, but the intent was to keep the contents of utils.R in the local utils environment.

It's definitely true that if utils.R happened to also include a call to import::from() and not specify a capturing environment this could cause great confusion, but I think the 'strict' case shown above mimics the patterns used by Python, JS, etc.

Perhaps extending the set of commands (here, from, into) with something like import::env(...) that only ever imports into a new.env() (that typically would then be captured as a variable for downstream usage).

mmuurr avatar Sep 21 '25 15:09 mmuurr

So, the question is: "Is there any appetite for allowing import::into() and import::from() to work recursively when .into is supplied and (i) is an environment and (ii) not environment()"

The answer is: "Probably not" – but a quick elaboration ...

import is currently in "low-maintenance mode". I took over maintenance a few years ago and I will work to get bugs fixed assuming they are fixable. But:

  • New solutions now exist, such as additional parameters for library() and new packages such as conflicted and box that address clear subsets of the original needs that prompted this package, and
  • The package is pretty low-level and hence fragile (recursive imports, in particular, are a hornet's nest, which is why import::here() is the only recommended way for inner imports in a recursive structure)

Because of this, new features such as this one would require commitment from an implementer and preferably a statement of need from someone else apart from that. Detailed tests would also need to be written, and it would be needed to demonstrate that no existing tests would fail.

torfason avatar Oct 03 '25 09:10 torfason