]> granicus.if.org Git - python/commitdiff
Issue #9815: assertRaises now tries to clear references to local variables in the...
authorAntoine Pitrou <solipsis@pitrou.net>
Mon, 28 Apr 2014 23:23:50 +0000 (01:23 +0200)
committerAntoine Pitrou <solipsis@pitrou.net>
Mon, 28 Apr 2014 23:23:50 +0000 (01:23 +0200)
Lib/unittest/case.py
Lib/unittest/test/test_assertions.py
Misc/NEWS

index bedbc670d21688934a31d63885b82da848ac67f0..aa00b7accf4cad584fd5aad9af96b32171382bda 100644 (file)
@@ -9,6 +9,7 @@ import re
 import warnings
 import collections
 import contextlib
+import traceback
 
 from . import result
 from .util import (strclass, safe_repr, _count_diff_all_purpose,
@@ -178,6 +179,8 @@ class _AssertRaisesContext(_AssertRaisesBaseContext):
                                                                 self.obj_name))
             else:
                 self._raiseFailure("{} not raised".format(exc_name))
+        else:
+            traceback.clear_frames(tb)
         if not issubclass(exc_type, self.expected):
             # let unexpected exceptions pass through
             return False
index af08d5ad65a86ec84a9d792a7cb03f18bc643900..c349a95794f76a95b508db3967c07b1973214799 100644 (file)
@@ -1,5 +1,6 @@
 import datetime
 import warnings
+import weakref
 import unittest
 from itertools import product
 
@@ -97,6 +98,36 @@ class Test_Assertions(unittest.TestCase):
         else:
             self.fail("assertRaises() didn't let exception pass through")
 
+    def test_assertRaises_frames_survival(self):
+        # Issue #9815: assertRaises should avoid keeping local variables
+        # in a traceback alive.
+        class A:
+            pass
+        wr = None
+
+        class Foo(unittest.TestCase):
+
+            def foo(self):
+                nonlocal wr
+                a = A()
+                wr = weakref.ref(a)
+                try:
+                    raise IOError
+                except IOError:
+                    raise ValueError
+
+            def test_functional(self):
+                self.assertRaises(ValueError, self.foo)
+
+            def test_with(self):
+                with self.assertRaises(ValueError):
+                    self.foo()
+
+        Foo("test_functional").run()
+        self.assertIsNone(wr())
+        Foo("test_with").run()
+        self.assertIsNone(wr())
+
     def testAssertNotRegex(self):
         self.assertNotRegex('Ala ma kota', r'r+')
         try:
index 856520fb2bc3ea0d69c71480b4978f3301cda2e5..3975afa462556956a618b347e99e0e7f5df5ce38 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #9815: assertRaises now tries to clear references to local variables
+  in the exception's traceback.
+
 - Issue #13204: Calling sys.flags.__new__ would crash the interpreter,
   now it raises a TypeError.