--- a/DebugClients/Python/coverage/collector.py Sat Jul 23 13:33:54 2016 +0200 +++ b/DebugClients/Python/coverage/collector.py Sun Jul 24 12:01:01 2016 +0200 @@ -3,14 +3,18 @@ """Raw data collector for coverage.py.""" -import os, sys +import os +import sys from coverage import env from coverage.backward import iitems from coverage.files import abs_file -from coverage.misc import CoverageException +from coverage.misc import CoverageException, isolate_module from coverage.pytracer import PyTracer +os = isolate_module(os) + + try: # Use the C extension code when we can, for speed. from coverage.tracer import CTracer, CFileDisposition # pylint: disable=no-name-in-module @@ -33,6 +37,13 @@ pass +def should_start_context(frame): + """Who-Tests-What hack: Determine whether this frame begins a new who-context.""" + fn_name = frame.f_code.co_name + if fn_name.startswith("test"): + return fn_name + + class Collector(object): """Collects trace data. @@ -112,6 +123,10 @@ "Couldn't trace with concurrency=%s, the module isn't installed." % concurrency ) + # Who-Tests-What is just a hack at the moment, so turn it on with an + # environment variable. + self.wtw = int(os.getenv('COVERAGE_WTW', 0)) + self.reset() if timid: @@ -143,6 +158,10 @@ # pairs as keys (if branch coverage). self.data = {} + # A dict mapping contexts to data dictionaries. + self.contexts = {} + self.contexts[None] = self.data + # A dictionary mapping file names to file tracer plugin names that will # handle them. self.file_tracers = {} @@ -202,6 +221,11 @@ tracer.threading = self.threading if hasattr(tracer, 'check_include'): tracer.check_include = self.check_include + if self.wtw: + if hasattr(tracer, 'should_start_context'): + tracer.should_start_context = should_start_context + if hasattr(tracer, 'switch_context'): + tracer.switch_context = self.switch_context fn = tracer.start() self.tracers.append(tracer) @@ -290,7 +314,7 @@ if stats: print("\nCoverage.py tracer stats:") for k in sorted(stats.keys()): - print("%16s: %s" % (k, stats[k])) + print("%20s: %s" % (k, stats[k])) if self.threading: self.threading.settrace(None) @@ -303,6 +327,14 @@ else: self._start_tracer() + def switch_context(self, new_context): + """Who-Tests-What hack: switch to a new who-context.""" + # Make a new data dict, or find the existing one, and switch all the + # tracers to use it. + data = self.contexts.setdefault(new_context, {}) + for tracer in self.tracers: + tracer.data = data + def save_data(self, covdata): """Save the collected data to a `CoverageData`. @@ -319,6 +351,13 @@ covdata.add_lines(abs_file_dict(self.data)) covdata.add_file_tracers(abs_file_dict(self.file_tracers)) + if self.wtw: + # Just a hack, so just hack it. + import pprint + out_file = "coverage_wtw_{:06}.py".format(os.getpid()) + with open(out_file, "w") as wtw_out: + pprint.pprint(self.contexts, wtw_out) + self.reset() #