]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40350: fix namespace package support in modulefinder
authorFilipe Laíns <lains@riseup.net>
Sat, 23 Oct 2021 20:42:28 +0000 (21:42 +0100)
committerFilipe Laíns <lains@riseup.net>
Sat, 23 Oct 2021 21:12:17 +0000 (22:12 +0100)
Signed-off-by: Filipe Laíns <lains@riseup.net>
Lib/importlib/_bootstrap_external.py
Lib/modulefinder.py
Lib/test/test_modulefinder.py
Misc/NEWS.d/next/Library/2021-10-23-22-12-13.bpo-40350.t0dQMY.rst [new file with mode: 0644]

index ef4f23a4b499f135b99ff4f82cf9423b04cb09fd..5c910635a705f3174ce040490589d81b3a0ac0a9 100644 (file)
@@ -1455,6 +1455,7 @@ class PathFinder:
                 # can create the namespace package.
                 spec.origin = None
                 spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec)
+                spec.loader = NamespaceLoader(fullname, namespace_path, cls._get_spec)
                 return spec
             else:
                 return None
index a0a020f9eeb9b415b7ca39566c779e13b0051928..908e40905a5063c8143cd6067bc174df54ed4a0a 100644 (file)
@@ -17,6 +17,7 @@ _C_EXTENSION = 3
 _PKG_DIRECTORY = 5
 _C_BUILTIN = 6
 _PY_FROZEN = 7
+_NAMESPACE = 8
 
 # Modulefinder does a good job at simulating Python's, but it can not
 # handle __path__ modifications packages make at runtime.  Therefore there
@@ -66,7 +67,10 @@ def _find_module(name, path=None):
 
     file_path = spec.origin
 
-    if spec.loader.is_package(name):
+    if isinstance(spec.loader, importlib.machinery.NamespaceLoader):
+        return None, spec.submodule_search_locations, ("", "", _NAMESPACE)
+
+    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):
index ca1058b8d4087cf1e1de410a47808dcc7901dd1f..21a893af064b57a463b08e2036a3b2f9831c1b65 100644 (file)
@@ -79,6 +79,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",
@@ -352,6 +364,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 (file)
index 0000000..a5236cc
--- /dev/null
@@ -0,0 +1 @@
+Fix support for namespace packages in :mod:`modulefinder`.