summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-10-02 20:58:19 -0400
committerNed Batchelder <ned@nedbatchelder.com>2018-10-04 08:15:42 -0400
commit4a58cf9993a4c9e2cc1ee70f659cf4d53b7e3bb2 (patch)
tree6e4463da419acbfc91d658f2b72e31a5f31876b5
parent6041686245bd777bb47f9752f1ef67f693664c0f (diff)
downloadpython-coveragepy-git-4a58cf9993a4c9e2cc1ee70f659cf4d53b7e3bb2.tar.gz
In 3.7, namespace modules can have: mod.__file__ is None
Backport of c9f4f661ccb7decb55055d80a1e9a1cbb825b27f
-rw-r--r--coverage/control.py23
-rw-r--r--coverage/python.py2
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.