summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2009-04-19 08:16:50 -0400
committerNed Batchelder <ned@nedbatchelder.com>2009-04-19 08:16:50 -0400
commit4d45dc8c234eee1b4bd6da9eac409d588eba9455 (patch)
tree387e5f55061359707d33b39681ad555d5e9ef0b5
parent89fbd04106100a4cc821cc41bac2e9301bda33ec (diff)
downloadpython-coveragepy-git-4d45dc8c234eee1b4bd6da9eac409d588eba9455.tar.gz
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
-rw-r--r--CHANGES.txt5
-rw-r--r--coverage/annotate.py32
-rw-r--r--coverage/codeunit.py21
-rw-r--r--test/farm/annotate/gold_anno_dir/a___init__.py,cover0
-rw-r--r--test/farm/annotate/gold_anno_dir/a_a.py,cover (renamed from test/farm/annotate/gold_anno_dir/a.py,cover)0
-rw-r--r--test/farm/annotate/gold_anno_dir/b___init__.py,cover0
-rw-r--r--test/farm/annotate/gold_anno_dir/b_b.py,cover (renamed from test/farm/annotate/gold_anno_dir/b.py,cover)0
7 files changed, 45 insertions, 13 deletions
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___init__.py,cover b/test/farm/annotate/gold_anno_dir/a___init__.py,cover
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/farm/annotate/gold_anno_dir/a___init__.py,cover
diff --git a/test/farm/annotate/gold_anno_dir/a.py,cover b/test/farm/annotate/gold_anno_dir/a_a.py,cover
index 0c858f41..0c858f41 100644
--- a/test/farm/annotate/gold_anno_dir/a.py,cover
+++ b/test/farm/annotate/gold_anno_dir/a_a.py,cover
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
--- /dev/null
+++ b/test/farm/annotate/gold_anno_dir/b___init__.py,cover
diff --git a/test/farm/annotate/gold_anno_dir/b.py,cover b/test/farm/annotate/gold_anno_dir/b_b.py,cover
index 0bd04dac..0bd04dac 100644
--- a/test/farm/annotate/gold_anno_dir/b.py,cover
+++ b/test/farm/annotate/gold_anno_dir/b_b.py,cover