Skip to content

Commit b9131b5

Browse files
committed
Make sys.lazy_modules reflect the internal structure currently in use
1 parent edf9e75 commit b9131b5

File tree

9 files changed

+171
-175
lines changed

9 files changed

+171
-175
lines changed

Include/internal/pycore_import.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ extern void _PyImport_ClearModules(PyInterpreterState *interp);
8282

8383
extern void _PyImport_ClearModulesByIndex(PyInterpreterState *interp);
8484

85+
extern PyObject * _PyImport_InitLazyModules(PyInterpreterState *interp);
86+
extern void _PyImport_ClearLazyModules(PyInterpreterState *interp);
87+
8588
extern int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp);
8689
extern int _PyImport_IsDefaultImportFunc(
8790
PyInterpreterState *interp,

Include/internal/pycore_interp_structs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ struct _import_state {
327327
PyObject *lazy_imports_filter;
328328
PyObject *lazy_importing_modules;
329329
PyObject *lazy_modules;
330-
PyObject *lazy_modules_set; /* Set of fully-qualified module names lazily imported (PEP 810) */
331330
/* The global import lock. */
332331
_PyRecursiveMutex lock;
333332
/* diagnostic info in PyImport_ImportModuleLevelObject() */

Lib/test/test_import/data/lazy_imports/dunder_lazy_import_builtins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ def myimport(*args):
99
"__import__": myimport,
1010
}
1111
basic2 = 42
12-
basic = __lazy_import__("test.test_import.data.lazy_imports", fromlist="basic2", globals=new_globals)
12+
basic = __lazy_import__("test.test_import.data.lazy_imports.basic2", globals=new_globals)
1313
basic
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
basic = __lazy_import__('test.test_import.data.lazy_imports', fromlist="basic2")
1+
basic = __lazy_import__('test.test_import.data.lazy_imports', fromlist=("basic2", ))
22
basic

Lib/test/test_import/test_lazy_imports.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,26 @@ def tearDown(self):
1919

2020
sys.set_lazy_imports_filter(None)
2121
sys.set_lazy_imports("normal")
22+
sys.lazy_modules.clear()
2223

2324
def test_basic_unused(self):
2425
"""Lazy imported module should not be loaded if never accessed."""
2526
import test.test_import.data.lazy_imports.basic_unused
2627
self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules)
28+
self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules)
29+
self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"})
30+
31+
def test_sys_lazy_modules(self):
32+
try:
33+
import test.test_import.data.lazy_imports.basic_from_unused
34+
except ImportError as e:
35+
self.fail('lazy import failed')
36+
37+
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
38+
self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules)
39+
self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"})
40+
test.test_import.data.lazy_imports.basic_from_unused.basic2
41+
self.assertNotIn("test.test_import.data", sys.lazy_modules)
2742

2843
def test_basic_unused_use_externally(self):
2944
"""Lazy import should load module when accessed from outside."""
@@ -402,7 +417,7 @@ def test_dunder_lazy_import_builtins(self):
402417
from test.test_import.data.lazy_imports import dunder_lazy_import_builtins
403418

404419
self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules)
405-
self.assertEqual(dunder_lazy_import_builtins.basic, 42)
420+
self.assertEqual(dunder_lazy_import_builtins.basic.basic2, 42)
406421

407422

408423
class SysLazyImportsAPITests(unittest.TestCase):
@@ -458,23 +473,18 @@ def my_filter(name):
458473
sys.set_lazy_imports_filter(my_filter)
459474
self.assertIs(sys.get_lazy_imports_filter(), my_filter)
460475

461-
def test_get_lazy_modules_returns_set(self):
462-
"""get_lazy_modules should return a set per PEP 810."""
463-
result = sys.get_lazy_modules()
464-
self.assertIsInstance(result, set)
465-
466476
def test_lazy_modules_attribute_is_set(self):
467477
"""sys.lazy_modules should be a set per PEP 810."""
468-
self.assertIsInstance(sys.lazy_modules, set)
469-
self.assertIs(sys.lazy_modules, sys.get_lazy_modules())
478+
self.assertIsInstance(sys.lazy_modules, dict)
470479

471480
def test_lazy_modules_tracks_lazy_imports(self):
472481
"""sys.lazy_modules should track lazily imported module names."""
473482
code = textwrap.dedent("""
474483
import sys
475484
initial_count = len(sys.lazy_modules)
476485
import test.test_import.data.lazy_imports.basic_unused
477-
assert "test.test_import.data.lazy_imports.basic2" in sys.lazy_modules
486+
assert "test.test_import.data.lazy_imports" in sys.lazy_modules
487+
assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"}
478488
assert len(sys.lazy_modules) > initial_count
479489
print("OK")
480490
""")
@@ -854,14 +864,15 @@ def test_module_added_to_lazy_modules_on_lazy_import(self):
854864
lazy import test.test_import.data.lazy_imports.basic2
855865
856866
# Should be in lazy_modules after lazy import
857-
assert "test.test_import.data.lazy_imports.basic2" in sys.lazy_modules
867+
assert "test.test_import.data.lazy_imports" in sys.lazy_modules
868+
assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"}
858869
assert len(sys.lazy_modules) > initial_count
859870
860871
# Trigger reification
861872
_ = test.test_import.data.lazy_imports.basic2.x
862873
863874
# Module should still be tracked (for diagnostics per PEP 810)
864-
assert "test.test_import.data.lazy_imports.basic2" in sys.lazy_modules
875+
assert "test.test_import.data.lazy_imports" not in sys.lazy_modules
865876
print("OK")
866877
""")
867878
result = subprocess.run(
@@ -875,8 +886,7 @@ def test_module_added_to_lazy_modules_on_lazy_import(self):
875886
def test_lazy_modules_is_per_interpreter(self):
876887
"""Each interpreter should have independent sys.lazy_modules."""
877888
# Basic test that sys.lazy_modules exists and is a set
878-
self.assertIsInstance(sys.lazy_modules, set)
879-
self.assertIs(sys.lazy_modules, sys.get_lazy_modules())
889+
self.assertIsInstance(sys.lazy_modules, dict)
880890

881891

882892
class CommandLineAndEnvVarTests(unittest.TestCase):
@@ -1467,7 +1477,7 @@ def create_lazy_imports(idx):
14671477
t.join()
14681478
14691479
assert not errors, f"Errors: {errors}"
1470-
assert isinstance(sys.lazy_modules, set), "sys.lazy_modules is not a set"
1480+
assert isinstance(sys.lazy_modules, dict), "sys.lazy_modules is not a dict"
14711481
print("OK")
14721482
""")
14731483

Python/clinic/sysmodule.c.h

Lines changed: 1 addition & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)