https://github.com/python/cpython/commit/cd2ca74c53d3cb502db40e3f52911d4429797daf commit: cd2ca74c53d3cb502db40e3f52911d4429797daf branch: main author: dr-carlos <[email protected]> committer: vstinner <[email protected]> date: 2025-12-15T13:20:19+01:00 summary:
gh-142029: Raise `ModuleNotFoundError` instead of crashing on nonexsistent module name given to `create_builtin()` (#142054) Co-authored-by: Brett Cannon <[email protected]> Co-authored-by: Victor Stinner <[email protected]> files: A Misc/NEWS.d/next/Core_and_Builtins/2025-11-29-08-51-56.gh-issue-142029.rUpcmt.rst M Lib/test/test_import/__init__.py M Python/import.c diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index c5cabc6477c8e6..59c6dc4587c93d 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1255,15 +1255,23 @@ class Spec2: 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 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 f4decf6e5cd247..db433dbc971d76 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()) _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
