From 9681022f1ee5c6c9160c515b24d2a3d1efe8b90d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 29 Apr 2014 01:23:50 +0200 Subject: [PATCH] Issue #9815: assertRaises now tries to clear references to local variables in the exception's traceback. --- Lib/unittest/case.py | 3 +++ Lib/unittest/test/test_assertions.py | 31 ++++++++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 37 insertions(+) diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index bedbc670d21688..aa00b7accf4cad 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -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, @@ -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 diff --git a/Lib/unittest/test/test_assertions.py b/Lib/unittest/test/test_assertions.py index af08d5ad65a86e..c349a95794f76a 100644 --- a/Lib/unittest/test/test_assertions.py +++ b/Lib/unittest/test/test_assertions.py @@ -1,5 +1,6 @@ import datetime import warnings +import weakref import unittest from itertools import product @@ -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()) + def testAssertNotRegex(self): self.assertNotRegex('Ala ma kota', r'r+') try: diff --git a/Misc/NEWS b/Misc/NEWS index 856520fb2bc3ea..3975afa4625569 100644 --- 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.