-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathannotate.py
88 lines (67 loc) · 2.67 KB
/
annotate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
"""Source file annotation for coverage.py."""
import io
import os
import re
from coverage.files import flat_rootname
from coverage.misc import isolate_module
from coverage.report import Reporter
os = isolate_module(os)
class AnnotateReporter(Reporter):
"""Generate annotated source files showing line coverage.
This reporter creates annotated copies of the measured source files. Each
.py file is copied as a .py,cover file, with a left-hand margin annotating
each line::
> def h(x):
- if 0: #pragma: no cover
- pass
> if x == 1:
! a = 1
> else:
> a = 2
> h(2)
Executed lines use '>', lines not executed use '!', lines excluded from
consideration use '-'.
"""
def __init__(self, coverage, config):
super(AnnotateReporter, self).__init__(coverage, config)
self.directory = None
blank_re = re.compile(r"\s*(#|$)")
else_re = re.compile(r"\s*else\s*:\s*(#|$)")
def report(self, morfs, directory=None):
"""Run the report.
See `coverage.report()` for arguments.
"""
self.report_files(self.annotate_file, morfs, directory)
def annotate_file(self, fr, analysis):
"""Annotate a single file.
`fr` is the FileReporter for the file to annotate.
"""
statements = sorted(analysis.statements)
missing = sorted(analysis.missing)
excluded = sorted(analysis.excluded)
missing_branches = sorted(analysis.missing_branch_arcs().keys())
if self.directory:
dest_file = os.path.join(self.directory, flat_rootname(fr.relative_filename()))
if dest_file.endswith("_py"):
dest_file = dest_file[:-3] + ".py"
dest_file += ",cover"
else:
dest_file = fr.filename + ",cover"
with io.open(dest_file, 'w', encoding='utf8') as dest:
source = fr.source()
for lineno, line in enumerate(source.splitlines(True), start=1):
# if lineno in analysis.statements:
# line_class.append("stm")
if lineno in excluded:
dest.write(u'- ')
elif lineno in missing:
dest.write(u'! ')
elif lineno in missing_branches:
dest.write(u'~ ')
elif lineno in statements:
dest.write(u'> ')
else:
dest.write(' ')
dest.write(line)