3
3
import pytest
4
4
5
5
from 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
+ )
6
15
7
16
8
17
@pytest .mark .parametrize ("raise_error" , [False , True ])
@@ -42,10 +51,24 @@ def test_exceptions(qtbot):
42
51
)
43
52
result = testdir .runpytest ()
44
53
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
+ ]
49
72
result .stdout .fnmatch_lines (expected_lines )
50
73
assert "pytest.fail" not in "\n " .join (result .outlines )
51
74
else :
@@ -84,6 +107,7 @@ def test_format_captured_exceptions_chained():
84
107
85
108
86
109
@pytest .mark .parametrize ("no_capture_by_marker" , [True , False ])
110
+ @exception_capture_pyside6
87
111
def test_no_capture (testdir , no_capture_by_marker ):
88
112
"""
89
113
Make sure options that disable exception capture are working (either marker
@@ -99,15 +123,15 @@ def test_no_capture(testdir, no_capture_by_marker):
99
123
"""
100
124
[pytest]
101
125
qt_no_exception_capture = 1
102
- """
126
+ """
103
127
)
104
128
testdir .makepyfile (
105
- """
129
+ f """
106
130
import pytest
107
131
import sys
108
132
from pytestqt.qt_compat import qt_api
109
133
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.
111
135
sys.excepthook = lambda *args: None
112
136
113
137
class MyWidget(qt_api.QtWidgets.QWidget):
@@ -120,9 +144,7 @@ def test_widget(qtbot):
120
144
w = MyWidget()
121
145
qtbot.addWidget(w)
122
146
qtbot.mouseClick(w, qt_api.QtCore.Qt.MouseButton.LeftButton)
123
- """ .format (
124
- marker_code = marker_code
125
- )
147
+ """
126
148
)
127
149
res = testdir .runpytest ()
128
150
res .stdout .fnmatch_lines (["*1 passed*" ])
@@ -265,6 +287,7 @@ def test_capture(widget):
265
287
266
288
267
289
@pytest .mark .qt_no_exception_capture
290
+ @exception_capture_pyside6
268
291
def test_capture_exceptions_context_manager (qapp ):
269
292
"""Test capture_exceptions() context manager.
270
293
@@ -319,6 +342,7 @@ def raise_on_event():
319
342
result .stdout .fnmatch_lines (["*1 passed*" ])
320
343
321
344
345
+ @exception_capture_pyside6
322
346
def test_exceptions_to_stderr (qapp , capsys ):
323
347
"""
324
348
Exceptions should still be reported to stderr.
@@ -341,10 +365,7 @@ def event(self, ev):
341
365
assert 'raise RuntimeError("event processed")' in err
342
366
343
367
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
348
369
def test_exceptions_dont_leak (testdir ):
349
370
"""
350
371
Ensure exceptions are cleared when an exception occurs and don't leak (#187).
0 commit comments