Description
Bug report
I noticed recently that Setuptools CI started failing for Python 3.12.0a7 with a SystemError
that is difficult to understand:
SystemError: <built-in method startswith of str object at 0x7fe399991298> returned a result with an exception set
At a first glance this error does not make much sense because str.startswith
is a built-in method in a built-in data structure. I am struggling to see how it can have an exception set attached to the result.
I managed to create the following simplified reproducer:
docker run --rm -it python:3.12.0a7-bullseye
Python 3.12.0a7 (main, Apr 12 2023, 14:13:09) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class Distribution:
... @property
... def version(self):
... try:
... return self._version
... except AttributeError as e:
... # ... complex code omitted for the sake of simplification ...
... raise ValueError("Missing Version")
... def __getattr__(self, attr):
... if attr.startswith("_"):
... raise AttributeError(attr)
... # ... complex code omitted for the sake of simplification ...
... return 42
...
>>> dist = Distribution()
>>> dist.version
Traceback (most recent call last):
File "<stdin>", line 5, in version
File "<stdin>", line 11, in __getattr__
AttributeError: _version. Did you mean: 'version'?
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 8, in version
ValueError: Missing Version
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 10, in __getattr__
SystemError: <method 'startswith' of 'str' objects> returned a result with an exception set
>>>
The error seems to be related to the combination of the following factors:
- A
property
is being used1 - The property getter access an undefined attribute and triggers
__getattr__
__getattr__
raises anAttributeError
- The property getter is supposed to catch the
AttributeError
exception and raise a different exeception.
My expectation is that the SystemError
never gets triggered with the confusing message. Instead the example should end up with a ValueError
.
Please note that the example is very simplified. For the realistic implementation please consider pkg_resources.Distribution
.
Your environment
- CPython versions tested on: 3.12.0a7
- Operating system and architecture:
Reproducer tested on both Ubuntu 20.04.6 LTS machine andpython:3.12.0a7-bullseye
container
Problem also identified in GitHub Actions runners: ubuntu-latest
, macos-latest
, windows-latest
(see https://github.com/pypa/setuptools/actions/runs/4710601389?pr=3893) for Python 3.12-dev
.
Footnotes
-
If we replace the property with a regular method, the example works as expected. ↩