Repository navigation
ModuleType.__repr__ can fail on py312+ #112414
Description
Bug report
Bug description:
Calling repr() on a ModuleType instance can fail with AttributeError on py312+, due to changes made in #98870. This is because the implementation of importlib._bootstrap._module_repr_from_spec assumes that all loaders will have a _path attribute. But if the module had a custom loader, that won't necessarily hold true: _path is an undocumented, internal, private attribute that CPython's import loaders have, but custom third-party loaders won't necessarily have.
An easy way to see this is the following (in a py312 venv with setuptools installed):
Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct 2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from setuptools._vendor import packaging
>>> repr(packaging)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<frozen importlib._bootstrap>", line 545, in _module_repr
File "<frozen importlib._bootstrap>", line 830, in _module_repr_from_spec
AttributeError: 'VendorImporter' object has no attribute '_path'setuptools implements the custom VendorImporter loader here: https://github.com/pypa/setuptools/blob/b1bf87be7869df40872e947e27296ef87e3125ae/setuptools/extern/__init__.py#L5-L70. Instances of VendorImporter do not have a _path attribute.
This kind of thing trips up external tools such as mypy's stubtest.py script, which calls repr() on arbitrary instances of types.ModuleType on certain code paths and (reasonably) expects that to always succeed: https://github.com/python/mypy/blob/1200d1d956e589a0a33c86ef8a7cb3f5a9b64f1f/mypy/stubtest.py#L224
Cc. @FFY00 and @jaraco, as participants in #98139 (the issue #98870 was linked to)
CPython versions tested on:
3.12
Operating systems tested on:
Windows
Linked PRs
- gh-112414: Fix
AttributeErrorwhen callingrepr()on a namespace package imported with a custom loader #112425 - gh-112414: Fix repr for custom loader #112436
- [3.12] gh-112414: Fix
AttributeErrorwhen callingrepr()on a namespace package imported with a custom loader (GH-112425) #112440 - gh-112414: Add additional unit tests for calling
repr()on a namespace package #112475 - [3.12] gh-112414: Add additional unit tests for calling
repr()on a namespace package (GH-112475) #112480
Activity
AlexWaygood commentedon Nov 25, 2023
Maybe something like this would be a reasonable fix?
TeamSpen210 commentedon Nov 25, 2023
Maybe it'd be better to do an
isinstance()check. Then someone defining_pathin their own loader wouldn't have the repr mysteriously change. Seems like an entirely reasonable attribute to have, and if it was a string you'd get rather silly results.AlexWaygood commentedon Nov 26, 2023
Makes sense. That implies a diff like this:
pythongh-112414: Fix `AttributeError` when calling `repr()` on a modu…
AlexWaygood commentedon Nov 26, 2023
Another easy way to observe this bug: apply this diff to
main:And then run
python -m test test_importlib.import_.test___loader__ -v:Test output
I've filed #112425 to fix it.
pythongh-112414: Fix repr for custom loader
gh-112414: Fix `AttributeError` when calling `repr()` on a namespace …
pythongh-112414: Fix `AttributeError` when calling `repr()` on a name…
[3.12] gh-112414: Fix `AttributeError` when calling `repr()` on a nam…
pythongh-112414: Add additional unit tests for calling `repr()` on a …
gh-112414: Add additional unit tests for calling `repr()` on a namesp…
pythongh-112414: Add additional unit tests for calling `repr()` on a …
[3.12] gh-112414: Add additional unit tests for calling `repr()` on a…
pythongh-112414: Fix `AttributeError` when calling `repr()` on a name…
pythongh-112414: Add additional unit tests for calling `repr()` on a …
pythongh-112414: Fix `AttributeError` when calling `repr()` on a name…
pythongh-112414: Add additional unit tests for calling `repr()` on a …