33import pytest
44
55from pytestqt .exceptions import capture_exceptions , format_captured_exceptions
6+ from pytestqt .qt_compat import qt_api
7+
8+ # PySide6 is automatically captures exceptions during the event loop,
9+ # and re-raises them when control gets back to Python, so the related
10+ # functionality does not work, nor is needed for the end user.
11+ exception_capture_pyside6 = pytest .mark .skipif (
12+ qt_api .pytest_qt_api == "pyside6" ,
13+ reason = "pytest-qt capture not working/needed on PySide6" ,
14+ )
615
716
817@pytest .mark .parametrize ("raise_error" , [False , True ])
@@ -42,10 +51,24 @@ def test_exceptions(qtbot):
4251 )
4352 result = testdir .runpytest ()
4453 if raise_error :
45- expected_lines = ["*Exceptions caught in Qt event loop:*" ]
46- if sys .version_info .major == 3 :
47- expected_lines .append ("RuntimeError: original error" )
48- expected_lines .extend (["*ValueError: mistakes were made*" , "*1 failed*" ])
54+ if qt_api .pytest_qt_api == "pyside6" :
55+ # PySide6 automatically captures exceptions during the event loop,
56+ # and re-raises them when control gets back to Python.
57+ # This results in the exception not being captured by
58+ # us, and a more natural traceback which includes the app.sendEvent line.
59+ expected_lines = [
60+ "*RuntimeError: original error" ,
61+ "*app.sendEvent*" ,
62+ "*ValueError: mistakes were made*" ,
63+ "*1 failed*" ,
64+ ]
65+ else :
66+ expected_lines = [
67+ "*Exceptions caught in Qt event loop:*" ,
68+ "RuntimeError: original error" ,
69+ "*ValueError: mistakes were made*" ,
70+ "*1 failed*" ,
71+ ]
4972 result .stdout .fnmatch_lines (expected_lines )
5073 assert "pytest.fail" not in "\n " .join (result .outlines )
5174 else :
@@ -84,6 +107,7 @@ def test_format_captured_exceptions_chained():
84107
85108
86109@pytest .mark .parametrize ("no_capture_by_marker" , [True , False ])
110+ @exception_capture_pyside6
87111def test_no_capture (testdir , no_capture_by_marker ):
88112 """
89113 Make sure options that disable exception capture are working (either marker
@@ -99,15 +123,15 @@ def test_no_capture(testdir, no_capture_by_marker):
99123 """
100124 [pytest]
101125 qt_no_exception_capture = 1
102- """
126+ """
103127 )
104128 testdir .makepyfile (
105- """
129+ f """
106130 import pytest
107131 import sys
108132 from pytestqt.qt_compat import qt_api
109133
110- # PyQt 5.5+ will crash if there's no custom exception handler installed
134+ # PyQt 5.5+ will crash if there's no custom exception handler installed.
111135 sys.excepthook = lambda *args: None
112136
113137 class MyWidget(qt_api.QtWidgets.QWidget):
@@ -120,9 +144,7 @@ def test_widget(qtbot):
120144 w = MyWidget()
121145 qtbot.addWidget(w)
122146 qtbot.mouseClick(w, qt_api.QtCore.Qt.MouseButton.LeftButton)
123- """ .format (
124- marker_code = marker_code
125- )
147+ """
126148 )
127149 res = testdir .runpytest ()
128150 res .stdout .fnmatch_lines (["*1 passed*" ])
@@ -265,6 +287,7 @@ def test_capture(widget):
265287
266288
267289@pytest .mark .qt_no_exception_capture
290+ @exception_capture_pyside6
268291def test_capture_exceptions_context_manager (qapp ):
269292 """Test capture_exceptions() context manager.
270293
@@ -319,6 +342,7 @@ def raise_on_event():
319342 result .stdout .fnmatch_lines (["*1 passed*" ])
320343
321344
345+ @exception_capture_pyside6
322346def test_exceptions_to_stderr (qapp , capsys ):
323347 """
324348 Exceptions should still be reported to stderr.
@@ -341,10 +365,7 @@ def event(self, ev):
341365 assert 'raise RuntimeError("event processed")' in err
342366
343367
344- @pytest .mark .xfail (
345- condition = sys .version_info [:2 ] == (3 , 4 ),
346- reason = "failing in Python 3.4, which is about to be dropped soon anyway" ,
347- )
368+ @exception_capture_pyside6
348369def test_exceptions_dont_leak (testdir ):
349370 """
350371 Ensure exceptions are cleared when an exception occurs and don't leak (#187).
0 commit comments