Skip to content

Commit afb7f9e

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

File tree

9 files changed

+172
-175
lines changed

9 files changed

+172
-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: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,27 @@ 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+
print(sys.lazy_modules)
29+
self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules)
30+
self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"})
31+
32+
def test_sys_lazy_modules(self):
33+
try:
34+
import test.test_import.data.lazy_imports.basic_from_unused
35+
except ImportError as e:
36+
self.fail('lazy import failed')
37+
38+
self.assertFalse("test.test_import.data.lazy_imports.basic2" in sys.modules)
39+
self.assertIn("test.test_import.data.lazy_imports", sys.lazy_modules)
40+
self.assertEqual(sys.lazy_modules["test.test_import.data.lazy_imports"], {"basic2"})
41+
test.test_import.data.lazy_imports.basic_from_unused.basic2
42+
self.assertNotIn("test.test_import.data", sys.lazy_modules)
2743

2844
def test_basic_unused_use_externally(self):
2945
"""Lazy import should load module when accessed from outside."""
@@ -402,7 +418,7 @@ def test_dunder_lazy_import_builtins(self):
402418
from test.test_import.data.lazy_imports import dunder_lazy_import_builtins
403419

404420
self.assertNotIn("test.test_import.data.lazy_imports.basic2", sys.modules)
405-
self.assertEqual(dunder_lazy_import_builtins.basic, 42)
421+
self.assertEqual(dunder_lazy_import_builtins.basic.basic2, 42)
406422

407423

408424
class SysLazyImportsAPITests(unittest.TestCase):
@@ -458,23 +474,18 @@ def my_filter(name):
458474
sys.set_lazy_imports_filter(my_filter)
459475
self.assertIs(sys.get_lazy_imports_filter(), my_filter)
460476

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-
466477
def test_lazy_modules_attribute_is_set(self):
467478
"""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())
479+
self.assertIsInstance(sys.lazy_modules, dict)
470480

471481
def test_lazy_modules_tracks_lazy_imports(self):
472482
"""sys.lazy_modules should track lazily imported module names."""
473483
code = textwrap.dedent("""
474484
import sys
475485
initial_count = len(sys.lazy_modules)
476486
import test.test_import.data.lazy_imports.basic_unused
477-
assert "test.test_import.data.lazy_imports.basic2" in sys.lazy_modules
487+
assert "test.test_import.data.lazy_imports" in sys.lazy_modules
488+
assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"}
478489
assert len(sys.lazy_modules) > initial_count
479490
print("OK")
480491
""")
@@ -854,14 +865,15 @@ def test_module_added_to_lazy_modules_on_lazy_import(self):
854865
lazy import test.test_import.data.lazy_imports.basic2
855866
856867
# Should be in lazy_modules after lazy import
857-
assert "test.test_import.data.lazy_imports.basic2" in sys.lazy_modules
868+
assert "test.test_import.data.lazy_imports" in sys.lazy_modules
869+
assert sys.lazy_modules["test.test_import.data.lazy_imports"] == {"basic2"}
858870
assert len(sys.lazy_modules) > initial_count
859871
860872
# Trigger reification
861873
_ = test.test_import.data.lazy_imports.basic2.x
862874
863875
# Module should still be tracked (for diagnostics per PEP 810)
864-
assert "test.test_import.data.lazy_imports.basic2" in sys.lazy_modules
876+
assert "test.test_import.data.lazy_imports" not in sys.lazy_modules
865877
print("OK")
866878
""")
867879
result = subprocess.run(
@@ -875,8 +887,7 @@ def test_module_added_to_lazy_modules_on_lazy_import(self):
875887
def test_lazy_modules_is_per_interpreter(self):
876888
"""Each interpreter should have independent sys.lazy_modules."""
877889
# 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())
890+
self.assertIsInstance(sys.lazy_modules, dict)
880891

881892

882893
class CommandLineAndEnvVarTests(unittest.TestCase):
@@ -1467,7 +1478,7 @@ def create_lazy_imports(idx):
14671478
t.join()
14681479
14691480
assert not errors, f"Errors: {errors}"
1470-
assert isinstance(sys.lazy_modules, set), "sys.lazy_modules is not a set"
1481+
assert isinstance(sys.lazy_modules, dict), "sys.lazy_modules is not a dict"
14711482
print("OK")
14721483
""")
14731484

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)