pytest-dev / pytest-dev/pytest-qt

test_catch_exceptions_in_virtual_methods[True] fails with PySide6 >= 6.8.0

Open
#575 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
455
Forks
72
Avg merge
12h 26m
Merged PRs (30d)
1

Description

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.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with tests/test_exceptions.py, especially test_catch_exceptions_in_virtual_methods and its expected PySide6 output. Run the failing test with PySide6 6.8.0 or newer, then update the test or exception handling so the changed traceback remains correctly validated while both original and wrapped exceptions are covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.