PEP 810: Explicit lazy imports

Hi! Love the PEP. A few questions about the spec that are not clear to me on first read:

  1. The “Syntax restrictions” specify “only allowed at the global (module) level, not inside functions, class bodies, with try/with blocks, or import *". It’s not clear to me if this is a list of examples or a specification list. For example, if a module contains if foo: lazy import mymod, would that import be “at the module level” and thus valid, or not?
  2. The tryrestriction seems to prevent using this feature in the very common pattern where an “optional” module is attempted to be loaded, and a fallback mechanism (either providing an alternative source or dummy replacement) is provided in the except clause. I’m talking about:
try:
    from typing import LiteralString
except ImportError:
    LiteralString = str

I understand why this is hard to do lazily, but are there any suggestions on how to approach this?

  1. When a module has a lazy import foo, and ”foo” is already on sys.modules because some other code already needed it, does the spec say if my current module will get a real module or a proxy in its globals?
  2. The behaviour of argumentless dir()is not clear. If my module contains lazy import foo; dir() , does the call force the import of foo? (The document only clarifies what happens with dir(foo)which, quite reasonably, forces the import.)
  3. Finally, given that there’s likely some existing code that would benefit from using lazy imports, but they may also be using globals() (for example, in an eval()call). The PEP says “if you add lazy imports to your module and call globals(), you’re responsible for handling the lazy objects”. What would be the recommended code changes in that scenario for the owners of the module if they don’t want to have lazy objects (which I imagine is a common scenario)?

Thanks again!

4 Likes