gh-84530: fix namespace package support in modulefinder (#29196)

* 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>
This commit is contained in:
Filipe Laíns 2025-12-09 15:50:50 +00:00 committed by GitHub
parent 49207a5226
commit 1b460fcddc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 1 deletions

View 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]

View 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)

View File

@ -0,0 +1 @@
Fix support for namespace packages in :mod:`modulefinder`.