diff options
| author | Ned Batchelder <ned@nedbatchelder.com> | 2018-10-02 20:58:19 -0400 |
|---|---|---|
| committer | Ned Batchelder <ned@nedbatchelder.com> | 2018-10-04 08:15:42 -0400 |
| commit | 4a58cf9993a4c9e2cc1ee70f659cf4d53b7e3bb2 (patch) | |
| tree | 6e4463da419acbfc91d658f2b72e31a5f31876b5 | |
| parent | 6041686245bd777bb47f9752f1ef67f693664c0f (diff) | |
| download | python-coveragepy-git-4a58cf9993a4c9e2cc1ee70f659cf4d53b7e3bb2.tar.gz | |
In 3.7, namespace modules can have: mod.__file__ is None
Backport of c9f4f661ccb7decb55055d80a1e9a1cbb825b27f
| -rw-r--r-- | coverage/control.py | 23 | ||||
| -rw-r--r-- | coverage/python.py | 2 |
2 files changed, 17 insertions, 8 deletions
diff --git a/coverage/control.py b/coverage/control.py index b82c8047..cf65d658 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -855,8 +855,7 @@ class Coverage(object): # Find files that were never executed at all. 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__)): + not module_has_file(sys.modules[pkg])): continue pkg_file = source_for_file(sys.modules[pkg].__file__) self._find_unexecuted_files(self._canonical_path(pkg_file)) @@ -878,15 +877,12 @@ class Coverage(object): self._warn("Module %s was never imported." % pkg, slug="module-not-imported") return - is_namespace = hasattr(mod, '__path__') and not hasattr(mod, '__file__') - has_file = hasattr(mod, '__file__') and os.path.exists(mod.__file__) - - if is_namespace: + if module_is_namespace(mod): # A namespace package. It's OK for this not to have been traced, # since there is no code directly in it. return - if not has_file: + if not module_has_file(mod): self._warn("Module %s has no Python source." % pkg, slug="module-not-python") return @@ -1204,6 +1200,19 @@ class Coverage(object): return info +def module_is_namespace(mod): + """Is the module object `mod` a PEP420 namespace module?""" + return hasattr(mod, '__path__') and getattr(mod, '__file__', None) is None + + +def module_has_file(mod): + """Does the module object `mod` have an existing __file__ ?""" + mod__file__ = getattr(mod, '__file__', None) + if mod__file__ is None: + return False + return os.path.exists(mod__file__) + + # FileDisposition "methods": FileDisposition is a pure value object, so it can # be implemented in either C or Python. Acting on them is done with these # functions. diff --git a/coverage/python.py b/coverage/python.py index 372347f5..2b16acab 100644 --- a/coverage/python.py +++ b/coverage/python.py @@ -135,7 +135,7 @@ class PythonFileReporter(FileReporter): def __init__(self, morf, coverage=None): self.coverage = coverage - if hasattr(morf, '__file__'): + if hasattr(morf, '__file__') and morf.__file__: filename = morf.__file__ elif isinstance(morf, types.ModuleType): # A module should have had .__file__, otherwise we can't use it. |
