DebugClients/Python/coverage/annotate.py

changeset 4489
d0d6e4ad31bd
parent 3499
f2d4b02c7e88
child 4491
0d8612e24fef
equal deleted inserted replaced
4481:456c58fc64b0 4489:d0d6e4ad31bd
1 """Source file annotation for Coverage.""" 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 3
3 import os, re 4 """Source file annotation for coverage.py."""
4 5
5 from .backward import sorted # pylint: disable=W0622 6 import io
6 from .report import Reporter 7 import os
8 import re
9
10 from coverage.files import flat_rootname
11 from coverage.report import Reporter
7 12
8 class AnnotateReporter(Reporter): 13 class AnnotateReporter(Reporter):
9 """Generate annotated source files showing line coverage. 14 """Generate annotated source files showing line coverage.
10 15
11 This reporter creates annotated copies of the measured source files. Each 16 This reporter creates annotated copies of the measured source files. Each
40 See `coverage.report()` for arguments. 45 See `coverage.report()` for arguments.
41 46
42 """ 47 """
43 self.report_files(self.annotate_file, morfs, directory) 48 self.report_files(self.annotate_file, morfs, directory)
44 49
45 def annotate_file(self, cu, analysis): 50 def annotate_file(self, fr, analysis):
46 """Annotate a single file. 51 """Annotate a single file.
47 52
48 `cu` is the CodeUnit for the file to annotate. 53 `fr` is the FileReporter for the file to annotate.
49 54
50 """ 55 """
51 if not cu.relative:
52 return
53
54 filename = cu.filename
55 source = cu.source_file()
56 if self.directory:
57 dest_file = os.path.join(self.directory, cu.flat_rootname())
58 dest_file += ".py,cover"
59 else:
60 dest_file = filename + ",cover"
61 dest = open(dest_file, 'w')
62
63 statements = sorted(analysis.statements) 56 statements = sorted(analysis.statements)
64 missing = sorted(analysis.missing) 57 missing = sorted(analysis.missing)
65 excluded = sorted(analysis.excluded) 58 excluded = sorted(analysis.excluded)
66 59
67 lineno = 0 60 if self.directory:
68 i = 0 61 dest_file = os.path.join(self.directory, flat_rootname(fr.relative_filename()))
69 j = 0 62 if dest_file.endswith("_py"):
70 covered = True 63 dest_file = dest_file[:-3] + ".py"
71 while True: 64 dest_file += ",cover"
72 line = source.readline() 65 else:
73 if line == '': 66 dest_file = fr.filename + ",cover"
74 break 67
75 lineno += 1 68 with io.open(dest_file, 'w', encoding='utf8') as dest:
76 while i < len(statements) and statements[i] < lineno: 69 i = 0
77 i += 1 70 j = 0
78 while j < len(missing) and missing[j] < lineno: 71 covered = True
79 j += 1 72 source = fr.source()
80 if i < len(statements) and statements[i] == lineno: 73 for lineno, line in enumerate(source.splitlines(True), start=1):
81 covered = j >= len(missing) or missing[j] > lineno 74 while i < len(statements) and statements[i] < lineno:
82 if self.blank_re.match(line): 75 i += 1
83 dest.write(' ') 76 while j < len(missing) and missing[j] < lineno:
84 elif self.else_re.match(line): 77 j += 1
85 # Special logic for lines containing only 'else:'. 78 if i < len(statements) and statements[i] == lineno:
86 if i >= len(statements) and j >= len(missing): 79 covered = j >= len(missing) or missing[j] > lineno
87 dest.write('! ') 80 if self.blank_re.match(line):
88 elif i >= len(statements) or j >= len(missing): 81 dest.write(u' ')
89 dest.write('> ') 82 elif self.else_re.match(line):
90 elif statements[i] == missing[j]: 83 # Special logic for lines containing only 'else:'.
91 dest.write('! ') 84 if i >= len(statements) and j >= len(missing):
85 dest.write(u'! ')
86 elif i >= len(statements) or j >= len(missing):
87 dest.write(u'> ')
88 elif statements[i] == missing[j]:
89 dest.write(u'! ')
90 else:
91 dest.write(u'> ')
92 elif lineno in excluded:
93 dest.write(u'- ')
94 elif covered:
95 dest.write(u'> ')
92 else: 96 else:
93 dest.write('> ') 97 dest.write(u'! ')
94 elif lineno in excluded:
95 dest.write('- ')
96 elif covered:
97 dest.write('> ')
98 else:
99 dest.write('! ')
100 dest.write(line)
101 source.close()
102 dest.close()
103 98
104 # 99 dest.write(line)
105 # eflag: FileType = Python2

eric ide

mercurial