port 8d05f697acd4 (#11627)

This commit is contained in:
Benjamin Peterson 2011-07-15 14:15:40 -05:00
parent 2659140a5d
commit c3349cd22e
3 changed files with 21 additions and 2 deletions

View file

@ -464,6 +464,14 @@ class ExceptionTests(unittest.TestCase):
self.assertTrue(e is RuntimeError, e) self.assertTrue(e is RuntimeError, e)
self.assertIn("maximum recursion depth exceeded", str(v)) 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 # Helper class used by TestSameStrAndUnicodeMsg

View file

@ -9,6 +9,9 @@ What's New in Python 2.7.3?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #11627: Fix segfault when __new__ on a exception returns a non-exception
class.
- Issue #12149: Update the method cache after a type's dictionnary gets - Issue #12149: Update the method cache after a type's dictionnary gets
cleared by the garbage collector. This fixes a segfault when an instance cleared by the garbage collector. This fixes a segfault when an instance
and its type get caught in a reference cycle, and the instance's and its type get caught in a reference cycle, and the instance's

View file

@ -3515,9 +3515,17 @@ do_raise(PyObject *type, PyObject *value, PyObject *tb)
Py_DECREF(tmp); Py_DECREF(tmp);
} }
if (PyExceptionClass_Check(type)) if (PyExceptionClass_Check(type)) {
PyErr_NormalizeException(&type, &value, &tb); 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)) { else if (PyExceptionInstance_Check(type)) {
/* Raising an instance. The value should be a dummy. */ /* Raising an instance. The value should be a dummy. */
if (value != Py_None) { if (value != Py_None) {