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 @@ -1372,6 +1372,25 @@ def test_initializing_module_is_still_tracked(self):
13721372 """ )
13731373 assert_python_ok ("-c" , code )
13741374
1375+ def test_module_spec_descriptor_is_not_run (self ):
1376+ """Checking whether a module is loaded must not run its descriptors."""
1377+ code = textwrap .dedent ("""
1378+ import sys
1379+ import types
1380+
1381+ class RaisingSpec(types.ModuleType):
1382+ @property
1383+ def __spec__(self):
1384+ raise RuntimeError("__spec__ descriptor was run")
1385+
1386+ sys.modules["raising_spec"] = RaisingSpec("raising_spec")
1387+ lazy import raising_spec
1388+ assert "raising_spec" not in sys.lazy_modules, (
1389+ f"expected 'raising_spec' untracked, got {sys.lazy_modules}"
1390+ )
1391+ """ )
1392+ assert_python_ok ("-c" , code )
1393+
13751394 def test_pending_submodule_is_still_tracked (self ):
13761395 """`lazy from` a submodule that is not loaded must stay tracked."""
13771396 code = textwrap .dedent ("""
Original file line number Diff line number Diff line change @@ -4390,10 +4390,12 @@ lazy_modules_add(PyThreadState *tstate, PyObject *name)
43904390 }
43914391 // A None entry blocks the import rather than satisfying it.
43924392 int loaded = (existing != NULL && existing != Py_None );
4393- if (loaded ) {
4394- // Check if the module is still initializing.
4393+ if (loaded && PyModule_Check (existing )) {
4394+ // Check if the module is still initializing. Read __spec__ from the
4395+ // module dict so that a descriptor on a module subclass is not run.
43954396 PyObject * spec ;
4396- int rc = PyObject_GetOptionalAttr (existing , & _Py_ID (__spec__ ), & spec );
4397+ int rc = PyDict_GetItemRef (_PyModule_GetDict (existing ),
4398+ & _Py_ID (__spec__ ), & spec );
43974399 if (rc > 0 ) {
43984400 rc = _PyModuleSpec_IsInitializing (spec );
43994401 Py_DECREF (spec );
You can’t perform that action at this time.
0 commit comments