[Python-3000-checkins] r62847 - in python/branches/py3k: Lib/test/test_exceptions.py Python/ceval.c
barry.warsaw
python-3000-checkins at python.org
Thu May 8 06:26:36 CEST 2008
Author: barry.warsaw
Date: Thu May 8 06:26:35 2008
New Revision: 62847
Log:
Antoine Pitrou's patch for bug 2507; exception state lives too long in
3.0.
Modified:
python/branches/py3k/Lib/test/test_exceptions.py
python/branches/py3k/Python/ceval.c
Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py (original)
+++ python/branches/py3k/Lib/test/test_exceptions.py Thu May 8 06:26:35 2008
@@ -4,6 +4,7 @@
import sys
import unittest
import pickle
+import weakref
from test.test_support import TESTFN, unlink, run_unittest
@@ -400,8 +401,9 @@
self.failUnless(str(Exception('a')))
self.failUnless(str(Exception('a')))
- def testExceptionCleanup(self):
- # Make sure "except V as N" exceptions are cleaned up properly
+ def testExceptionCleanupNames(self):
+ # Make sure the local variable bound to the exception instance by
+ # an "except" statement is only visible inside the except block.
try:
raise Exception()
@@ -410,6 +412,31 @@
del e
self.failIf('e' in locals())
+ def testExceptionCleanupState(self):
+ # Make sure exception state is cleaned up as soon as the except
+ # block is left. See #2507
+
+ class MyException(Exception):
+ def __init__(self, obj):
+ self.obj = obj
+ class MyObj:
+ pass
+
+ def inner_raising_func():
+ # Create some references in exception value and traceback
+ local_ref = obj
+ raise MyException(obj)
+
+ obj = MyObj()
+ wr = weakref.ref(obj)
+ try:
+ inner_raising_func()
+ except MyException as e:
+ pass
+ obj = None
+ obj = wr()
+ self.failUnless(obj is None, "%s" % obj)
+
def test_main():
run_unittest(ExceptionTests)
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Thu May 8 06:26:35 2008
@@ -1477,6 +1477,19 @@
"'finally' pops bad exception");
why = WHY_EXCEPTION;
}
+ /*
+ Make sure the exception state is cleaned up before
+ the end of an except block. This ensures objects
+ referenced by the exception state are not kept
+ alive too long.
+ See #2507.
+ */
+ if (tstate->frame->f_exc_type != NULL)
+ reset_exc_info(tstate);
+ else {
+ assert(tstate->frame->f_exc_value == NULL);
+ assert(tstate->frame->f_exc_traceback == NULL);
+ }
Py_DECREF(v);
break;
More information about the Python-3000-checkins
mailing list