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]

Reply via email to