From 4d45dc8c234eee1b4bd6da9eac409d588eba9455 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sun, 19 Apr 2009 08:16:50 -0400 Subject: Annotated files are only created for source files relative to the current directory. When writing to a separate file, annotation file names include the directory hierarchy flattened, so that same-named files won't collide. --HG-- rename : test/farm/annotate/gold_anno_dir/a.py,cover => test/farm/annotate/gold_anno_dir/a_a.py,cover rename : test/farm/annotate/gold_anno_dir/b.py,cover => test/farm/annotate/gold_anno_dir/b_b.py,cover --- CHANGES.txt | 5 ++++ coverage/annotate.py | 32 ++++++++++++++-------- coverage/codeunit.py | 21 +++++++++++++- test/farm/annotate/gold_anno_dir/a.py,cover | 5 ---- .../annotate/gold_anno_dir/a___init__.py,cover | 0 test/farm/annotate/gold_anno_dir/a_a.py,cover | 5 ++++ test/farm/annotate/gold_anno_dir/b.py,cover | 2 -- .../annotate/gold_anno_dir/b___init__.py,cover | 0 test/farm/annotate/gold_anno_dir/b_b.py,cover | 2 ++ 9 files changed, 52 insertions(+), 20 deletions(-) delete mode 100644 test/farm/annotate/gold_anno_dir/a.py,cover create mode 100644 test/farm/annotate/gold_anno_dir/a___init__.py,cover create mode 100644 test/farm/annotate/gold_anno_dir/a_a.py,cover delete mode 100644 test/farm/annotate/gold_anno_dir/b.py,cover create mode 100644 test/farm/annotate/gold_anno_dir/b___init__.py,cover create mode 100644 test/farm/annotate/gold_anno_dir/b_b.py,cover diff --git a/CHANGES.txt b/CHANGES.txt index 6727d078..2f3d310c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,11 @@ Continued refactoring. - coverage.annotate_file is no longer available. +- Annotation into a directory (-a -d) behaves differently. The annotated files + are named with their hierarchy flattened so that same-named files from + different directories no longer collide. Also, only files in the current + tree are included. + - Programs executed with -x now behave more as they should, for example, __file__ has the correct value. diff --git a/coverage/annotate.py b/coverage/annotate.py index 14a7b7c7..c0c69800 100644 --- a/coverage/annotate.py +++ b/coverage/annotate.py @@ -7,7 +7,6 @@ from coverage.report import Reporter class AnnotateReporter(Reporter): def __init__(self, coverage, ignore_errors=False): super(AnnotateReporter, self).__init__(coverage, ignore_errors) - self.directory = None blank_re = re.compile(r"\s*(#|$)") @@ -17,27 +16,36 @@ class AnnotateReporter(Reporter): self.find_code_units(morfs, omit_prefixes) self.directory = directory + if self.directory and not os.path.exists(self.directory): + os.makedirs(self.directory) + for cu in self.code_units: try: + if not cu.relative: + continue statements, excluded, missing, _ = self.coverage.analyze(cu) - self.annotate_file(cu.filename, statements, excluded, missing) + self.annotate_file(cu, statements, excluded, missing) except KeyboardInterrupt: raise except: if not self.ignore_errors: raise - def annotate_file(self, filename, statements, excluded, missing): + def annotate_file(self, cu, statements, excluded, missing): + """Annotate a single file. + + `cu` is the CodeUnit for the file to annotate. + + """ + filename = cu.filename source = open(filename, 'r') if self.directory: - if not os.path.exists(self.directory): - os.makedirs(self.directory) - dest_file = os.path.join(self.directory, - os.path.basename(filename) - + ',cover') + dest_file = os.path.join(self.directory, cu.flat_rootname()) + ".py" else: - dest_file = filename + ',cover' + dest_file = filename + dest_file += ",cover" dest = open(dest_file, 'w') + lineno = 0 i = 0 j = 0 @@ -46,11 +54,11 @@ class AnnotateReporter(Reporter): line = source.readline() if line == '': break - lineno = lineno + 1 + lineno += 1 while i < len(statements) and statements[i] < lineno: - i = i + 1 + i += 1 while j < len(missing) and missing[j] < lineno: - j = j + 1 + j += 1 if i < len(statements) and statements[i] == lineno: covered = j >= len(missing) or missing[j] > lineno if self.blank_re.match(line): diff --git a/coverage/codeunit.py b/coverage/codeunit.py index 96ed43bb..3c3d30f5 100644 --- a/coverage/codeunit.py +++ b/coverage/codeunit.py @@ -47,8 +47,11 @@ def code_unit_factory(morfs, file_locator, omit_prefixes=None): class CodeUnit: """Code unit: a filename or module. + Instance attributes: + `name` is a human-readable name for this code unit. `filename` is the os path from which we can read the source. + `relative` is a boolean. """ @@ -64,10 +67,26 @@ class CodeUnit: if hasattr(morf, '__name__'): n = morf.__name__ + self.relative = True else: n = os.path.splitext(morf)[0] - n = file_locator.relative_filename(n) + rel = file_locator.relative_filename(n) + self.relative = (rel != n) + n = rel self.name = n def __cmp__(self, other): return cmp(self.name, other.name) + + def flat_rootname(self): + """A base for a flat filename to correspond to this code unit. + + Useful for writing files about the code where you want all the files in + the same directory, but need to differentiate same-named files from + different directories. + + For example, the file a/b/c.py might return 'a_b_c' + + """ + root = os.path.splitdrive(os.path.splitext(self.name)[0])[1] + return root.replace('\\', '_').replace('/', '_') diff --git a/test/farm/annotate/gold_anno_dir/a.py,cover b/test/farm/annotate/gold_anno_dir/a.py,cover deleted file mode 100644 index 0c858f41..00000000 --- a/test/farm/annotate/gold_anno_dir/a.py,cover +++ /dev/null @@ -1,5 +0,0 @@ -> def a(x): -> if x == 1: -> print "x is 1" -! else: -! print "x is not 1" diff --git a/test/farm/annotate/gold_anno_dir/a___init__.py,cover b/test/farm/annotate/gold_anno_dir/a___init__.py,cover new file mode 100644 index 00000000..e69de29b diff --git a/test/farm/annotate/gold_anno_dir/a_a.py,cover b/test/farm/annotate/gold_anno_dir/a_a.py,cover new file mode 100644 index 00000000..0c858f41 --- /dev/null +++ b/test/farm/annotate/gold_anno_dir/a_a.py,cover @@ -0,0 +1,5 @@ +> def a(x): +> if x == 1: +> print "x is 1" +! else: +! print "x is not 1" diff --git a/test/farm/annotate/gold_anno_dir/b.py,cover b/test/farm/annotate/gold_anno_dir/b.py,cover deleted file mode 100644 index 0bd04dac..00000000 --- a/test/farm/annotate/gold_anno_dir/b.py,cover +++ /dev/null @@ -1,2 +0,0 @@ -> def b(x): -> print "x is %s" % x diff --git a/test/farm/annotate/gold_anno_dir/b___init__.py,cover b/test/farm/annotate/gold_anno_dir/b___init__.py,cover new file mode 100644 index 00000000..e69de29b diff --git a/test/farm/annotate/gold_anno_dir/b_b.py,cover b/test/farm/annotate/gold_anno_dir/b_b.py,cover new file mode 100644 index 00000000..0bd04dac --- /dev/null +++ b/test/farm/annotate/gold_anno_dir/b_b.py,cover @@ -0,0 +1,2 @@ +> def b(x): +> print "x is %s" % x -- cgit v1.2.1