]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-84530: fix namespace package support in modulefinder (#29196)
authorFilipe Laíns <lains@riseup.net>
Tue, 9 Dec 2025 15:50:50 +0000 (15:50 +0000)
committerGitHub <noreply@github.com>
Tue, 9 Dec 2025 15:50:50 +0000 (15:50 +0000)
* bpo-40350: fix namespace package support in modulefinder

Signed-off-by: Filipe Laíns <lains@riseup.net>
* consider that namespace package specs might have the loader set

Signed-off-by: Filipe Laíns <lains@riseup.net>
* Revert "consider that namespace package specs might have the loader set"

This reverts commit 23fb4e0de38466217e932115143db1a9584e35da.

Signed-off-by: Filipe Laíns <lains@riseup.net>
* Fix load_module and load_package to handle namespace packages

Signed-off-by: Filipe Laíns <lains@riseup.net>
* Drop _NAMESPACE constant

Signed-off-by: Filipe Laíns <lains@riseup.net>
* Drop importlib changes

Signed-off-by: Filipe Laíns <lains@riseup.net>
* Update NamespacePath check

Signed-off-by: Filipe Laíns <lains@riseup.net>
* Mixed some

Signed-off-by: Filipe Laíns <lains@riseup.net>
---------

Signed-off-by: Filipe Laíns <lains@riseup.net>
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 7fb19a5c5d1805f1981d44985b44da3c3d8a36fb..b8dccc2dd33afe79bec92e1d929f86996b8f2614 100644 (file)
@@ -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]
 
index b64e684f80599fe7dcee2b3a21467406fbae21d5..703bfbf94d7bff4386d7d49754fcb607558560d8 100644 (file)
@@ -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 (file)
index 0000000..a5236cc
--- /dev/null
@@ -0,0 +1 @@
+Fix support for namespace packages in :mod:`modulefinder`.