diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2009-03-13 06:28:25 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2009-03-13 06:28:25 -0400 |
commit | 60c91428b2baa1844914c6852fa9d159703741fd (patch) | |
tree | 6fd5e2e49a367db09edbe9a9082b9d3063a98c22 | |
parent | 4b9a45174e54933df7acc851474ab53d5fc51941 (diff) | |
download | python-coveragepy-git-60c91428b2baa1844914c6852fa9d159703741fd.tar.gz |
Refactor the annotate code into annotate.py
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | coverage/annotate.py | 75 | ||||
-rw-r--r-- | coverage/cmdline.py | 4 | ||||
-rw-r--r-- | coverage/control.py | 77 | ||||
-rw-r--r-- | coverage/summary.py | 8 |
5 files changed, 97 insertions, 70 deletions
@@ -7,7 +7,8 @@ Version 3.0b2 Continued refactoring.
--
+- coverage.annotate_file is no longer available.
+
Version 3.0b1
-------------
diff --git a/coverage/annotate.py b/coverage/annotate.py new file mode 100644 index 00000000..2d7d04a7 --- /dev/null +++ b/coverage/annotate.py @@ -0,0 +1,75 @@ +"""Source file annotation for coverage.py""" + +import os, re + +from coverage.codeunit import code_unit_factory + +class AnnotateReporter: + def __init__(self, coverage, ignore_errors=False): + self.coverage = coverage + self.ignore_errors = ignore_errors + + self.directory = None + + blank_re = re.compile(r"\s*(#|$)") + else_re = re.compile(r"\s*else\s*:\s*(#|$)") + + def report(self, morfs, directory=None, omit_prefixes=None): + morfs = morfs or self.coverage.data.executed_files() + code_units = code_unit_factory(morfs, self.coverage.file_locator, omit_prefixes) + self.directory = directory + for cu in code_units: + try: + filename, statements, excluded, missing, _ = self.coverage.analyze(cu) + self.annotate_file(filename, statements, excluded, missing) + except KeyboardInterrupt: + raise + except: + if not self.ignore_errors: + raise + + def annotate_file(self, filename, statements, excluded, missing): + source = open(filename, 'r') + if self.directory: + dest_file = os.path.join(self.directory, + os.path.basename(filename) + + ',cover') + else: + dest_file = filename + ',cover' + dest = open(dest_file, 'w') + lineno = 0 + i = 0 + j = 0 + covered = True + while True: + line = source.readline() + if line == '': + break + lineno = lineno + 1 + while i < len(statements) and statements[i] < lineno: + i = i + 1 + while j < len(missing) and missing[j] < lineno: + j = j + 1 + if i < len(statements) and statements[i] == lineno: + covered = j >= len(missing) or missing[j] > lineno + if self.blank_re.match(line): + dest.write(' ') + elif self.else_re.match(line): + # Special logic for lines containing only 'else:'. + if i >= len(statements) and j >= len(missing): + dest.write('! ') + elif i >= len(statements) or j >= len(missing): + dest.write('> ') + elif statements[i] == missing[j]: + dest.write('! ') + else: + dest.write('> ') + elif lineno in excluded: + dest.write('- ') + elif covered: + dest.write('> ') + else: + dest.write('! ') + dest.write(line) + source.close() + dest.close() diff --git a/coverage/cmdline.py b/coverage/cmdline.py index ee82eca2..0787f19e 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -2,6 +2,7 @@ import getopt, os, sys +from coverage.annotate import AnnotateReporter from coverage.summary import SummaryReporter USAGE = r""" @@ -141,7 +142,8 @@ class CoverageScript: reporter = SummaryReporter(self.coverage, show_missing, ignore_errors) reporter.report(args, omit_prefixes=omit) if settings.get('annotate'): - self.coverage.annotate(args, directory, ignore_errors, omit_prefixes=omit) + reporter = AnnotateReporter(self.coverage, ignore_errors) + reporter.report(args, directory, omit_prefixes=omit) # Main entrypoint. This is installed as the script entrypoint, so don't diff --git a/coverage/control.py b/coverage/control.py index cd1a515a..5fc08247 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -1,7 +1,8 @@ """Core control stuff for coverage.py""" -import os, re, sys +import os +from coverage.annotate import AnnotateReporter from coverage.codeunit import code_unit_factory from coverage.data import CoverageData from coverage.files import FileLocator @@ -162,66 +163,14 @@ class coverage: reporter = SummaryReporter(self, show_missing, ignore_errors) reporter.report(morfs, outfile=file) - # annotate(morfs, ignore_errors). - - blank_re = re.compile(r"\s*(#|$)") - else_re = re.compile(r"\s*else\s*:\s*(#|$)") - - def annotate(self, morfs, directory=None, ignore_errors=False, omit_prefixes=None): - morfs = morfs or self.data.executed_files() - code_units = code_unit_factory(morfs, self.file_locator, omit_prefixes) - for cu in code_units: - try: - filename, statements, excluded, missing, _ = self.analyze(cu) - self.annotate_file(filename, statements, excluded, missing, directory) - except KeyboardInterrupt: - raise - except: - if not ignore_errors: - raise - - def annotate_file(self, filename, statements, excluded, missing, directory=None): - source = open(filename, 'r') - if directory: - dest_file = os.path.join(directory, - os.path.basename(filename) - + ',cover') - else: - dest_file = filename + ',cover' - dest = open(dest_file, 'w') - lineno = 0 - i = 0 - j = 0 - covered = True - while True: - line = source.readline() - if line == '': - break - lineno = lineno + 1 - while i < len(statements) and statements[i] < lineno: - i = i + 1 - while j < len(missing) and missing[j] < lineno: - j = j + 1 - if i < len(statements) and statements[i] == lineno: - covered = j >= len(missing) or missing[j] > lineno - if self.blank_re.match(line): - dest.write(' ') - elif self.else_re.match(line): - # Special logic for lines containing only 'else:'. - if i >= len(statements) and j >= len(missing): - dest.write('! ') - elif i >= len(statements) or j >= len(missing): - dest.write('> ') - elif statements[i] == missing[j]: - dest.write('! ') - else: - dest.write('> ') - elif lineno in excluded: - dest.write('- ') - elif covered: - dest.write('> ') - else: - dest.write('! ') - dest.write(line) - source.close() - dest.close() + def annotate(self, morfs, directory=None, ignore_errors=False): + """Annotate a list of modules. + + Each module in `morfs` is annotated. The source is written to a new + file, named with a ",cover" suffix, with each line prefixed with a + marker to indicate the coverage of the line. Covered lines have ">", + excluded lines have "-", and missing lines have "!". + + """ + reporter = AnnotateReporter(self, ignore_errors) + reporter.report(morfs, directory) diff --git a/coverage/summary.py b/coverage/summary.py index 011c07e2..804709d0 100644 --- a/coverage/summary.py +++ b/coverage/summary.py @@ -8,15 +8,15 @@ class SummaryReporter: """A reporter for writing the summary report.""" def __init__(self, coverage, show_missing=True, ignore_errors=False): - self.cov = coverage + self.coverage = coverage self.show_missing = show_missing self.ignore_errors = ignore_errors def report(self, morfs, omit_prefixes=None, outfile=None): """Writes a report summarizing coverage statistics per module.""" - morfs = morfs or self.cov.data.executed_files() - code_units = code_unit_factory(morfs, self.cov.file_locator, omit_prefixes) + morfs = morfs or self.coverage.data.executed_files() + code_units = code_unit_factory(morfs, self.coverage.file_locator, omit_prefixes) code_units.sort() max_name = max(5, max(map(lambda cu: len(cu.name), code_units))) @@ -35,7 +35,7 @@ class SummaryReporter: total_executed = 0 for cu in code_units: try: - _, statements, _, missing, readable = self.cov.analyze(cu) + _, statements, _, missing, readable = self.coverage.analyze(cu) n = len(statements) m = n - len(missing) if n > 0: |