diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -961,16 +961,22 @@ class ImportErrorTests(unittest.TestCase exc = ImportError('test', path='somepath') self.assertEqual(exc.path, 'somepath') self.assertIsNone(exc.name) exc = ImportError('test', path='somepath', name='somename') self.assertEqual(exc.name, 'somename') self.assertEqual(exc.path, 'somepath') + with self.assertRaises(TypeError) as cm: + ImportError('test', invalid='keyword') + self.assertEqual(str(cm.exception), + "ImportError only accepts 'name' and 'path' " + "keyword arguments") + def test_non_str_argument(self): # Issue #15778 with check_warnings(('', BytesWarning), quiet=True): arg = b'abc' exc = ImportError(arg) self.assertEqual(str(arg), str(exc)) diff --git a/Objects/exceptions.c b/Objects/exceptions.c --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -609,16 +609,17 @@ SimpleExtendsException(PyExc_BaseExcepti */ static int ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) { PyObject *msg = NULL; PyObject *name = NULL; PyObject *path = NULL; + int kwds_size; /* Macro replacement doesn't allow ## to start the first line of a macro, so we move the assignment and NULL check into the if-statement. */ #define GET_KWD(kwd) { \ kwd = PyDict_GetItemString(kwds, #kwd); \ if (kwd) { \ Py_CLEAR(self->kwd); \ self->kwd = kwd; \ @@ -626,20 +627,24 @@ ImportError_init(PyImportErrorObject *se if (PyDict_DelItemString(kwds, #kwd)) \ return -1; \ } \ } if (kwds) { GET_KWD(name); GET_KWD(path); + kwds_size = PyDict_Size(kwds); + if (kwds_size != 0) { + PyErr_SetString(PyExc_TypeError, + "ImportError only accepts 'name' and 'path' keyword arguments"); + return -1; + } } - if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) - return -1; if (PyTuple_GET_SIZE(args) != 1) return 0; if (!PyArg_UnpackTuple(args, "ImportError", 1, 1, &msg)) return -1; Py_CLEAR(self->msg); /* replacing */ self->msg = msg; Py_INCREF(self->msg);