853 self._warn("No data was collected.", slug="no-data-collected") |
853 self._warn("No data was collected.", slug="no-data-collected") |
854 |
854 |
855 # Find files that were never executed at all. |
855 # Find files that were never executed at all. |
856 for pkg in self.source_pkgs: |
856 for pkg in self.source_pkgs: |
857 if (not pkg in sys.modules or |
857 if (not pkg in sys.modules or |
858 not hasattr(sys.modules[pkg], '__file__') or |
858 not module_has_file(sys.modules[pkg])): |
859 not os.path.exists(sys.modules[pkg].__file__)): |
|
860 continue |
859 continue |
861 pkg_file = source_for_file(sys.modules[pkg].__file__) |
860 pkg_file = source_for_file(sys.modules[pkg].__file__) |
862 self._find_unexecuted_files(self._canonical_path(pkg_file)) |
861 self._find_unexecuted_files(self._canonical_path(pkg_file)) |
863 |
862 |
864 for src in self.source: |
863 for src in self.source: |
876 mod = sys.modules.get(pkg) |
875 mod = sys.modules.get(pkg) |
877 if mod is None: |
876 if mod is None: |
878 self._warn("Module %s was never imported." % pkg, slug="module-not-imported") |
877 self._warn("Module %s was never imported." % pkg, slug="module-not-imported") |
879 return |
878 return |
880 |
879 |
881 is_namespace = hasattr(mod, '__path__') and not hasattr(mod, '__file__') |
880 if module_is_namespace(mod): |
882 has_file = hasattr(mod, '__file__') and os.path.exists(mod.__file__) |
|
883 |
|
884 if is_namespace: |
|
885 # A namespace package. It's OK for this not to have been traced, |
881 # A namespace package. It's OK for this not to have been traced, |
886 # since there is no code directly in it. |
882 # since there is no code directly in it. |
887 return |
883 return |
888 |
884 |
889 if not has_file: |
885 if not module_has_file(mod): |
890 self._warn("Module %s has no Python source." % pkg, slug="module-not-python") |
886 self._warn("Module %s has no Python source." % pkg, slug="module-not-python") |
891 return |
887 return |
892 |
888 |
893 # The module was in sys.modules, and seems like a module with code, but |
889 # The module was in sys.modules, and seems like a module with code, but |
894 # we never measured it. I guess that means it was imported before |
890 # we never measured it. I guess that means it was imported before |
1202 info.append((matcher_name, matcher_info)) |
1198 info.append((matcher_name, matcher_info)) |
1203 |
1199 |
1204 return info |
1200 return info |
1205 |
1201 |
1206 |
1202 |
|
1203 def module_is_namespace(mod): |
|
1204 """Is the module object `mod` a PEP420 namespace module?""" |
|
1205 return hasattr(mod, '__path__') and getattr(mod, '__file__', None) is None |
|
1206 |
|
1207 |
|
1208 def module_has_file(mod): |
|
1209 """Does the module object `mod` have an existing __file__ ?""" |
|
1210 mod__file__ = getattr(mod, '__file__', None) |
|
1211 if mod__file__ is None: |
|
1212 return False |
|
1213 return os.path.exists(mod__file__) |
|
1214 |
|
1215 |
1207 # FileDisposition "methods": FileDisposition is a pure value object, so it can |
1216 # FileDisposition "methods": FileDisposition is a pure value object, so it can |
1208 # be implemented in either C or Python. Acting on them is done with these |
1217 # be implemented in either C or Python. Acting on them is done with these |
1209 # functions. |
1218 # functions. |
1210 |
1219 |
1211 def _disposition_init(cls, original_filename): |
1220 def _disposition_init(cls, original_filename): |