Skip to content

PEP810 lazy from imports ignore module __getattr__ when reifying #144957

@DavidCEllis

Description

@DavidCEllis

Bug report

Bug description:

Without lazy imports:
python -c "from typing import Match; print(Match)"

typing.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

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions