summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
Diffstat (limited to 'coverage')
-rw-r--r--coverage/cmdline.py44
-rw-r--r--coverage/collector.py4
-rw-r--r--coverage/control.py24
-rw-r--r--coverage/data.py13
4 files changed, 78 insertions, 7 deletions
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index accade5..d421aab 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -199,7 +199,7 @@ CMDS = {
"missed with !."
),
- 'help': CmdOptionParser("help",
+ 'help': CmdOptionParser("help", [Opts.help],
usage = "[command]",
description = "Describe how to use coverage.py"
),
@@ -217,14 +217,22 @@ CMDS = {
"executed, excluded, and missed lines."
),
- 'combine': CmdOptionParser("combine",
+ 'combine': CmdOptionParser("combine", [Opts.help],
usage = " ",
description = "Combine data from multiple coverage files collected "
"with 'run -p'. The combined results are stored into a single "
"file representing the union of the coverage."
),
- 'erase': CmdOptionParser("erase",
+ 'debug': CmdOptionParser("debug", [Opts.help],
+ usage = "<topic>",
+ description = "Display information the internals of coverage.py, "
+ "for diagnosing problems. "
+ "Topics are 'data' to show a summary of the data collected in "
+ ".coverage, or 'sys' to show installation information."
+ ),
+
+ 'erase': CmdOptionParser("erase", [Opts.help],
usage = " ",
description = "Erase previously collected coverage data."
),
@@ -371,6 +379,7 @@ class CoverageScript:
'execute' in options.actions or
'annotate' in options.actions or
'html' in options.actions or
+ 'debug' in options.actions or
'report' in options.actions or
'xml' in options.actions
)
@@ -389,6 +398,35 @@ class CoverageScript:
timid = options.timid,
)
+ if 'debug' in options.actions:
+ if not args:
+ self.help_fn("What information would you like: data, sys?")
+ return ERR
+ for info in args:
+ if info == 'sys':
+ print("-- sys ----------------------------------------")
+ for label, info in self.coverage.sysinfo():
+ if isinstance(info, list):
+ print("%15s:" % label)
+ for e in info:
+ print("%15s %s" % ("", e))
+ else:
+ print("%15s: %s" % (label, info))
+ elif info == 'data':
+ print("-- data ---------------------------------------")
+ self.coverage.load()
+ summary = self.coverage.data.summary(fullpath=True)
+ if summary:
+ filenames = sorted(summary.keys())
+ for f in filenames:
+ print("%s: %d lines" % (f, summary[f]))
+ else:
+ print("No data collected")
+ else:
+ self.help_fn("Don't know what you mean by %r" % info)
+ return ERR
+ return OK
+
if 'erase' in options.actions or options.erase_first:
self.coverage.erase()
else:
diff --git a/coverage/collector.py b/coverage/collector.py
index a121193..3b56d24 100644
--- a/coverage/collector.py
+++ b/coverage/collector.py
@@ -118,6 +118,10 @@ class Collector:
# trace function.
self._trace_class = Tracer or PyTracer
+ def tracer_name(self):
+ """Return the class name of the tracer we're using."""
+ return self._trace_class.__name__
+
def reset(self):
"""Clear collected data, and prepare to collect more."""
# A dictionary with an entry for (Python source file name, line number
diff --git a/coverage/control.py b/coverage/control.py
index 4fdec93..d51dd29 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -332,3 +332,27 @@ class coverage:
outfile = open(outfile, "w")
reporter = XmlReporter(self, ignore_errors)
reporter.report(morfs, omit_prefixes=omit_prefixes, outfile=outfile)
+
+ def sysinfo(self):
+ """Return a list of key,value pairs showing internal information."""
+
+ import coverage as covmod
+ import platform, re, sys
+
+ info = [
+ ('version', covmod.__version__),
+ ('coverage', covmod.__file__),
+ ('cover_prefix', self.cover_prefix),
+ ('pylib_prefix', self.pylib_prefix),
+ ('tracer', self.collector.tracer_name()),
+ ('data_file', self.data.filename),
+ ('python', sys.version),
+ ('platform', platform.platform()),
+ ('cwd', os.getcwd()),
+ ('path', sys.path),
+ ('environment', [
+ ("%s = %s" % (k, v)) for k, v in os.environ.items()
+ if re.search("^COV|^PY", k)
+ ]),
+ ]
+ return info
diff --git a/coverage/data.py b/coverage/data.py
index 4d368f5..5497965 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -164,14 +164,19 @@ class CoverageData:
"""
return self.lines.get(filename) or {}
- def summary(self):
+ def summary(self, fullpath=False):
"""Return a dict summarizing the coverage data.
- Keys are the basename of the filenames, and values are the number of
- executed lines. This is useful in the unit tests.
+ Keys are based on the filenames, and values are the number of executed
+ lines. If `fullpath` is true, then the keys are the full pathnames of
+ the files, otherwise they are the basenames of the files.
"""
summ = {}
+ if fullpath:
+ filename_fn = lambda f: f
+ else:
+ filename_fn = os.path.basename
for filename, lines in self.lines.items():
- summ[os.path.basename(filename)] = len(lines)
+ summ[filename_fn(filename)] = len(lines)
return summ