]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-145059: Record lazy modules without submodules in `sys.lazy_modules` (#146081)
authorBartosz Sławecki <bartosz@ilikepython.com>
Fri, 27 Mar 2026 21:37:11 +0000 (22:37 +0100)
committerGitHub <noreply@github.com>
Fri, 27 Mar 2026 21:37:11 +0000 (14:37 -0700)
Record simple lazy modules as well

Lib/test/test_lazy_import/__init__.py
Misc/NEWS.d/next/Core_and_Builtins/2026-03-17-14-20-56.gh-issue-145059.aB3xKm.rst [new file with mode: 0644]
Python/import.c

index 6e53e2c042bc16bbfe63ae139af7e1641f8b653e..69cb96cf4a0c1af82b541fd82b952ba06f0ae44d 100644 (file)
@@ -969,6 +969,21 @@ class SysLazyModulesTrackingTests(unittest.TestCase):
         # Basic test that sys.lazy_modules exists and is a dict
         self.assertIsInstance(sys.lazy_modules, dict)
 
+    def test_lazy_module_without_children_is_tracked(self):
+        code = textwrap.dedent("""
+            import sys
+            lazy import json
+            assert "json" in sys.lazy_modules, (
+                f"expected 'json' in sys.lazy_modules, got {set(sys.lazy_modules)}"
+            )
+            assert sys.lazy_modules["json"] == set(), (
+                f"expected empty set for sys.lazy_modules['json'], "
+                f"got {sys.lazy_modules['json']!r}"
+            )
+            print("OK")
+        """)
+        assert_python_ok("-c", code)
+
 
 @support.requires_subprocess()
 class CommandLineAndEnvVarTests(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-17-14-20-56.gh-issue-145059.aB3xKm.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-17-14-20-56.gh-issue-145059.aB3xKm.rst
new file mode 100644 (file)
index 0000000..e2db5a8
--- /dev/null
@@ -0,0 +1 @@
+Fixed ``sys.lazy_modules`` to include lazy modules without submodules. Patch by Bartosz Sławecki.
index f615fe37ba8fbee6d8bb11fb100f4b732c5ff8be..e298fbee536c1ba7053447701d3e8159560c2492 100644 (file)
@@ -4377,6 +4377,12 @@ register_lazy_on_parent(PyThreadState *tstate, PyObject *name,
         Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0,
                                             PyUnicode_GET_LENGTH(name), -1);
         if (dot < 0) {
+            PyObject *lazy_submodules = ensure_lazy_submodules(
+                (PyDictObject *)lazy_modules, name);
+            if (lazy_submodules == NULL) {
+                goto done;
+            }
+            Py_DECREF(lazy_submodules);
             ret = 0;
             goto done;
         }