diff options
-rw-r--r-- | coverage/collector.py | 19 | ||||
-rw-r--r-- | coverage/fullcoverage/encodings.py | 41 |
2 files changed, 59 insertions, 1 deletions
diff --git a/coverage/collector.py b/coverage/collector.py index 9c40d16c..9752e530 100644 --- a/coverage/collector.py +++ b/coverage/collector.py @@ -233,8 +233,25 @@ class Collector(object): self._collectors[-1].pause() self._collectors.append(self) #print >>sys.stderr, "Started: %r" % self._collectors + + # Check to see whether we had a fullcoverage tracer installed. + traces0 = None + if hasattr(sys, "gettrace"): + fn0 = sys.gettrace() + if fn0: + tracer0 = getattr(fn0, '__self__', None) + if tracer0: + traces0 = getattr(tracer0, 'traces', None) + # Install the tracer on this thread. - self._start_tracer() + fn = self._start_tracer() + + if traces0: + #print("traces0 has %d" % len(traces0)) + for args in traces0: + frame, event, arg = args + fn(*args) + # Install our installation tracer in threading, to jump start other # threads. threading.settrace(self._installation_trace) diff --git a/coverage/fullcoverage/encodings.py b/coverage/fullcoverage/encodings.py new file mode 100644 index 00000000..48b2b2e0 --- /dev/null +++ b/coverage/fullcoverage/encodings.py @@ -0,0 +1,41 @@ +"""Imposter encodings module that installs a coverage-style tracer. + +This is NOT the encodings module; it is an imposter that sets up tracing +instrumentation and then replaces itself with the real encodings module. + +If the directory that holds this file is placed first in the PYTHONPATH when +using "coverage" to run Python's tests, then this file will become the very +first module imported by the internals of Python 3. It installs a +coverage-compatible trace function that can watch Standard Library modules +execute from the very earliest stages of Python's own boot process. This fixes +a problem with coverage - that it starts too late to trace the coverage of many +of the most fundamental modules in the Standard Library. + +""" + +import sys + +class FullCoverageTracer(object): + def __init__(self): + self.traces = [] + + def fullcoverage_trace(self, *args): + frame, event, arg = args + #if "os.py" in frame.f_code.co_filename: + # print("%s @ %d" % (frame.f_code.co_filename, frame.f_lineno)) + self.traces.append(args) + return self.fullcoverage_trace + +sys.settrace(FullCoverageTracer().fullcoverage_trace) + +# Finally, remove our own directory from sys.path; remove ourselves from +# sys.modules; and re-import "encodings", which will be the real package +# this time. Note that the delete from sys.modules dictionary has to +# happen last, since all of the symbols in this module will become None +# at that exact moment, including "sys". + +import os +this = os.path.dirname(__file__) +sys.path.remove(this) +del sys.modules['encodings'] +import encodings |