Skip to content

Implement PEP 810 – Explicit lazy imports #142349

Closed
8 of 8 issues completed
Closed

Description

@pablogsal

Activity

  1. added a commit that references this issue on Feb 12, 2026
  2. added a commit that references this issue on Feb 12, 2026
  3. added 3 commits that reference this issue on Feb 15, 2026
  4. added 5 commits that reference this issue on Feb 15, 2026
  5. DavidCEllis commented on Feb 17, 2026

    @DavidCEllis
    Contributor

    Should __lazy_import__ ignore sys.set_lazy_imports("none")?

    Currently it does:

    import sys
    sys.set_lazy_imports("none")
    
    lazy import annotationlib
    typing = __lazy_import__("typing")
    
    print(globals()["annotationlib"])  # <module 'annotationlib' from ...>
    print(globals()["typing"])  # <lazy_import 'typing'>

    A way to ignore this setting may actually be useful to handle circular imports, but I'm not sure if __lazy_import__ doing so is intentional.

    Setting the filter currently crashes with __lazy_import__ so I couldn't check that interaction - #144851.

  6. changed the title [-]Implement PEP 810[/-] [+]Implement PEP 810 – Explicit lazy imports[/+] on Feb 20, 2026
  7. added 5 commits that reference this issue on Feb 28, 2026
  8. hugovk commented on Mar 10, 2026

    @hugovk
    Member

    This is merged and in alpha 7.

    Anything more to do here, or shall we close this issue and mark the PEP as Final?

    Oh, one thing: __lazy_modules__ isn't documented yet. @johnslavik I think you might have had a PR for this to the lazycabal fork?

  9. johnslavik commented on Mar 10, 2026

    @johnslavik
    Member

    Oh, one thing: __lazy_modules__ isn't documented yet.

    I'd add that sys.lazy_modules is also undocumented and needs general polishing (ref GH-145057 and GH-145059), and from some discussions I've had it is not clear if we'd like to keep it public or make it private.

    @johnslavik I think you might have had a PR for this to the lazycabal fork?

    I can't find it, but I'm happy to contribute more documentation as part of my interest in touching up lazy imports.

  10. hugovk commented on Mar 10, 2026

    @hugovk
    Member

    I was thinking of LazyImportsCabal#42.

  11. added 2 commits that reference this issue on Mar 15, 2026
  12. added 6 commits that reference this issue on Apr 25, 2026
  13. added 3 commits that reference this issue on May 15, 2026
  14. encukou commented on Jun 29, 2026

    @encukou
    Member

    sys.lazy_modules doesn't necessarily contain fully-qualified module names:

    >>> lazy from math import floor
    >>> import sys
    >>> sys.lazy_modules
    {..., 'math.floor'}

    This doesn't match the docs or PEP. Is this intended?

    Also, unlike regular import, lazy imports for non-modules work without from. This isn't clear from the PEP; is it intentional?

    >>> lazy import math.floor
    >>> math.floor
    <built-in function floor>
    
    >>> import math.floor
    Traceback (most recent call last):
      File "<python-input-5>", line 1, in <module>
        import math.floor
    ModuleNotFoundError: No module named 'math.floor'; 'math' is not a package
  15. gpshead commented on Jun 29, 2026

    @gpshead
    Member

    sys.lazy_modules doesn't necessarily contain fully-qualified module names:

    lazy from math import floor
    import sys
    sys.lazy_modules
    {..., 'math.floor'}
    This doesn't match the docs or PEP. Is this intended?

    Also, unlike regular import, lazy imports for non-modules work without from. This isn't clear from the PEP; is it intentional?

    lazy import math.floor
    math.floor

    import math.floor
    Traceback (most recent call last):
    File "", line 1, in
    import math.floor
    ModuleNotFoundError: No module named 'math.floor'; 'math' is not a package

    Being lazy there's no way to know what the names and their types are until the actual import happens so i feel like this is expected. The error appears on first use.

    I expect most codebases adopting lazy have also adopted static analysis to catch this at build/push/CI time.

  16. encukou commented on Jun 29, 2026

    @encukou
    Member

    i feel like this is expected.

    OK, so (for the first point) we should update the lazy_modules docs (and PEP, to match the implementation).

    The error appears on first use.

    The (second) point is that it does not appear at all.

  17. johnslavik commented on Jun 29, 2026

    @johnslavik
    Member

    update the lazy_modules docs (and PEP, to match the implementation).

    I made these docs, how would you rephrase it?

    I'm also unhappy with the current wording. Maybe "A set of strings capturing lazily imported modules or module members in the current interpreter. When a lazily imported module or module member is accessed for the first time and successfully resolved [reified?], its name is removed from this set.". WDYT?

  18. johnslavik commented on Jun 29, 2026

    @johnslavik
    Member

    I made GH-152622, let's iterate there.

  19. encukou commented on Jun 30, 2026

    @encukou
    Member

    I made these docs, how would you rephrase it?

    The docs currently match the PEP, which should be changed to “accurately describes the implementation at the point where it is marked Final”. It's not about the docs.
    Do you know why this wasn't implemented as specified?

    Fully qualified module names would be useful as they could be passed to importlib.import_module to load eagerly. The current implementation looks like it's the legacy form for pkgutil.resolve_name -- is that right?

    When a lazily imported module or module member is accessed for the first time and successfully resolved [reified?], its name is removed from this set.

    That doesn't look right:

    >>> lazy import typing
    >>> globals()['typing']
    <lazy_import 'typing'>
    >>> import sys
    >>> 'typing' in sys.lazy_modules
    True
    >>> globals()['typing'].resolve()
    <module 'typing' from '/home/encukou/dev/cpython/Lib/typing.py'>
    >>> 'typing' in sys.lazy_modules
    True
    >>> typing
    <module 'typing' from '/home/encukou/dev/cpython/Lib/typing.py'>
    >>> 'typing' in sys.lazy_modules
    True
  20. DavidCEllis commented on Jun 30, 2026

    @DavidCEllis
    Contributor

    I think this is different depending on if the module has actually already been imported. If you're using the REPL then typing is already in sys.modules. If the module has already been imported then it still gets added but doesn't get removed.

    Using threading instead, which isn't imported by the REPL.

    >>> lazy import threading
    >>> globals()['threading']
    <lazy_import 'threading'>
    >>> import sys
    >>> 'threading' in sys.lazy_modules
    True
    >>> globals()['threading'].resolve()
    <module 'threading' from '/home/david/.local/share/uv/python/cpython-3.15.0b3-linux-x86_64-gnu/lib/python3.15/threading.py'>
    >>> 'threading' in sys.lazy_modules
    False
    >>> threading
    <module 'threading' from '/home/david/.local/share/uv/python/cpython-3.15.0b3-linux-x86_64-gnu/lib/python3.15/threading.py'>
    >>> threading in sys.lazy_modules
    False
  21. added 2 commits that reference this issue on Jul 28, 2026
  22. encukou commented on Jul 29, 2026

    @encukou
    Member

    So, what is sys.lazy_modules meant to contain?

  23. brittanyrey commented on Aug 3, 2026

    @brittanyrey
    Contributor

    So, what is sys.lazy_modules meant to contain?

    Thread continued on discuss.py

  24. added a commit that references this issue on Aug 14, 2026
  25. added a commit that references this issue on Sep 4, 2026
  26. added a commit that references this issue on Sep 4, 2026
  27. added a commit that references this issue on Sep 10, 2026
  28. added a commit that references this issue on Sep 11, 2026
  29. added 2 commits that reference this issue on Sep 12, 2026
  30. added a commit that references this issue on Sep 14, 2026
  31. added a commit that references this issue on Oct 1, 2026
  32. added a commit that references this issue on Oct 1, 2026
  33. added a commit that references this issue on Oct 3, 2026
  34. added a commit that references this issue on Oct 3, 2026
  35. added 3 commits that reference this issue on Oct 5, 2026
  36. added a commit that references this issue on Oct 21, 2026
  37. added a commit that references this issue on Oct 25, 2026
  38. hugovk commented on Oct 25, 2026

    @hugovk
    Member

    Python 3.15 has been released with lazy imports! Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions