Close #19880: Fix a reference leak in unittest.TestCase. Explicitly break

reference cycles between frames and the _Outcome instance.
This commit is contained in:
Victor Stinner 2013-12-09 01:52:50 +01:00
parent 28dd6deca8
commit 031bd532c4
3 changed files with 42 additions and 1 deletions

View file

@ -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."""