Commit 1966f1c9 authored by Collin Winter's avatar Collin Winter

Fix refleaks exposed by test_raise.

parent 1963ad31
...@@ -37,6 +37,18 @@ class TestRaise(unittest.TestCase): ...@@ -37,6 +37,18 @@ class TestRaise(unittest.TestCase):
else: else:
self.fail("No exception raised") self.fail("No exception raised")
def test_erroneous_exception(self):
class MyException(Exception):
def __init__(self):
raise RuntimeError()
try:
raise MyException
except RuntimeError:
pass
else:
self.fail("No exception raised")
class TestCause(unittest.TestCase): class TestCause(unittest.TestCase):
def test_invalid_cause(self): def test_invalid_cause(self):
...@@ -64,6 +76,18 @@ class TestCause(unittest.TestCase): ...@@ -64,6 +76,18 @@ class TestCause(unittest.TestCase):
else: else:
self.fail("No exception raised") self.fail("No exception raised")
def test_erroneous_cause(self):
class MyException(Exception):
def __init__(self):
raise RuntimeError()
try:
raise IndexError from MyException
except RuntimeError:
pass
else:
self.fail("No exception raised")
class TestTraceback(unittest.TestCase): class TestTraceback(unittest.TestCase):
def test_sets_traceback(self): def test_sets_traceback(self):
......
...@@ -28,7 +28,7 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -28,7 +28,7 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
/* the dict is created on the fly in PyObject_GenericSetAttr */ /* the dict is created on the fly in PyObject_GenericSetAttr */
self->dict = NULL; self->dict = NULL;
self->traceback = NULL; self->traceback = self->cause = self->context = NULL;
self->args = PyTuple_New(0); self->args = PyTuple_New(0);
if (!self->args) { if (!self->args) {
...@@ -58,6 +58,8 @@ BaseException_clear(PyBaseExceptionObject *self) ...@@ -58,6 +58,8 @@ BaseException_clear(PyBaseExceptionObject *self)
Py_CLEAR(self->dict); Py_CLEAR(self->dict);
Py_CLEAR(self->args); Py_CLEAR(self->args);
Py_CLEAR(self->traceback); Py_CLEAR(self->traceback);
Py_CLEAR(self->cause);
Py_CLEAR(self->context);
return 0; return 0;
} }
...@@ -75,6 +77,8 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg) ...@@ -75,6 +77,8 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
Py_VISIT(self->dict); Py_VISIT(self->dict);
Py_VISIT(self->args); Py_VISIT(self->args);
Py_VISIT(self->traceback); Py_VISIT(self->traceback);
Py_VISIT(self->cause);
Py_VISIT(self->context);
return 0; return 0;
} }
......
...@@ -2967,7 +2967,6 @@ do_raise(PyObject *exc, PyObject *cause) ...@@ -2967,7 +2967,6 @@ do_raise(PyObject *exc, PyObject *cause)
/* Not something you can raise. You get an exception /* Not something you can raise. You get an exception
anyway, just not what you specified :-) */ anyway, just not what you specified :-) */
Py_DECREF(exc); Py_DECREF(exc);
Py_XDECREF(cause);
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"exceptions must derive from BaseException"); "exceptions must derive from BaseException");
goto raise_error; goto raise_error;
...@@ -2980,12 +2979,12 @@ do_raise(PyObject *exc, PyObject *cause) ...@@ -2980,12 +2979,12 @@ do_raise(PyObject *exc, PyObject *cause)
fixed_cause = PyObject_CallObject(cause, NULL); fixed_cause = PyObject_CallObject(cause, NULL);
if (fixed_cause == NULL) if (fixed_cause == NULL)
goto raise_error; goto raise_error;
Py_DECREF(cause);
} }
else if (PyExceptionInstance_Check(cause)) { else if (PyExceptionInstance_Check(cause)) {
fixed_cause = cause; fixed_cause = cause;
} }
else { else {
Py_DECREF(cause);
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"exception causes must derive from BaseException"); "exception causes must derive from BaseException");
goto raise_error; goto raise_error;
...@@ -3000,6 +2999,7 @@ raise_error: ...@@ -3000,6 +2999,7 @@ raise_error:
Py_XDECREF(value); Py_XDECREF(value);
Py_XDECREF(type); Py_XDECREF(type);
Py_XDECREF(tb); Py_XDECREF(tb);
Py_XDECREF(cause);
return WHY_EXCEPTION; return WHY_EXCEPTION;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment