summaryrefslogtreecommitdiffstats
path: root/Lib/unittest/case.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2013-12-09 00:52:50 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2013-12-09 00:52:50 (GMT)
commit031bd532c48cf20a9cbf438bdae75dde49e36c51 (patch)
tree80052a8b6913721ca49b3a020cd989ec87ad0b06 /Lib/unittest/case.py
parent28dd6deca8afd79cd8c33731f01c108dd11257ab (diff)
downloadcpython-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.py14
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."""