diff Python/errors.c @ 84109:3a50025f1900

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.
author Brett Cannon <brett@python.org>
date Wed, 12 Jun 2013 23:29:18 -0400
parents bb94f6222fef
children e3ec8b176a80
line wrap: on
line diff
--- a/Python/errors.c	Wed Jun 12 21:25:59 2013 -0400
+++ b/Python/errors.c	Wed Jun 12 23:29:18 2013 -0400
@@ -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)
 {