]> granicus.if.org Git - python/commitdiff
Fix refleaks exposed by test_raise.
authorCollin Winter <collinw@gmail.com>
Sat, 1 Sep 2007 20:26:44 +0000 (20:26 +0000)
committerCollin Winter <collinw@gmail.com>
Sat, 1 Sep 2007 20:26:44 +0000 (20:26 +0000)
Lib/test/test_raise.py
Objects/exceptions.c
Python/ceval.c

index 0e19972f4efcf68360ee9415556d5cf6ef1d24d1..27a5cbcf65c19584696b4847a8765a53b524f825 100644 (file)
@@ -37,6 +37,18 @@ class TestRaise(unittest.TestCase):
         else:
             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):
     def test_invalid_cause(self):
@@ -64,6 +76,18 @@ class TestCause(unittest.TestCase):
         else:
             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):
     def test_sets_traceback(self):
index cbc41e8ba2393e46e73f106b50768f23b41153d8..ce536fd78dc562fd1af1a4f2083994fff09b550f 100644 (file)
@@ -28,7 +28,7 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         return NULL;
     /* the dict is created on the fly in PyObject_GenericSetAttr */
     self->dict = NULL;
-    self->traceback = NULL;
+    self->traceback = self->cause = self->context = NULL;
 
     self->args = PyTuple_New(0);
     if (!self->args) {
@@ -58,6 +58,8 @@ BaseException_clear(PyBaseExceptionObject *self)
     Py_CLEAR(self->dict);
     Py_CLEAR(self->args);
     Py_CLEAR(self->traceback);
+    Py_CLEAR(self->cause);
+    Py_CLEAR(self->context);
     return 0;
 }
 
@@ -75,6 +77,8 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
     Py_VISIT(self->dict);
     Py_VISIT(self->args);
     Py_VISIT(self->traceback);
+    Py_VISIT(self->cause);
+    Py_VISIT(self->context);
     return 0;
 }
 
index 24d4dec277c769d6b1293acc12ec52ec5bf0dbc1..fa08fe68403912880f65099fc188a63756c8a275 100644 (file)
@@ -2967,7 +2967,6 @@ do_raise(PyObject *exc, PyObject *cause)
                /* Not something you can raise.  You get an exception
                   anyway, just not what you specified :-) */
         Py_DECREF(exc);
-        Py_XDECREF(cause);
                PyErr_SetString(PyExc_TypeError,
                                 "exceptions must derive from BaseException");
                goto raise_error;
@@ -2980,12 +2979,12 @@ do_raise(PyObject *exc, PyObject *cause)
             fixed_cause = PyObject_CallObject(cause, NULL);
             if (fixed_cause == NULL)
                 goto raise_error;
+            Py_DECREF(cause);
         }
         else if (PyExceptionInstance_Check(cause)) {
             fixed_cause = cause;
         }
         else {
-            Py_DECREF(cause);
             PyErr_SetString(PyExc_TypeError,
                             "exception causes must derive from BaseException");
             goto raise_error;
@@ -3000,6 +2999,7 @@ raise_error:
        Py_XDECREF(value);
        Py_XDECREF(type);
        Py_XDECREF(tb);
+       Py_XDECREF(cause);
        return WHY_EXCEPTION;
 }