Description
Hi,
Version: 3.12.0a7
OS: Windows
While testing pytest in 3.12 on Windows, we noticed an odd behavior that we believe might be a bug/regression.
Consider this minimal example:
class Stat:
@property
def owner(self):
print("--> accessing owner")
raise NotImplementedError("owner not implemented")
def __getattr__(self, item):
return getattr(1, "foobar")
s = Stat()
s.owner
(Using getattr(1, ...)
there just to have an object in-place; in the real code 1
is actually another object, but the outcome is the same).
Running this in Python 3.11.2
(and previous versions), we get this output:
λ py -3.11 --version
Python 3.11.2
λ py -3.11 .tmp\reproducer.py
--> accessing owner
Traceback (most recent call last):
File "e:\projects\pytest\.tmp\reproducer.py", line 12, in <module>
s.owner
File "e:\projects\pytest\.tmp\reproducer.py", line 5, in owner
raise NotImplementedError("owner not implemented")
NotImplementedError: owner not implemented
NotImplementedError
is raised from the property access, and __getattr__
is never called.
In Python 3.12.0a7
however we get:
λ py -3.12 --version
Python 3.12.0a7
λ py -3.12 .tmp\reproducer.py
--> accessing owner
Traceback (most recent call last):
File "e:\projects\pytest\.tmp\reproducer.py", line 12, in <module>
s.owner
File "e:\projects\pytest\.tmp\reproducer.py", line 8, in __getattr__
return getattr(1, "foobar")
^^^^^^^^^^^^^^^^^^^^
AttributeError: 'int' object has no attribute 'foobar'
The property is still being accessed (as shown by the print
call), but NotImplementedError
is being swallowed/ignored, and __getattr__
seems to be getting called as a fallback.
Changing the example slightly:
class Stat:
@property
def owner(self):
print("--> accessing owner")
raise NotImplementedError("owner not implemented")
def __getattr__(self, item):
raise AttributeError("foobar")
s = Stat()
s.owner
In Python 3.11
the behavior stays the same as before, however in Python 3.12
we now get:
λ py -3.12 .tmp\reproducer.py
--> accessing owner
Traceback (most recent call last):
File "e:\projects\pytest\.tmp\reproducer.py", line 5, in owner
raise NotImplementedError("owner not implemented")
NotImplementedError: owner not implemented
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "e:\projects\pytest\.tmp\reproducer.py", line 12, in <module>
s.owner
File "e:\projects\pytest\.tmp\reproducer.py", line 8, in __getattr__
raise AttributeError("foobar")
^^^^^^^^^^^^^^^^^^^^^^^^
SystemError: <class 'AttributeError'> returned a result with an exception set
Please let us know if you need more information.