Commit 70b22549 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #9815: assertRaises now tries to clear references to local variables in...

Issue #9815: assertRaises now tries to clear references to local variables in the exception's traceback.
parent 122d3239
...@@ -9,6 +9,7 @@ import re ...@@ -9,6 +9,7 @@ import re
import warnings import warnings
import collections import collections
import contextlib import contextlib
import traceback
from . import result from . import result
from .util import (strclass, safe_repr, _count_diff_all_purpose, from .util import (strclass, safe_repr, _count_diff_all_purpose,
...@@ -178,6 +179,8 @@ class _AssertRaisesContext(_AssertRaisesBaseContext): ...@@ -178,6 +179,8 @@ class _AssertRaisesContext(_AssertRaisesBaseContext):
self.obj_name)) self.obj_name))
else: else:
self._raiseFailure("{} not raised".format(exc_name)) self._raiseFailure("{} not raised".format(exc_name))
else:
traceback.clear_frames(tb)
if not issubclass(exc_type, self.expected): if not issubclass(exc_type, self.expected):
# let unexpected exceptions pass through # let unexpected exceptions pass through
return False return False
......
import datetime import datetime
import warnings import warnings
import weakref
import unittest import unittest
from itertools import product from itertools import product
...@@ -97,6 +98,36 @@ class Test_Assertions(unittest.TestCase): ...@@ -97,6 +98,36 @@ class Test_Assertions(unittest.TestCase):
else: else:
self.fail("assertRaises() didn't let exception pass through") 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): def testAssertNotRegex(self):
self.assertNotRegex('Ala ma kota', r'r+') self.assertNotRegex('Ala ma kota', r'r+')
try: try:
......
...@@ -39,6 +39,9 @@ Core and Builtins ...@@ -39,6 +39,9 @@ Core and Builtins
Library 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, - Issue #13204: Calling sys.flags.__new__ would crash the interpreter,
now it raises a TypeError. now it raises a TypeError.
......
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