Skip to content

Commit cd2ca74

Browse files
dr-carlosbrettcannonvstinner
authored
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]>
1 parent 6658e2c commit cd2ca74

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

Lib/test/test_import/__init__.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,15 +1255,23 @@ class Spec2:
12551255

12561256
def test_create_builtin(self):
12571257
class Spec:
1258-
name = None
1258+
pass
12591259
spec = Spec()
12601260

1261+
spec.name = "sys"
1262+
self.assertIs(_imp.create_builtin(spec), sys)
1263+
1264+
spec.name = None
12611265
with self.assertRaisesRegex(TypeError, 'name must be string, not NoneType'):
12621266
_imp.create_builtin(spec)
12631267

1264-
spec.name = ""
1268+
# gh-142029
1269+
spec.name = "nonexistent_lib"
1270+
with self.assertRaises(ModuleNotFoundError):
1271+
_imp.create_builtin(spec)
12651272

12661273
# gh-142029
1274+
spec.name = ""
12671275
with self.assertRaisesRegex(ValueError, 'name must not be empty'):
12681276
_imp.create_builtin(spec)
12691277

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Raise :exc:`ModuleNotFoundError` instead of crashing when a nonexistent module
2+
is used as a name in ``_imp.create_builtin()``.

Python/import.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,12 +2383,12 @@ is_builtin(PyObject *name)
23832383
return 0;
23842384
}
23852385

2386-
static PyModInitFunction
2387-
lookup_inittab_initfunc(const struct _Py_ext_module_loader_info* info)
2386+
static struct _inittab*
2387+
lookup_inittab_entry(const struct _Py_ext_module_loader_info* info)
23882388
{
23892389
for (struct _inittab *p = INITTAB; p->name != NULL; p++) {
23902390
if (_PyUnicode_EqualToASCIIString(info->name, p->name)) {
2391-
return (PyModInitFunction)p->initfunc;
2391+
return p;
23922392
}
23932393
}
23942394
// not found
@@ -2430,16 +2430,28 @@ create_builtin(
24302430
_extensions_cache_delete(info.path, info.name);
24312431
}
24322432

2433-
PyModInitFunction p0 = initfunc;
2434-
if (p0 == NULL) {
2435-
p0 = lookup_inittab_initfunc(&info);
2436-
if (p0 == NULL) {
2437-
/* Cannot re-init internal module ("sys" or "builtins") */
2438-
assert(is_core_module(tstate->interp, info.name, info.path));
2439-
mod = import_add_module(tstate, info.name);
2433+
PyModInitFunction p0 = NULL;
2434+
if (initfunc == NULL) {
2435+
struct _inittab *entry = lookup_inittab_entry(&info);
2436+
if (entry == NULL) {
2437+
mod = NULL;
2438+
_PyErr_SetModuleNotFoundError(name);
24402439
goto finally;
24412440
}
2441+
2442+
p0 = (PyModInitFunction)entry->initfunc;
24422443
}
2444+
else {
2445+
p0 = initfunc;
2446+
}
2447+
2448+
if (p0 == NULL) {
2449+
/* Cannot re-init internal module ("sys" or "builtins") */
2450+
assert(is_core_module(tstate->interp, info.name, info.path));
2451+
mod = import_add_module(tstate, info.name);
2452+
goto finally;
2453+
}
2454+
24432455

24442456
#ifdef Py_GIL_DISABLED
24452457
// This call (and the corresponding call to _PyImport_CheckGILForModule())

0 commit comments

Comments
 (0)