diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2009-05-03 23:31:40 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2009-05-03 23:31:40 -0400 |
commit | 998879621fe7195580ddcf5262170b80843d8cc8 (patch) | |
tree | 38307cc74002dc6203785822b7bf065b414e2d85 /coverage/collector.py | |
parent | cf74b70ae1f8e0018c604153c8637106f552b662 (diff) | |
download | python-coveragepy-git-998879621fe7195580ddcf5262170b80843d8cc8.tar.gz |
Keeping a stack of Collectors makes it possible for Coverage to measure itself (mostly).
Diffstat (limited to 'coverage/collector.py')
-rw-r--r-- | coverage/collector.py | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/coverage/collector.py b/coverage/collector.py index efc41c3b..f9bb3177 100644 --- a/coverage/collector.py +++ b/coverage/collector.py @@ -56,7 +56,6 @@ except ImportError: """Stop this Tracer.""" sys.settrace(None) - class Collector: """Collects trace data. @@ -72,6 +71,11 @@ class Collector: """ + # The stack of active Collectors. Collectors are added here when started, + # and popped when stopped. Collectors on the stack are paused when not + # the top, and resumed when they become the top again. + _collectors = [] + def __init__(self, should_trace): """Create a collector. @@ -123,6 +127,9 @@ class Collector: def start(self): """Start collecting trace information.""" + if self._collectors: + self._collectors[-1]._pause() + self._collectors.append(self) # Install the tracer on this thread. self._start_tracer() # Install our installation tracer in threading, to jump start other @@ -131,10 +138,31 @@ class Collector: def stop(self): """Stop collecting trace information.""" + assert self._collectors + assert self._collectors[-1] is self + for tracer in self.tracers: tracer.stop() self.tracers = [] threading.settrace(None) + + # Remove this Collector from the stack, and resume the one underneath + # (if any). + self._collectors.pop() + if self._collectors: + self._collectors[-1]._resume() + + def _pause(self): + """Stop tracing, but be prepared to _resume.""" + for tracer in self.tracers: + tracer.stop() + threading.settrace(None) + + def _resume(self): + """Resume tracing after a _pause.""" + for tracer in self.tracers: + tracer.start() + threading.settrace(self._installation_trace) def data_points(self): """Return the (filename, lineno) pairs collected.""" |