Merge lp:~gz/testtools/avoid_exc_info_cycles into lp:~testtools-committers/testtools/trunk

Proposed by Martin Packman
Status: Merged
Merged at revision: 103
Proposed branch: lp:~gz/testtools/avoid_exc_info_cycles
Merge into: lp:~testtools-committers/testtools/trunk
Diff against target: 79 lines (+19/-9)
4 files modified
testtools/run.py (+1/-3)
testtools/runtest.py (+5/-2)
testtools/testcase.py (+12/-4)
testtools/tests/helpers.py (+1/-0)
To merge this branch: bzr merge lp:~gz/testtools/avoid_exc_info_cycles
Reviewer Review Type Date Requested Status
Robert Collins Approve
Review via email: mp+32726@code.launchpad.net

Description of the change

Adds try/finally/del in a few places that assigned result of sys.exc_info call to a local variable. This creates a reference cycle, which while mostly harmless as will be dealt with by gc, can be annoying when trying to write deterministic code.

There are a couple I've not resolved. The one in testtools.tests.helpers was easy to avoid by not using that (non-public?) module. The expectedFailure method has me stumped for the moment, as the unittest _ExpectedFailure signature isn't as sane as the old Bazaar version (see also bug 607400). On irc lifeless suggested some frame mangling might be able to fix this, any hints on that I'd appreciate.

See <lp:~gz/bzr/cleanup_testcases_by_collection_613247> for branch to bzr that prompted this change.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

I've also tweaked this one - you had no test coverage (your change only checked the error path), and I've made the no-reason fallback supply the whole details dict (because something has obviously gone wrong).

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

bah wrong mp

Revision history for this message
Robert Collins (lifeless) wrote :

there was a conflict with my multiple-exception support, I've trivially resolved that, but its possible that that work added more cycles.

review: Approve
Revision history for this message
Martin Packman (gz) wrote :

Thanks! The merge looks fine by eyeball, once lp:~gz/bzr/transport_post_connect_hook lands which will unblock me on the test collection front I'll double check that everything still works as expected.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'testtools/run.py'
2--- testtools/run.py 2010-07-01 11:33:57 +0000
3+++ testtools/run.py 2010-08-15 23:26:39 +0000
4@@ -187,9 +187,7 @@
5 self.testNames = (self.defaultTest,)
6 self.createTests()
7 except getopt.error:
8- exc_info = sys.exc_info()
9- msg = exc_info[1]
10- self.usageExit(msg)
11+ self.usageExit(sys.exc_info()[1])
12
13 def createTests(self):
14 if self.testNames is None:
15
16=== modified file 'testtools/runtest.py'
17--- testtools/runtest.py 2010-07-29 18:20:02 +0000
18+++ testtools/runtest.py 2010-08-15 23:26:39 +0000
19@@ -146,8 +146,11 @@
20 raise
21 except:
22 exc_info = sys.exc_info()
23- e = exc_info[1]
24- self.case.onException(exc_info)
25+ try:
26+ e = exc_info[1]
27+ self.case.onException(exc_info)
28+ finally:
29+ del exc_info
30 for exc_class, handler in self.handlers:
31 if isinstance(e, exc_class):
32 self._exceptions.append(e)
33
34=== modified file 'testtools/testcase.py'
35--- testtools/testcase.py 2010-08-04 13:05:20 +0000
36+++ testtools/testcase.py 2010-08-15 23:26:39 +0000
37@@ -179,8 +179,11 @@
38 raise
39 except:
40 exc_info = sys.exc_info()
41- self._report_traceback(exc_info)
42- last_exception = exc_info[1]
43+ try:
44+ self._report_traceback(exc_info)
45+ last_exception = exc_info[1]
46+ finally:
47+ del exc_info
48 return last_exception
49
50 def addCleanup(self, function, *arguments, **keywordArguments):
51@@ -319,9 +322,14 @@
52 try:
53 predicate(*args, **kwargs)
54 except self.failureException:
55+ # GZ 2010-08-12: Don't know how to avoid exc_info cycle as the new
56+ # unittest _ExpectedFailure wants old traceback
57 exc_info = sys.exc_info()
58- self._report_traceback(exc_info)
59- raise _ExpectedFailure(exc_info)
60+ try:
61+ self._report_traceback(exc_info)
62+ raise _ExpectedFailure(exc_info)
63+ finally:
64+ del exc_info
65 else:
66 raise _UnexpectedSuccess(reason)
67
68
69=== modified file 'testtools/tests/helpers.py'
70--- testtools/tests/helpers.py 2009-12-31 03:15:19 +0000
71+++ testtools/tests/helpers.py 2010-08-15 23:26:39 +0000
72@@ -12,6 +12,7 @@
73 from testtools import TestResult
74
75
76+# GZ 2010-08-12: Don't do this, pointlessly creates an exc_info cycle
77 try:
78 raise Exception
79 except Exception:

Subscribers

People subscribed via source and target branches