diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index 7fb19a5c5d1..b8dccc2dd33 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -66,7 +66,12 @@ def _find_module(name, path=None): file_path = spec.origin - if spec.loader.is_package(name): + # On namespace packages, spec.loader might be None, but + # spec.submodule_search_locations should always be set — check it instead. + if isinstance(spec.submodule_search_locations, importlib.machinery.NamespacePath): + return None, spec.submodule_search_locations, ("", "", _PKG_DIRECTORY) + + if spec.loader.is_package(name): # non-namespace package return None, os.path.dirname(file_path), ("", "", _PKG_DIRECTORY) if isinstance(spec.loader, importlib.machinery.SourceFileLoader): @@ -453,6 +458,11 @@ class ModuleFinder: if newname: fqname = newname m = self.add_module(fqname) + + if isinstance(pathname, importlib.machinery.NamespacePath): + m.__path__ = pathname + return m + m.__file__ = pathname m.__path__ = [pathname] diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py index b64e684f805..703bfbf94d7 100644 --- a/Lib/test/test_modulefinder.py +++ b/Lib/test/test_modulefinder.py @@ -76,6 +76,18 @@ a/c.py from sys import version_info """] +namespace_package_test = [ + "module", + ["a", "module"], + ["a.c", "blahblah"], [], + """\ +module.py + import a + import a.c + import blahblah +a/b.py +"""] + absolute_import_test = [ "a.module", ["a", "a.module", @@ -353,6 +365,9 @@ class ModuleFinderTest(unittest.TestCase): def test_package(self): self._do_test(package_test) + def test_namespace_package(self): + self._do_test(namespace_package_test) + def test_maybe(self): self._do_test(maybe_test) diff --git a/Misc/NEWS.d/next/Library/2021-10-23-22-12-13.bpo-40350.t0dQMY.rst b/Misc/NEWS.d/next/Library/2021-10-23-22-12-13.bpo-40350.t0dQMY.rst new file mode 100644 index 00000000000..a5236cc57a0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-10-23-22-12-13.bpo-40350.t0dQMY.rst @@ -0,0 +1 @@ +Fix support for namespace packages in :mod:`modulefinder`.