Issue #15767: Touch up ModuleNotFoundError usage by import.
Forgot to raise ModuleNotFoundError when None is found in sys.modules.
This led to introducing the C function PyErr_SetImportErrorSubclass()
to make setting ModuleNotFoundError easier.
Also updated the reference docs to mention ModuleNotFoundError
appropriately. Updated the docs for ModuleNotFoundError to mention the
None in sys.modules case.
Lastly, it was noticed that PyErr_SetImportError() was not setting an
exception when returning None in one case. That issue is now fixed.
diff --git a/Python/errors.c b/Python/errors.c
index 1f955b5..89021aa 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -619,12 +619,25 @@
#endif /* MS_WINDOWS */
PyObject *
-PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
+PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
+ PyObject *name, PyObject *path)
{
+ int issubclass;
PyObject *args, *kwargs, *error;
- if (msg == NULL)
+ issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
+ if (issubclass < 0) {
return NULL;
+ }
+ else if (!issubclass) {
+ PyErr_SetString(PyExc_TypeError, "expected a subclass of ImportError");
+ return NULL;
+ }
+
+ if (msg == NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a message argument");
+ return NULL;
+ }
args = PyTuple_New(1);
if (args == NULL)
@@ -649,7 +662,7 @@
PyDict_SetItemString(kwargs, "name", name);
PyDict_SetItemString(kwargs, "path", path);
- error = PyObject_Call(PyExc_ImportError, args, kwargs);
+ error = PyObject_Call(exception, args, kwargs);
if (error != NULL) {
PyErr_SetObject((PyObject *)Py_TYPE(error), error);
Py_DECREF(error);
@@ -661,6 +674,12 @@
return NULL;
}
+PyObject *
+PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
+{
+ return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path);
+}
+
void
_PyErr_BadInternalCall(const char *filename, int lineno)
{
diff --git a/Python/import.c b/Python/import.c
index 0bb46d2..fad54e6 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1436,7 +1436,8 @@
PyObject *msg = PyUnicode_FromFormat("import of %R halted; "
"None in sys.modules", abs_name);
if (msg != NULL) {
- PyErr_SetImportError(msg, abs_name, NULL);
+ PyErr_SetImportErrorSubclass(PyExc_ModuleNotFoundError, msg,
+ abs_name, NULL);
Py_DECREF(msg);
}
mod = NULL;
diff --git a/Python/importlib.h b/Python/importlib.h
index 4067631..e2f60c9 100644
--- a/Python/importlib.h
+++ b/Python/importlib.h
@@ -3239,8 +3239,8 @@
0,114,64,1,0,0,114,59,1,0,0,114,96,0,0,0,
114,56,1,0,0,114,7,0,0,0,114,145,0,0,0,114,
69,1,0,0,244,11,0,0,0,95,103,99,100,95,105,109,
- 112,111,114,116,114,97,0,0,0,114,46,0,0,0,114,156,
- 0,0,0,114,98,0,0,0,40,5,0,0,0,114,66,0,
+ 112,111,114,116,114,97,0,0,0,114,46,0,0,0,114,66,
+ 1,0,0,114,98,0,0,0,40,5,0,0,0,114,66,0,
0,0,114,57,1,0,0,114,58,1,0,0,114,160,0,0,
0,114,139,0,0,0,114,4,0,0,0,114,4,0,0,0,
114,5,0,0,0,114,70,1,0,0,61,6,0,0,115,26,