gh-142029: Raise ModuleNotFoundError instead of crashing on nonexsistent module name given to create_builtin() (#142054)

Co-authored-by: Brett Cannon <brett@python.org>
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
dr-carlos 2025-12-15 22:50:19 +10:30 committed by GitHub
parent 6658e2cb07
commit cd2ca74c53
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 12 deletions

View file

@ -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)

View file

@ -0,0 +1,2 @@
Raise :exc:`ModuleNotFoundError` instead of crashing when a nonexistent module
is used as a name in ``_imp.create_builtin()``.

View file

@ -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())