Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Python 3.12] SystemError and other undesirable behavior #10928

Closed
jaraco opened this issue Apr 21, 2023 · 3 comments
Closed

[Python 3.12] SystemError and other undesirable behavior #10928

jaraco opened this issue Apr 21, 2023 · 3 comments

Comments

@jaraco
Copy link
Contributor

jaraco commented Apr 21, 2023

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.

@RonnyPfannschmidt
Copy link
Member

It's a know cpython bug, is fixed upstream but not yet released

@jaraco
Copy link
Contributor Author

jaraco commented Apr 26, 2023

Glad to hear. I tried to find the CPython bug, but couldn't. If anyone knows which bug it was, I'd be interested in reading up on it. In the meantime, I'll watch for alpha 8 or beta 1 to fix it.

@RonnyPfannschmidt
Copy link
Member

python/cpython#103551

noted via #10894 (comment) (which is why i didn't find it in the pytest issues )

@Zac-HD Zac-HD closed this as completed Apr 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants