summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorloic@dachary.org <loic@dachary.org>2017-01-06 15:42:56 +0100
committerloic@dachary.org <loic@dachary.org>2017-01-06 15:42:56 +0100
commitbcc6d71c52207fa4808f14234231af7d399b975f (patch)
tree6fd982d58f1434c6f438934afba4fae368fb8f67
parent6d5ebb6b653b9551c78383e23309860f1f650ba3 (diff)
downloadpython-coveragepy-git-bcc6d71c52207fa4808f14234231af7d399b975f.tar.gz
make --source module do the same as --source directory #426
The --source argument can either be a module or a directory. The user expects that it behaves the same in both cases. Make sure the module is recursively explored so that files that are not run show in the coverage report. close #426 --HG-- branch : issue-426
-rw-r--r--coverage/control.py24
-rw-r--r--tests/test_process.py9
2 files changed, 28 insertions, 5 deletions
diff --git a/coverage/control.py b/coverage/control.py
index 992ca585..d968b182 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -159,6 +159,7 @@ class Coverage(object):
# Other instance attributes, set later.
self.omit = self.include = self.source = None
+ self.source_pkgs_unmatched = None
self.source_pkgs = None
self.data = self.data_files = self.collector = None
self.plugins = None
@@ -223,6 +224,7 @@ class Coverage(object):
self.source.append(files.canonical_filename(src))
else:
self.source_pkgs.append(src)
+ self.source_pkgs_unmatched = self.source_pkgs[:]
self.omit = prep_patterns(self.config.omit)
self.include = prep_patterns(self.config.include)
@@ -549,8 +551,8 @@ class Coverage(object):
# stdlib and coverage.py directories.
if self.source_match:
if self.source_pkgs_match.match(modulename):
- if modulename in self.source_pkgs:
- self.source_pkgs.remove(modulename)
+ if modulename in self.source_pkgs_unmatched:
+ self.source_pkgs_unmatched.remove(modulename)
return None # There's no reason to skip this file.
if not self.source_match.match(filename):
@@ -815,10 +817,10 @@ class Coverage(object):
self.collector.save_data(self.data)
- # If there are still entries in the source_pkgs list, then we never
+ # If there are still entries in the source_pkgs_unmatched list, then we never
# encountered those packages.
if self._warn_unimported_source:
- for pkg in self.source_pkgs:
+ for pkg in self.source_pkgs_unmatched:
if pkg not in sys.modules:
self._warn("Module %s was never imported." % pkg)
elif not (
@@ -833,8 +835,20 @@ class Coverage(object):
if not self.data and self._warn_no_data:
self._warn("No data was collected.")
+ src_directories = self.source[:]
+
+ for pkg in self.source_pkgs:
+ if (not pkg in sys.modules or
+ not hasattr(sys.modules[pkg], '__file__') or
+ not os.path.exists(sys.modules[pkg].__file__)):
+ continue
+ pkg_file = sys.modules[pkg].__file__
+ if not pkg_file.endswith(('__init__.py', '__init__.pyc', '__init__.pyo')):
+ continue
+ src_directories.append(self._canonical_dir(sys.modules[pkg]))
+
# Find files that were never executed at all.
- for src in self.source:
+ for src in src_directories:
for py_file in find_python_files(src):
py_file = files.canonical_filename(py_file)
diff --git a/tests/test_process.py b/tests/test_process.py
index be9bdb76..a9e8d4c6 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -505,6 +505,15 @@ class ProcessTest(CoverageTest):
self.assertEqual(st, 0)
self.assertEqual(self.line_count(out), 6, out)
+ def test_coverage_doubledashsource_module(self):
+ """ pkg1.sub is not a directory, verify the files it contains
+ and that were not run show in the report """
+ out = self.run_command("coverage run --source pkg1.sub -m pkg1.sub arg")
+ self.assertIn('pkg1.sub.__main__: passed', out)
+ st, out = self.run_command_status("coverage report")
+ self.assertEqual(st, 0)
+ self.assertIn('runmod3.py', out)
+
def test_coverage_run_script_imports_doubledashsource(self):
# This file imports try_execfile, which compiles it to .pyc, so the
# first run will have __file__ == "try_execfile.py" and the second will