PEP 810 lazy from imports ignore module `__getattr__` when reifying
Bug report
Bug description:
Without lazy imports:
python -c "from typing import Match; print(Match)"
With lazy imports:
python -c "lazy from typing import Match; print(Match)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
lazy from typing import Match; print(Match)
ImportError: deferred import of 'typing.Match' raised an exception during resolution
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<string>", line 1, in <module>
lazy from typing import Match; print(Match)
^^^^^
ImportError: cannot import name 'Match' from 'typing' (.../src/cpython/Lib/typing.py)
I believe the underlying issue is that the lazy import statement creates a lazy_import object in the module __dict__ which then prevents the module __getattr__ from being called. This occurs even if the module has already been imported.
demo_module.py
def __getattr__(name): return name
demo_script.py
import demo_module lazy from demo_module import ohno try: print(ohno) except ImportError: print("Import failed") # The lazy from import has placed the ohno object in demo_module's globals try: print(demo_module.ohno) except ImportError: print("Failed again") print({k: v for k, v in demo_module.__dict__.items() if not k.startswith("_")}) demo_module.__dict__.pop("ohno", None) print(demo_module.ohno)
python demo_script.py
Import failed
Failed again
{'ohno': <lazy_import 'demo_module.ohno'>}
ohno
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response