# PEP 690: Lazy Imports Again

**URL:** <https://discuss.python.org/t/pep-690-lazy-imports-again/19661>\
**Category:** PEPs\
**Created:** [October 3, 2022, 4:09pm UTC](https://discuss.python.org/t/pep-690-lazy-imports-again/19661 "2022-10-03T16:09:53Z")\
**Posts on this page:** 1\
**Showing post:** 18

<div class="post-metadata">

**Author:** ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)\
**Post date:** [November 14, 2022, 4:56pm UTC](https://discuss.python.org/t/pep-690-lazy-imports-again/19661/18 "2022-11-14T16:56:25Z")

</div>

Re-reading the PEP, I see one point without much rationale. Sorry about pointing it so late – it’s a big PEP, and it’s easy to miss the forest for the trees.

> “Transparent” means that besides the delayed import (and necessarily observable effects of that, such as delayed import side effects and changes to `sys.modules`), there is no other observable change in behavior: the imported object is present in the module namespace as normal and is transparently loaded whenever first used: its status as a “lazy imported object” is not directly observable from Python or from C extension code.

Is this a good constraint?  
Lazy imports aren’t _fully_ transparent, as they have “necessarily observable effects”. With that in mind, is preventing any other observable changes worth the implementation complexity?

The complexity worries me. I understand that it can be easily added to current dicts, but it’ll be a burden for any future optimizations and implementations.

To make things clearer, consider semantics like the following. (I don’t see anything similar in Rejected ideas, hopefully it wasn’t floated earlier):

- `import foo` creates a global variable `__lazy:foo` (specially named, but otherwise normal), and sets it to a lazy object. (Another possibility is using a global dict: `__lazy__['foo']`.)
- `LOAD_GLOBAL` for potentially lazy objects (which are known at compile time) becomes `LOAD_LAZY_GLOBAL`, which:
  - tries loading `foo`, and if it doesn’t succeed:
    - loads `__lazy:foo` from globals (not builtins), resolves it and stores the result as `foo`
    - deletes `lazy:foo`

  - replaces itself with `LOAD_GLOBAL`, if the specializing machinery allows that

- module ` __getattr__ ` tries resolving lazy objects the same way
- `is_lazy_import`, `eager_imports`, `set_lazy_imports` would work as in the PEP
- `importlib.resolve_lazy_imports(mod_or_dict)` or a `globals(resolve_lazy_imports=True)`

That would break more modules than transparent way of modifying `dict`, but, how serious would that be? ISTM that it would break modules that inspect module ` __dict__ ` or `globals()` directly.

Would it be better than changing ` __dict__ `? I have no way of knowing. Even if I implement it, I can’t quite test it without access to huge real-world codebases, and mechanisms to patch third-party deps.  
And that’s the main thing that makes me uneasy. Testing an implementation is a _huge_ undertaking, since it involves adapting third-party code. I don’t think it can realistically be done outside Meta. If the proposed semantics are just a local optimum, or a Meta-specific one, we might get stuck in it.

I don’t know what to do about this, though. It dosesn’t sound fair to ask Cinder folks to implement and test half-baked ideas.  
So, my concrete question is: how important is the “transparency”?  
(Apologies it this was discussed before – but if it was, it should be mentioned in the PEP.)

_[edit]: This is a personal view, I don’t represent the SC here._

---

_[View the full topic](https://discuss.python.org/t/pep-690-lazy-imports-again/19661)._
