diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-12-09 00:52:50 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-12-09 00:52:50 (GMT) |
commit | 031bd532c48cf20a9cbf438bdae75dde49e36c51 (patch) | |
tree | 80052a8b6913721ca49b3a020cd989ec87ad0b06 /Lib/unittest/case.py | |
parent | 28dd6deca8afd79cd8c33731f01c108dd11257ab (diff) | |
download | cpython-031bd532c48cf20a9cbf438bdae75dde49e36c51.zip cpython-031bd532c48cf20a9cbf438bdae75dde49e36c51.tar.gz cpython-031bd532c48cf20a9cbf438bdae75dde49e36c51.tar.bz2 |
Close #19880: Fix a reference leak in unittest.TestCase. Explicitly break
reference cycles between frames and the _Outcome instance.
Diffstat (limited to 'Lib/unittest/case.py')
-rw-r--r-- | Lib/unittest/case.py | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 7ed932f..87fb02b 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -69,6 +69,9 @@ class _Outcome(object): else: self.success = False self.errors.append((test_case, exc_info)) + # explicitly break a reference cycle: + # exc_info -> frame -> exc_info + exc_info = None else: if self.result_supports_subtests and self.success: self.errors.append((test_case, None)) @@ -559,8 +562,8 @@ class TestCase(object): return expecting_failure = getattr(testMethod, "__unittest_expecting_failure__", False) + outcome = _Outcome(result) try: - outcome = _Outcome(result) self._outcome = outcome with outcome.testPartExecutor(self): @@ -593,6 +596,15 @@ class TestCase(object): if stopTestRun is not None: stopTestRun() + # explicitly break reference cycles: + # outcome.errors -> frame -> outcome -> outcome.errors + # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure + outcome.errors.clear() + outcome.expectedFailure = None + + # clear the outcome, no more needed + self._outcome = None + def doCleanups(self): """Execute all cleanup functions. Normally called for you after tearDown.""" |