-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Closed
Description
Consider the following test:
import pytest
class SpecialException(Exception):
pass
class Base:
def __getattr__(self, name):
raise AttributeError(name)
class Propertious(Base):
@property
def foo_special(self):
raise SpecialException
def test_attr():
p = Propertious()
with pytest.raises(SpecialException):
p.foo_special
The test passes on Python 3.11, but on Python 3.12.0a7, fails thus:
$ py -3.12 -m pip-run pytest -- -m pytest attr.py
============================================================= test session starts ==============================================================
platform darwin -- Python 3.12.0a7, pytest-7.3.1, pluggy-1.0.0
rootdir: /Users/jaraco/draft
plugins: anyio-3.6.2
collected 1 item
attr.py F [100%]
=================================================================== FAILURES ===================================================================
__________________________________________________________________ test_attr ___________________________________________________________________
self = <attr.Propertious object at 0x101aa9580>
@property
def foo_special(self):
> raise SpecialException
E attr.SpecialException
attr.py:16: SpecialException
The above exception was the direct cause of the following exception:
def test_attr():
p = Propertious()
with pytest.raises(SpecialException):
> p.foo_special
attr.py:22:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <attr.Propertious object at 0x101aa9580>, name = 'foo_special'
def __getattr__(self, name):
> raise AttributeError(name)
E SystemError: <class 'AttributeError'> returned a result with an exception set
attr.py:10: SystemError
=========================================================== short test summary info ============================================================
FAILED attr.py::test_attr - SystemError: <class 'AttributeError'> returned a result with an exception set
============================================================== 1 failed in 0.02s ===============================================================
I discovered the issue when troubleshooting a strange failure of jaraco.abode on Python 3.12. In that real-world example, tests fail when tests check for an expected exception during set_status, during which _control_url is accessed, but instead of being handled solely by the property on the class, somehow the superclass' getattr is evoked:
stream = open(filename)
tests/mock/devices/secure_barrier.py ..
/home/runner/work/jaraco.abode/jaraco.abode/.tox/python/lib/python3.12/site-packages/blib2to3/pgen2/pgen.py:42: EncodingWarning: 'encoding' argument not specified
stream = open(filename)
tests/mock/devices/siren.py ..
/home/runner/work/jaraco.abode/jaraco.abode/.tox/python/lib/python3.12/site-packages/blib2to3/pgen2/pgen.py:42: EncodingWarning: 'encoding' argument not specified
stream = open(filename)
tests/mock/devices/status_display.py ..
/home/runner/work/jaraco.abode/jaraco.abode/.tox/python/lib/python3.12/site-packages/blib2to3/pgen2/pgen.py:42: EncodingWarning: 'encoding' argument not specified
stream = open(filename)
tests/mock/devices/unknown.py ..
/home/runner/work/jaraco.abode/jaraco.abode/.tox/python/lib/python3.12/site-packages/blib2to3/pgen2/pgen.py:42: EncodingWarning: 'encoding' argument not specified
stream = open(filename)
tests/mock/devices/valve.py ..
/home/runner/work/jaraco.abode/jaraco.abode/.tox/python/lib/python3.12/site-packages/blib2to3/pgen2/pgen.py:42: EncodingWarning: 'encoding' argument not specified
stream = open(filename)
tests/mock/devices/water_sensor.py ..
=================================== FAILURES ===================================
________________________ TestDevice.test_no_control_url ________________________
self = <jaraco.abode.devices.binary_sensor.Connectivity object at 0x7f4f1a304950>
name = '_control_url'
def __getattr__(self, name):
try:
> return self._state[name]
E KeyError: '_control_url'
jaraco/abode/state.py:19: KeyError
The above exception was the direct cause of the following exception:
self = <tests.test_device.TestDevice object at 0x7f4f218a35c0>
m = <requests_mock.mocker.Mocker object at 0x7f4f1b7d3a40>
def test_no_control_url(self, m):
"""Check that devices return false without control url's."""
# Set up URLs
m.post(urls.LOGIN, json=LOGIN.post_response_ok())
m.get(urls.OAUTH_TOKEN, json=OAUTH_CLAIMS.get_response_ok())
m.post(urls.LOGOUT, json=LOGOUT.post_response_ok())
m.get(urls.PANEL, json=PANEL.get_response_ok())
m.get(urls.DEVICES, json=GLASS.device(status=STATUS.ONLINE))
# Logout to reset everything
self.client.logout()
# Get device
device = self.client.get_device(GLASS.DEVICE_ID)
assert device is not None
with pytest.raises(jaraco.abode.Exception):
> device.set_status(1)
tests/test_device.py:254:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
jaraco/abode/devices/base.py:34: in set_status
path=self._control_url,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <jaraco.abode.devices.binary_sensor.Connectivity object at 0x7f4f1a304950>
name = '_control_url'
def __getattr__(self, name):
try:
return self._state[name]
except KeyError as exc:
> raise AttributeError(name) from exc
E AttributeError: _control_url
jaraco/abode/state.py:21: AttributeError
The failure mode in the repro isn't precisely the same, but it's close, and I suspect it will trace to the same cause.
Metadata
Metadata
Assignees
Labels
No labels