Skip to content

PEP 810 lazy from imports ignore module __getattr__ when reifying #144957

Closed

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

Linked PRs

Activity

  1. added 5 commits that reference this issue on Feb 27, 2026
  2. changed the title [-]PEP810 lazy from imports ignore module `__getattr__` when reifying[/-] [+]PEP 810 lazy from imports ignore module `__getattr__` when reifying[/+] on Mar 13, 2026
  3. DavidCEllis commented on Apr 2, 2026

    @DavidCEllis
    ContributorAuthor

    I'd like to note that despite what that closed, linked, AI generated PR claimed this does not in fact work on Main (as of this morning).

  4. akaIDIOT commented on Apr 8, 2026

    @akaIDIOT

    I can confirm this is still broken on 3.15a8 (running on linuxmint 22.3, python3.15 and python3.15t installed from packages provided by the deadsnakes ppa, both "3.15.0~a8-1+noble1"). The demo module + script posted by OP show the exact same output.

    I'm running into the same erroneous import in local testing with PYTHON_LAZY_IMPORTS=all, where rich references typing.Match from rich.markup, crashing in a similar way:

      File ".../python3.15t/site-packages/rich/markup.py", line 43, in <module>
        _ReStringMatch = Match[str]  # regex match object
                         ^^^^^
    ImportError: cannot import name 'Match' from 'typing' (/usr/lib/python3.15/typing.py)
    

    Without PYTHON_LAZY_IMPORTS set, there is no issue.

  5. DavidCEllis commented on Apr 8, 2026

    @DavidCEllis
    ContributorAuthor

    rich using typing.Match is also how I found this, although via testing on pip list.

  6. JelleZijlstra commented on May 9, 2026

    @JelleZijlstra
    Member

    Added the blocker label as I don't think we should release 3.15 without fixing this.

  7. added a commit that references this issue on May 11, 2026
  8. added a commit that references this issue on May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions