From: dr-carlos <77367421+dr-carlos@users.noreply.github.com> Date: Mon, 15 Dec 2025 12:20:19 +0000 (+1030) Subject: gh-142029: Raise `ModuleNotFoundError` instead of crashing on nonexsistent module... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=HEAD;p=thirdparty%2FPython%2Fcpython.git gh-142029: Raise `ModuleNotFoundError` instead of crashing on nonexsistent module name given to `create_builtin()` (#142054) Co-authored-by: Brett Cannon Co-authored-by: Victor Stinner --- diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index c5cabc6477c8..59c6dc4587c9 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1255,15 +1255,23 @@ os.does_not_exist def test_create_builtin(self): class Spec: - name = None + pass spec = Spec() + spec.name = "sys" + self.assertIs(_imp.create_builtin(spec), sys) + + spec.name = None with self.assertRaisesRegex(TypeError, 'name must be string, not NoneType'): _imp.create_builtin(spec) - spec.name = "" + # gh-142029 + spec.name = "nonexistent_lib" + with self.assertRaises(ModuleNotFoundError): + _imp.create_builtin(spec) # gh-142029 + spec.name = "" with self.assertRaisesRegex(ValueError, 'name must not be empty'): _imp.create_builtin(spec) 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 000000000000..017761adb125 --- /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 f4decf6e5cd2..db433dbc971d 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())