Skip to content

Commit f9861e6

Browse files
[3.12] gh-112414: Fix AttributeError when calling repr() on a namespace package imported with a custom loader (GH-112425) (#112440)
gh-112414: Fix `AttributeError` when calling `repr()` on a namespace package imported with a custom loader (GH-112425) (cherry picked from commit 0622839) Co-authored-by: Alex Waygood <[email protected]>
1 parent 42df736 commit f9861e6

File tree

4 files changed

+16
-3
lines changed

4 files changed

+16
-3
lines changed

Lib/importlib/_bootstrap.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,10 +824,16 @@ def _module_repr_from_spec(spec):
824824
"""Return the repr to use for the module."""
825825
name = '?' if spec.name is None else spec.name
826826
if spec.origin is None:
827-
if spec.loader is None:
827+
loader = spec.loader
828+
if loader is None:
828829
return f'<module {name!r}>'
830+
elif (
831+
_bootstrap_external is not None
832+
and isinstance(loader, _bootstrap_external.NamespaceLoader)
833+
):
834+
return f'<module {name!r} (namespace) from {list(loader._path)}>'
829835
else:
830-
return f'<module {name!r} (namespace) from {list(spec.loader._path)}>'
836+
return f'<module {name!r} ({loader!r})>'
831837
else:
832838
if spec.has_location:
833839
return f'<module {name!r} from {spec.origin!r}>'

Lib/test/test_importlib/import_/test___loader__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ def test___loader__(self):
2626
with util.uncache('blah'), util.import_state(meta_path=[loader]):
2727
module = self.__import__('blah')
2828
self.assertEqual(loader, module.__loader__)
29+
expected_repr_pattern = (
30+
r"<module 'blah' \(<test\.test_importlib\..*SpecLoaderMock object at .+>\)>"
31+
)
32+
self.assertRegex(repr(module), expected_repr_pattern)
2933

3034

3135
(Frozen_SpecTests,

Lib/test/test_importlib/test_namespace_pkgs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def test_cant_import_other(self):
8181

8282
def test_simple_repr(self):
8383
import foo.one
84-
assert repr(foo).startswith("<module 'foo' (namespace) from [")
84+
self.assertTrue(repr(foo).startswith("<module 'foo' (namespace) from ["))
8585

8686

8787
class DynamicPathNamespacePackage(NamespacePackageTest):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix regression in Python 3.12 where calling :func:`repr` on a module that
2+
had been imported using a custom :term:`loader` could fail with
3+
:exc:`AttributeError`. Patch by Alex Waygood.

0 commit comments

Comments
 (0)