DebugClients/Python/coverage/collector.py

changeset 5051
3586ebd9fac8
parent 4491
0d8612e24fef
equal deleted inserted replaced
5047:04e5dfbd3f3d 5051:3586ebd9fac8
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt 2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
3 3
4 """Raw data collector for coverage.py.""" 4 """Raw data collector for coverage.py."""
5 5
6 import os, sys 6 import os
7 import sys
7 8
8 from coverage import env 9 from coverage import env
9 from coverage.backward import iitems 10 from coverage.backward import iitems
10 from coverage.files import abs_file 11 from coverage.files import abs_file
11 from coverage.misc import CoverageException 12 from coverage.misc import CoverageException, isolate_module
12 from coverage.pytracer import PyTracer 13 from coverage.pytracer import PyTracer
14
15 os = isolate_module(os)
16
13 17
14 try: 18 try:
15 # Use the C extension code when we can, for speed. 19 # Use the C extension code when we can, for speed.
16 from coverage.tracer import CTracer, CFileDisposition # pylint: disable=no-name-in-module 20 from coverage.tracer import CTracer, CFileDisposition # pylint: disable=no-name-in-module
17 except ImportError: 21 except ImportError:
29 33
30 34
31 class FileDisposition(object): 35 class FileDisposition(object):
32 """A simple value type for recording what to do with a file.""" 36 """A simple value type for recording what to do with a file."""
33 pass 37 pass
38
39
40 def should_start_context(frame):
41 """Who-Tests-What hack: Determine whether this frame begins a new who-context."""
42 fn_name = frame.f_code.co_name
43 if fn_name.startswith("test"):
44 return fn_name
34 45
35 46
36 class Collector(object): 47 class Collector(object):
37 """Collects trace data. 48 """Collects trace data.
38 49
110 except ImportError: 121 except ImportError:
111 raise CoverageException( 122 raise CoverageException(
112 "Couldn't trace with concurrency=%s, the module isn't installed." % concurrency 123 "Couldn't trace with concurrency=%s, the module isn't installed." % concurrency
113 ) 124 )
114 125
126 # Who-Tests-What is just a hack at the moment, so turn it on with an
127 # environment variable.
128 self.wtw = int(os.getenv('COVERAGE_WTW', 0))
129
115 self.reset() 130 self.reset()
116 131
117 if timid: 132 if timid:
118 # Being timid: use the simple Python trace function. 133 # Being timid: use the simple Python trace function.
119 self._trace_class = PyTracer 134 self._trace_class = PyTracer
140 """Clear collected data, and prepare to collect more.""" 155 """Clear collected data, and prepare to collect more."""
141 # A dictionary mapping file names to dicts with line number keys (if not 156 # A dictionary mapping file names to dicts with line number keys (if not
142 # branch coverage), or mapping file names to dicts with line number 157 # branch coverage), or mapping file names to dicts with line number
143 # pairs as keys (if branch coverage). 158 # pairs as keys (if branch coverage).
144 self.data = {} 159 self.data = {}
160
161 # A dict mapping contexts to data dictionaries.
162 self.contexts = {}
163 self.contexts[None] = self.data
145 164
146 # A dictionary mapping file names to file tracer plugin names that will 165 # A dictionary mapping file names to file tracer plugin names that will
147 # handle them. 166 # handle them.
148 self.file_tracers = {} 167 self.file_tracers = {}
149 168
200 tracer.file_tracers = self.file_tracers 219 tracer.file_tracers = self.file_tracers
201 if hasattr(tracer, 'threading'): 220 if hasattr(tracer, 'threading'):
202 tracer.threading = self.threading 221 tracer.threading = self.threading
203 if hasattr(tracer, 'check_include'): 222 if hasattr(tracer, 'check_include'):
204 tracer.check_include = self.check_include 223 tracer.check_include = self.check_include
224 if self.wtw:
225 if hasattr(tracer, 'should_start_context'):
226 tracer.should_start_context = should_start_context
227 if hasattr(tracer, 'switch_context'):
228 tracer.switch_context = self.switch_context
205 229
206 fn = tracer.start() 230 fn = tracer.start()
207 self.tracers.append(tracer) 231 self.tracers.append(tracer)
208 232
209 return fn 233 return fn
288 tracer.stop() 312 tracer.stop()
289 stats = tracer.get_stats() 313 stats = tracer.get_stats()
290 if stats: 314 if stats:
291 print("\nCoverage.py tracer stats:") 315 print("\nCoverage.py tracer stats:")
292 for k in sorted(stats.keys()): 316 for k in sorted(stats.keys()):
293 print("%16s: %s" % (k, stats[k])) 317 print("%20s: %s" % (k, stats[k]))
294 if self.threading: 318 if self.threading:
295 self.threading.settrace(None) 319 self.threading.settrace(None)
296 320
297 def resume(self): 321 def resume(self):
298 """Resume tracing after a `pause`.""" 322 """Resume tracing after a `pause`."""
301 if self.threading: 325 if self.threading:
302 self.threading.settrace(self._installation_trace) 326 self.threading.settrace(self._installation_trace)
303 else: 327 else:
304 self._start_tracer() 328 self._start_tracer()
305 329
330 def switch_context(self, new_context):
331 """Who-Tests-What hack: switch to a new who-context."""
332 # Make a new data dict, or find the existing one, and switch all the
333 # tracers to use it.
334 data = self.contexts.setdefault(new_context, {})
335 for tracer in self.tracers:
336 tracer.data = data
337
306 def save_data(self, covdata): 338 def save_data(self, covdata):
307 """Save the collected data to a `CoverageData`. 339 """Save the collected data to a `CoverageData`.
308 340
309 Also resets the collector. 341 Also resets the collector.
310 342
317 covdata.add_arcs(abs_file_dict(self.data)) 349 covdata.add_arcs(abs_file_dict(self.data))
318 else: 350 else:
319 covdata.add_lines(abs_file_dict(self.data)) 351 covdata.add_lines(abs_file_dict(self.data))
320 covdata.add_file_tracers(abs_file_dict(self.file_tracers)) 352 covdata.add_file_tracers(abs_file_dict(self.file_tracers))
321 353
354 if self.wtw:
355 # Just a hack, so just hack it.
356 import pprint
357 out_file = "coverage_wtw_{:06}.py".format(os.getpid())
358 with open(out_file, "w") as wtw_out:
359 pprint.pprint(self.contexts, wtw_out)
360
322 self.reset() 361 self.reset()
323 362
324 # 363 #
325 # eflag: FileType = Python2 364 # eflag: FileType = Python2

eric ide

mercurial