diff -r a56cd7aeac5e Lib/test/test_exceptions.py --- a/Lib/test/test_exceptions.py Tue Mar 22 09:06:38 2011 -0700 +++ b/Lib/test/test_exceptions.py Tue Mar 22 23:26:32 2011 +0100 @@ -464,6 +464,15 @@ self.assertTrue(e is RuntimeError, e) self.assertIn("maximum recursion depth exceeded", str(v)) + def test_new_returns_invalid_instance(self): + # See issue #11627. + class MyException(Exception): + def __new__(cls, *args): + return object() + + with self.assertRaises(TypeError): + raise MyException + # Helper class used by TestSameStrAndUnicodeMsg diff -r a56cd7aeac5e Python/ceval.c --- a/Python/ceval.c Tue Mar 22 09:06:38 2011 -0700 +++ b/Python/ceval.c Tue Mar 22 23:26:32 2011 +0100 @@ -3515,9 +3515,17 @@ Py_DECREF(tmp); } - if (PyExceptionClass_Check(type)) + if (PyExceptionClass_Check(type)) { PyErr_NormalizeException(&type, &value, &tb); - + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %s() should have returned an instance of " + "BaseException, not '%s'", + ((PyTypeObject *)type)->tp_name, + Py_TYPE(value)->tp_name); + goto raise_error; + } + } else if (PyExceptionInstance_Check(type)) { /* Raising an instance. The value should be a dummy. */ if (value != Py_None) {