diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 5026c9670d81d2..9b28e32abe3a83 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -894,6 +894,32 @@ def hello(): self.assertEqual(result.returncode, 1) self.assertIn("Error", result.stderr) + def test_raising_spec_initializing(self): + """Test a raising spec._initializing""" + code = textwrap.dedent(""" + import sys + import types + + class Spec: + @property + def _initializing(self): + raise RuntimeError("boom") + + module = types.ModuleType("cached_spec") + module.__spec__ = Spec() + module.attr = 1 + sys.modules["cached_spec"] = module + lazy from cached_spec import attr # this ignores the error + try: + attr # this runs into the error again + except RuntimeError as e: + print('error:', e) + else: + raise AssertionError("exception not raised") + """) + proc = assert_python_ok("-c", code) + self.assertIn(b"error: boom", proc.out) + @support.requires_subprocess() class GlobalsAndDictTests(LazyImportTestCase): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-09-29-14-09-10.gh-issue-158402.wfew_Y.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-29-14-09-10.gh-issue-158402.wfew_Y.rst new file mode 100644 index 00000000000000..1678fabf9ec159 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-29-14-09-10.gh-issue-158402.wfew_Y.rst @@ -0,0 +1,2 @@ +During a lazy import, if getting an existing module fails with an exception, +ignore the exception. (Later reification will likely trigger it again.) diff --git a/Python/ceval.c b/Python/ceval.c index c1fbcb0611384c..784ec9ed24a580 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3358,6 +3358,11 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObje } Py_DECREF(mod); } + else if (PyErr_Occurred()) { + // Getting the module failed. Ignore that for now; future + // reification will likely fail again. + PyErr_Clear(); + } return _PyLazyImport_New(frame, d->lz_builtins, v, name); }