Skip to content

Commit 17de69e

Browse files
committed
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
1 parent 2c0e3f2 commit 17de69e

3 files changed

Lines changed: 27 additions & 1 deletion

File tree

Doc/library/sys.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,27 @@ always available. Unless explicitly noted otherwise, all variables are read-only
14831483
They hold the legacy representation of ``sys.last_exc``, as returned
14841484
from :func:`exc_info` above.
14851485

1486+
1487+
.. data:: lazy_modules
1488+
1489+
A read-only :class:`frozendict` snapshot of the lazy import registry for the
1490+
current interpreter. Each key is a module name string; the corresponding
1491+
value is a :class:`frozenset` of the child attribute names that were
1492+
registered as lazy imports from that module. A top-level lazy import (e.g.
1493+
``lazy import json``) is represented by an empty :class:`frozenset`.
1494+
1495+
A fresh snapshot is constructed on every attribute access, so the mapping
1496+
reflects the state of lazy imports at the time of access. The snapshot is
1497+
immutable; modifications must go through :func:`set_lazy_imports`.
1498+
1499+
The live, mutable registry is available as the private :data:`sys._lazy_modules`
1500+
for internal use.
1501+
1502+
See also :func:`set_lazy_imports`, :func:`get_lazy_imports`, and :pep:`810`.
1503+
1504+
.. versionadded:: 3.15
1505+
1506+
14861507
.. data:: maxsize
14871508

14881509
An integer giving the maximum value a variable of type :c:type:`Py_ssize_t` can

Lib/test/test_builtin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,9 @@ def getDict(self):
21322132

21332133
def test_vars(self):
21342134
self.assertEqual(set(vars()), set(dir()))
2135-
self.assertEqual(set(vars(sys)), set(dir(sys)))
2135+
# sys.lazy_modules is a virtual attribute served by sys.__getattr__,
2136+
# so it appears in dir() but not in vars().
2137+
self.assertEqual(set(vars(sys)) | {'lazy_modules'}, set(dir(sys)))
21362138
self.assertEqual(self.get_vars_f0(), {})
21372139
self.assertEqual(self.get_vars_f2(), {'a': 1, 'b': 2})
21382140
self.assertRaises(TypeError, vars, 42, 42)

Lib/test/test_inspect/test_inspect.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6179,6 +6179,9 @@ def test_sys_module_has_signatures(self):
61796179
no_signature = {'getsizeof', 'set_asyncgen_hooks'}
61806180
no_signature |= {name for name in ['getobjects']
61816181
if hasattr(sys, name)}
6182+
# sys.__dir__ and sys.__getattr__ are plain METH_NOARGS/METH_VARARGS
6183+
# builtins without Argument Clinic text signatures.
6184+
no_signature |= {'__dir__', '__getattr__'}
61826185
self._test_module_has_signatures(sys, no_signature)
61836186

61846187
def test_abc_module_has_signatures(self):

0 commit comments

Comments
 (0)