Thu, 10 Apr 2014 23:02:20 +0200
updated coverage to 3.7.1
(grafted from fac17a82b4314c14a5eea4fdc158059fa0540566)
3497 | 1 | """Imposter encodings module that installs a coverage-style tracer. |
2 | ||
3 | This is NOT the encodings module; it is an imposter that sets up tracing | |
4 | instrumentation and then replaces itself with the real encodings module. | |
5 | ||
6 | If the directory that holds this file is placed first in the PYTHONPATH when | |
7 | using "coverage" to run Python's tests, then this file will become the very | |
8 | first module imported by the internals of Python 3. It installs a | |
9 | coverage-compatible trace function that can watch Standard Library modules | |
10 | execute from the very earliest stages of Python's own boot process. This fixes | |
11 | a problem with coverage - that it starts too late to trace the coverage of many | |
12 | of the most fundamental modules in the Standard Library. | |
13 | ||
14 | """ | |
15 | ||
16 | import sys | |
17 | ||
18 | class FullCoverageTracer(object): | |
19 | def __init__(self): | |
20 | # `traces` is a list of trace events. Frames are tricky: the same | |
21 | # frame object is used for a whole scope, with new line numbers | |
22 | # written into it. So in one scope, all the frame objects are the | |
23 | # same object, and will eventually all will point to the last line | |
24 | # executed. So we keep the line numbers alongside the frames. | |
25 | # The list looks like: | |
26 | # | |
27 | # traces = [ | |
28 | # ((frame, event, arg), lineno), ... | |
29 | # ] | |
30 | # | |
31 | self.traces = [] | |
32 | ||
33 | def fullcoverage_trace(self, *args): | |
34 | frame, event, arg = args | |
35 | self.traces.append((args, frame.f_lineno)) | |
36 | return self.fullcoverage_trace | |
37 | ||
38 | sys.settrace(FullCoverageTracer().fullcoverage_trace) | |
39 | ||
40 | # In coverage/files.py is actual_filename(), which uses glob.glob. I don't | |
41 | # understand why, but that use of glob borks everything if fullcoverage is in | |
42 | # effect. So here we make an ugly hail-mary pass to switch off glob.glob over | |
43 | # there. This means when using fullcoverage, Windows path names will not be | |
44 | # their actual case. | |
45 | ||
46 | #sys.fullcoverage = True | |
47 | ||
48 | # Finally, remove our own directory from sys.path; remove ourselves from | |
49 | # sys.modules; and re-import "encodings", which will be the real package | |
50 | # this time. Note that the delete from sys.modules dictionary has to | |
51 | # happen last, since all of the symbols in this module will become None | |
52 | # at that exact moment, including "sys". | |
53 | ||
54 | parentdir = max(filter(__file__.startswith, sys.path), key=len) | |
55 | sys.path.remove(parentdir) | |
56 | del sys.modules['encodings'] | |
57 | import encodings |