diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 271361ae816449..63cbbfd899a961 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1253,6 +1253,21 @@ class Spec2: origin = "a\x00b" _imp.create_dynamic(Spec2()) + def test_create_builtin(self): + class Spec: + name = "sys" + + spec = Spec() + self.assertIs(_imp.create_builtin(spec), sys) + + spec.name = "builtins" + self.assertIs(_imp.create_builtin(spec), builtins) + + # gh-142029 + spec.name = "nonexistent_lib" + with self.assertRaises(ModuleNotFoundError): + _imp.create_builtin(spec) + def test_filter_syntax_warnings_by_module(self): module_re = r'test\.test_import\.data\.syntax_warnings\z' unload('test.test_import.data.syntax_warnings') diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-08-51-56.gh-issue-142029.rUpcmt.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-08-51-56.gh-issue-142029.rUpcmt.rst new file mode 100644 index 00000000000000..017761adb1255e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-08-51-56.gh-issue-142029.rUpcmt.rst @@ -0,0 +1,2 @@ +Raise :exc:`ModuleNotFoundError` instead of crashing when a nonexistent module +is used as a name in ``_imp.create_builtin()``. diff --git a/Python/import.c b/Python/import.c index e91c95b40d94bf..6c9f49842d4e94 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2383,12 +2383,12 @@ is_builtin(PyObject *name) return 0; } -static PyModInitFunction -lookup_inittab_initfunc(const struct _Py_ext_module_loader_info* info) +static struct _inittab* +lookup_inittab_entry(const struct _Py_ext_module_loader_info* info) { for (struct _inittab *p = INITTAB; p->name != NULL; p++) { if (_PyUnicode_EqualToASCIIString(info->name, p->name)) { - return (PyModInitFunction)p->initfunc; + return p; } } // not found @@ -2430,16 +2430,28 @@ create_builtin( _extensions_cache_delete(info.path, info.name); } - PyModInitFunction p0 = initfunc; - if (p0 == NULL) { - p0 = lookup_inittab_initfunc(&info); - if (p0 == NULL) { - /* Cannot re-init internal module ("sys" or "builtins") */ - assert(is_core_module(tstate->interp, info.name, info.path)); - mod = import_add_module(tstate, info.name); + PyModInitFunction p0 = NULL; + if (initfunc == NULL) { + struct _inittab *entry = lookup_inittab_entry(&info); + if (entry == NULL) { + mod = NULL; + _PyErr_SetModuleNotFoundError(name); goto finally; } + + p0 = (PyModInitFunction)entry->initfunc; } + else { + p0 = initfunc; + } + + if (p0 == NULL) { + /* Cannot re-init internal module ("sys" or "builtins") */ + assert(is_core_module(tstate->interp, info.name, info.path)); + mod = import_add_module(tstate, info.name); + goto finally; + } + #ifdef Py_GIL_DISABLED // This call (and the corresponding call to _PyImport_CheckGILForModule())