PEP 810: Explicit lazy imports

Notice the hypothetical __raw_dict__ only makes sense across module boundaries when inspecting module objects:

# x.py

lazy import a
lazy import b

def foo(): ...

# y.py

import x

# If we do here x.__dict__ then both x.a and x.b will be reified so we
# need some way to know that they are there but without triggering the
# reification

print(f"names in x are: {x.__raw_dict__.keys()}")

We are not closed to this if people agree that this is the best option. It means we are technically exposing lazy objects a bit more, also outside the module. Apart from the options highlighted in the PEP we didn’t went with this option initially so is also a bit easier to activate global mode, but I am happy to reevaluate it as its another option to the __raw_dict__ conundrum. I think @brittanyrey may have more info on how much this matters in practice in the wild.

Notice the get() method only happens if you somehow stumped into a proxy object via globals() the new hypothetical __raw_dict__ or __dict__ if we use your proposal.

>>> lazy import exampl
>>> print(globals()['example'])
<lazy_import 'example'>
>>> print(globals()['example'].get())
<module 'example' from '/Users/pgalindo3/github/python/main/example.py'>

Also note that any attempt to use will cause it to reify so its really hard to ever see a lazy object:

# lel.py
print("FORTRAN 77 ROCKS")

def foo(): ...

then:

>>> lazy import lel
>>> x = globals()['lel']
>>> print(x)
FORTRAN 77 ROCKS
<module 'lel' from '/Users/pgalindo3/github/python/main/lel.py'>

or

>>> lazy from lel import foo
>>>
>>> x = globals()['foo']
>>> def print_type(x):
...     print(type(x))
...
>>> print_type(x)
FORTRAN 77 ROCKS
<class 'function'>

Perhaps this can motivate why trying to reify on module.__dict__ is worth doing and exposing __raw_dict__ or some free function that does that: it “hides” the lazy objects more. Not that they are a problem if they appear (that’s fine!) but is nice that is rare for them to show up.

2 Likes