File tree Expand file tree Collapse file tree
Lib/test/test_lazy_import Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1349,6 +1349,25 @@ def test_initializing_module_is_still_tracked(self):
13491349 """ )
13501350 assert_python_ok ("-c" , code )
13511351
1352+ def test_module_spec_descriptor_is_not_run (self ):
1353+ """Checking whether a module is loaded must not run its descriptors."""
1354+ code = textwrap .dedent ("""
1355+ import sys
1356+ import types
1357+
1358+ class RaisingSpec(types.ModuleType):
1359+ @property
1360+ def __spec__(self):
1361+ raise RuntimeError("__spec__ descriptor was run")
1362+
1363+ sys.modules["raising_spec"] = RaisingSpec("raising_spec")
1364+ lazy import raising_spec
1365+ assert "raising_spec" not in sys.lazy_modules, (
1366+ f"expected 'raising_spec' untracked, got {sys.lazy_modules}"
1367+ )
1368+ """ )
1369+ assert_python_ok ("-c" , code )
1370+
13521371 def test_pending_submodule_is_still_tracked (self ):
13531372 """`lazy from` a submodule that is not loaded must stay tracked."""
13541373 code = textwrap .dedent ("""
Original file line number Diff line number Diff line change @@ -4370,10 +4370,12 @@ lazy_modules_add(PyThreadState *tstate, PyObject *name)
43704370 }
43714371 // A None entry blocks the import rather than satisfying it.
43724372 int loaded = (existing != NULL && existing != Py_None );
4373- if (loaded ) {
4374- // Check if the module is still initializing.
4373+ if (loaded && PyModule_Check (existing )) {
4374+ // Check if the module is still initializing. Read __spec__ from the
4375+ // module dict so that a descriptor on a module subclass is not run.
43754376 PyObject * spec ;
4376- int rc = PyObject_GetOptionalAttr (existing , & _Py_ID (__spec__ ), & spec );
4377+ int rc = PyDict_GetItemRef (_PyModule_GetDict (existing ),
4378+ & _Py_ID (__spec__ ), & spec );
43774379 if (rc > 0 ) {
43784380 rc = _PyModuleSpec_IsInitializing (spec );
43794381 Py_DECREF (spec );
You can’t perform that action at this time.
0 commit comments