Skip to content

Commit

Permalink
Issue #9815: assertRaises now tries to clear references to local vari…
Browse files Browse the repository at this point in the history
…ables in the exception's traceback.
  • Loading branch information
pitrou committed Apr 28, 2014
1 parent 871dfc4 commit 9681022
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Lib/unittest/case.py
Expand Up @@ -9,6 +9,7 @@
import warnings
import collections
import contextlib
import traceback

from . import result
from .util import (strclass, safe_repr, _count_diff_all_purpose,
Expand Down Expand Up @@ -178,6 +179,8 @@ def __exit__(self, exc_type, exc_value, tb):
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

This comment has been minimized.

Copy link
@blueyed

blueyed Feb 26, 2020

Contributor

Maybe clearing the traceback frames should only get done for expected exceptions? (https://bugs.python.org/issue39766)

Expand Down
31 changes: 31 additions & 0 deletions Lib/unittest/test/test_assertions.py
@@ -1,5 +1,6 @@
import datetime
import warnings
import weakref
import unittest
from itertools import product

Expand Down Expand Up @@ -97,6 +98,36 @@ def _raise(e):
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())

This comment has been minimized.

Copy link
@blueyed

blueyed Feb 26, 2020

Contributor

The test passes also without the traceback.clear_frames(tb) (from above), since bbd3cf8.


def testAssertNotRegex(self):
self.assertNotRegex('Ala ma kota', r'r+')
try:
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Expand Up @@ -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.

Expand Down

0 comments on commit 9681022

Please sign in to comment.