Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add sys.lazy_modules docs and fix CI test failures
- Add ``sys.lazy_modules`` entry to Doc/library/sys.rst (frozendict
  snapshot, fresh per access, versionadded 3.15)
- Fix test_builtin.test_vars: sys.lazy_modules is served by
  sys.__getattr__ so it appears in dir() but not vars()
- Fix test_inspect.test_sys_module_has_signatures: sys.__dir__ and
  sys.__getattr__ are METH_NOARGS/METH_VARARGS builtins without
  Argument Clinic text signatures; add them to no_signature
  • Loading branch information
johnslavik committed May 5, 2026
commit 17de69ef42653eb42c32f82f818affa1f6bda1cd
21 changes: 21 additions & 0 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,27 @@
They hold the legacy representation of ``sys.last_exc``, as returned
from :func:`exc_info` above.


.. data:: lazy_modules

A read-only :class:`frozendict` snapshot of the lazy import registry for the
current interpreter. Each key is a module name string; the corresponding
value is a :class:`frozenset` of the child attribute names that were
registered as lazy imports from that module. A top-level lazy import (e.g.
``lazy import json``) is represented by an empty :class:`frozenset`.

A fresh snapshot is constructed on every attribute access, so the mapping
reflects the state of lazy imports at the time of access. The snapshot is
immutable; modifications must go through :func:`set_lazy_imports`.

The live, mutable registry is available as the private :data:`sys._lazy_modules`

Check warning on line 1499 in Doc/library/sys.rst

View workflow job for this annotation

GitHub Actions / Docs / Docs

py:data reference target not found: sys._lazy_modules [ref.data]
for internal use.

See also :func:`set_lazy_imports`, :func:`get_lazy_imports`, and :pep:`810`.

.. versionadded:: 3.15


.. data:: maxsize

An integer giving the maximum value a variable of type :c:type:`Py_ssize_t` can
Expand Down
4 changes: 3 additions & 1 deletion Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2132,7 +2132,9 @@ def getDict(self):

def test_vars(self):
self.assertEqual(set(vars()), set(dir()))
self.assertEqual(set(vars(sys)), set(dir(sys)))
# sys.lazy_modules is a virtual attribute served by sys.__getattr__,
# so it appears in dir() but not in vars().
self.assertEqual(set(vars(sys)) | {'lazy_modules'}, set(dir(sys)))
self.assertEqual(self.get_vars_f0(), {})
self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2})
self.assertRaises(TypeError, vars, 42, 42)
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -6179,6 +6179,9 @@ def test_sys_module_has_signatures(self):
no_signature = {'getsizeof', 'set_asyncgen_hooks'}
no_signature |= {name for name in ['getobjects']
if hasattr(sys, name)}
# sys.__dir__ and sys.__getattr__ are plain METH_NOARGS/METH_VARARGS
# builtins without Argument Clinic text signatures.
no_signature |= {'__dir__', '__getattr__'}
self._test_module_has_signatures(sys, no_signature)

def test_abc_module_has_signatures(self):
Expand Down
Loading