File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 44import sys
55import unittest
66import pickle
7+ import weakref
78
89from test .test_support import TESTFN , unlink , run_unittest
910
@@ -400,8 +401,9 @@ def testUnicodeStrUsage(self):
400401 self .failUnless (str (Exception ('a' )))
401402 self .failUnless (str (Exception ('a' )))
402403
403- def testExceptionCleanup (self ):
404- # Make sure "except V as N" exceptions are cleaned up properly
404+ def testExceptionCleanupNames (self ):
405+ # Make sure the local variable bound to the exception instance by
406+ # an "except" statement is only visible inside the except block.
405407
406408 try :
407409 raise Exception ()
@@ -410,6 +412,31 @@ def testExceptionCleanup(self):
410412 del e
411413 self .failIf ('e' in locals ())
412414
415+ def testExceptionCleanupState (self ):
416+ # Make sure exception state is cleaned up as soon as the except
417+ # block is left. See #2507
418+
419+ class MyException (Exception ):
420+ def __init__ (self , obj ):
421+ self .obj = obj
422+ class MyObj :
423+ pass
424+
425+ def inner_raising_func ():
426+ # Create some references in exception value and traceback
427+ local_ref = obj
428+ raise MyException (obj )
429+
430+ obj = MyObj ()
431+ wr = weakref .ref (obj )
432+ try :
433+ inner_raising_func ()
434+ except MyException as e :
435+ pass
436+ obj = None
437+ obj = wr ()
438+ self .failUnless (obj is None , "%s" % obj )
439+
413440
414441def test_main ():
415442 run_unittest (ExceptionTests )
Original file line number Diff line number Diff line change @@ -1477,6 +1477,19 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
14771477 "'finally' pops bad exception" );
14781478 why = WHY_EXCEPTION ;
14791479 }
1480+ /*
1481+ Make sure the exception state is cleaned up before
1482+ the end of an except block. This ensures objects
1483+ referenced by the exception state are not kept
1484+ alive too long.
1485+ See #2507.
1486+ */
1487+ if (tstate -> frame -> f_exc_type != NULL )
1488+ reset_exc_info (tstate );
1489+ else {
1490+ assert (tstate -> frame -> f_exc_value == NULL );
1491+ assert (tstate -> frame -> f_exc_traceback == NULL );
1492+ }
14801493 Py_DECREF (v );
14811494 break ;
14821495
You can’t perform that action at this time.
0 commit comments