pytest-qt icon indicating copy to clipboard operation
pytest-qt copied to clipboard

test_catch_exceptions_in_virtual_methods[True] fails with PySide6 >= 6.8.0

Open penguinpee opened this issue 1 year ago • 0 comments

In Fedora (rawhide) with PySide6 6.8.0 and Python 3.13.0 I'm seeing the following failures when running tests:

=================================== FAILURES ===================================
________________ test_catch_exceptions_in_virtual_methods[True] ________________
testdir = <Testdir local('/tmp/pytest-of-mockbuild/pytest-1/test_catch_exceptions_in_virtual_methods1')>
raise_error = True
    @pytest.mark.parametrize("raise_error", [False, True])
    def test_catch_exceptions_in_virtual_methods(testdir, raise_error):
        """
        Catch exceptions that happen inside Qt's event loop and make the
        tests fail if any.
    
        :type testdir: _pytest.pytester.TmpTestdir
        """
        testdir.makepyfile(
            """
            from pytestqt.qt_compat import qt_api
    
            class Receiver(qt_api.QtCore.QObject):
    
                def event(self, ev):
                    if {raise_error}:
                        try:
                            raise RuntimeError('original error')
                        except RuntimeError:
                            raise ValueError('mistakes were made')
    
                    return qt_api.QtCore.QObject.event(self, ev)
    
    
            def test_exceptions(qtbot):
                v = Receiver()
                app = qt_api.QtWidgets.QApplication.instance()
                app.sendEvent(v, qt_api.QtCore.QEvent(qt_api.QtCore.QEvent.Type.User))
                app.sendEvent(v, qt_api.QtCore.QEvent(qt_api.QtCore.QEvent.Type.User))
                app.processEvents()
    
        """.format(
                raise_error=raise_error
            )
        )
        result = testdir.runpytest()
        if raise_error:
            if qt_api.pytest_qt_api == "pyside6":
                # PySide6 automatically captures exceptions during the event loop,
                # and re-raises them when control gets back to Python.
                # This results in the exception not being captured by
                # us, and a more natural traceback which includes the app.sendEvent line.
                expected_lines = [
                    "*RuntimeError: original error",
                    "*app.sendEvent*",
                    "*ValueError: mistakes were made*",
                    "*1 failed*",
                ]
            else:
                expected_lines = [
                    "*Exceptions caught in Qt event loop:*",
                    "RuntimeError: original error",
                    "*ValueError: mistakes were made*",
                    "*1 failed*",
                ]
>           result.stdout.fnmatch_lines(expected_lines)
E           Failed: nomatch: '*RuntimeError: original error'
E               and: '============================= test session starts =============================='
E               and: 'platform linux -- Python 3.13.0, pytest-8.3.3, pluggy-1.5.0'
E               and: 'PyQtAPI 1.0 -- Qt runtime 2.5 -- Qt compiled 3.5'
E               and: 'rootdir: /tmp/pytest-of-mockbuild/pytest-1/test_catch_exceptions_in_virtual_methods1'
E               and: 'plugins: qt-4.4.0'
E               and: 'collected 1 item'
E               and: ''
E               and: 'test_catch_exceptions_in_virtual_methods.py F                            [100%]'
E               and: ''
E               and: '=================================== FAILURES ==================================='
E               and: '_______________________________ test_exceptions ________________________________'
E               and: ''
E               and: 'self = <test_catch_exceptions_in_virtual_methods.Receiver(0x564b3bc33870) at 0x7f604702f500>'
E               and: 'ev = <PySide6.QtCore.QEvent(QEvent::User)>'
E               and: ''
E               and: '    def event(self, ev):'
E               and: '        if True:'
E               and: '            try:'
E               and: ">               raise RuntimeError('original error')"
E           fnmatch: '*RuntimeError: original error'
E              with: 'E               RuntimeError: original error'
E           nomatch: '*app.sendEvent*'
E               and: ''
E               and: 'test_catch_exceptions_in_virtual_methods.py:8: RuntimeError'
E               and: ''
E               and: 'During handling of the above exception, another exception occurred:'
E               and: ''
E               and: 'qtbot = <pytestqt.qtbot.QtBot object at 0x7f60472343c0>'
E               and: ''
E               and: '    def test_exceptions(qtbot):'
E               and: '        v = Receiver()'
E               and: '        app = qt_api.QtWidgets.QApplication.instance()'
E           fnmatch: '*app.sendEvent*'
E              with: '>       app.sendEvent(v, qt_api.QtCore.QEvent(qt_api.QtCore.QEvent.Type.User))'
E           nomatch: '*ValueError: mistakes were made*'
E               and: ''
E               and: 'test_catch_exceptions_in_virtual_methods.py:18: '
E               and: '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ '
E               and: ''
E               and: 'self = <test_catch_exceptions_in_virtual_methods.Receiver(0x564b3bc33870) at 0x7f604702f500>'
E               and: 'ev = <PySide6.QtCore.QEvent(QEvent::User)>'
E               and: ''
E               and: '    def event(self, ev):'
E               and: '        if True:'
E               and: '            try:'
E               and: "                raise RuntimeError('original error')"
E               and: '            except RuntimeError:'
E               and: ">               raise ValueError('mistakes were made')"
E               and: 'E               ValueError: Error calling Python override of QObject::event(): mistakes were made'
E               and: ''
E               and: 'test_catch_exceptions_in_virtual_methods.py:10: ValueError'
E               and: '=========================== short test summary info ============================'
E               and: 'FAILED test_catch_exceptions_in_virtual_methods.py::test_exceptions - ValueEr...'
E               and: '============================== 1 failed in 0.02s ==============================='
E           remains unmatched: '*ValueError: mistakes were made*'
/builddir/build/BUILD/python-pytest-qt-4.4.0-build/pytest-qt-4.4.0/tests/test_exceptions.py:72: Failed
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.13.0, pytest-8.3.3, pluggy-1.5.0
PyQtAPI 1.0 -- Qt runtime 2.5 -- Qt compiled 3.5
rootdir: /tmp/pytest-of-mockbuild/pytest-1/test_catch_exceptions_in_virtual_methods1
plugins: qt-4.4.0
collected 1 item
test_catch_exceptions_in_virtual_methods.py F                            [100%]
=================================== FAILURES ===================================
_______________________________ test_exceptions ________________________________
self = <test_catch_exceptions_in_virtual_methods.Receiver(0x564b3bc33870) at 0x7f604702f500>
ev = <PySide6.QtCore.QEvent(QEvent::User)>
    def event(self, ev):
        if True:
            try:
>               raise RuntimeError('original error')
E               RuntimeError: original error
test_catch_exceptions_in_virtual_methods.py:8: RuntimeError
During handling of the above exception, another exception occurred:
qtbot = <pytestqt.qtbot.QtBot object at 0x7f60472343c0>
    def test_exceptions(qtbot):
        v = Receiver()
        app = qt_api.QtWidgets.QApplication.instance()
>       app.sendEvent(v, qt_api.QtCore.QEvent(qt_api.QtCore.QEvent.Type.User))
test_catch_exceptions_in_virtual_methods.py:18: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <test_catch_exceptions_in_virtual_methods.Receiver(0x564b3bc33870) at 0x7f604702f500>
ev = <PySide6.QtCore.QEvent(QEvent::User)>
    def event(self, ev):
        if True:
            try:
                raise RuntimeError('original error')
            except RuntimeError:
>               raise ValueError('mistakes were made')
E               ValueError: Error calling Python override of QObject::event(): mistakes were made
test_catch_exceptions_in_virtual_methods.py:10: ValueError

It seems the test fails solely because of changed output (passed down from the exception?).

Changing:

https://github.com/pytest-dev/pytest-qt/blob/cdad310e88bcabe0cd6eb21843125b43706b54f1/tests/test_exceptions.py#L62

to

"*ValueError: *mistakes were made*",

makes the test pass. Though, I expect, the actual fix should be somewhat more sophisticated.

PS: Issue was original reported as part of #573.

penguinpee avatar Oct 18 '24 19:10 penguinpee