Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions src/pytestqt/wait_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ def _extract_pyqt_signal_name(self, potential_pyqt_signal):
signal_name = signal_name.lstrip("2")
return signal_name

def _extract_pyside_signal_name(self, potential_pyside_signal):
meta_method = qt_api.QtCore.QMetaMethod.fromSignal(potential_pyside_signal)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, on PyQt (both 5 and 6), I get AttributeError: type object 'QMetaMethod' has no attribute 'fromSignal', so it looks like the split between PyQt/PySide is still needed.

if not meta_method.isValid():
return ""
signal_name = meta_method.name().data().decode("utf-8")
return signal_name

def _extract_signal_from_signal_tuple(self, potential_signal_tuple):
if isinstance(potential_signal_tuple, tuple):
if len(potential_signal_tuple) != 2:
Expand Down Expand Up @@ -117,12 +124,15 @@ def determine_signal_name(self, potential_signal_tuple):
signal_name = self._extract_signal_from_signal_tuple(potential_signal_tuple)

if not signal_name:
try:
signal_name = self._extract_pyqt_signal_name(potential_signal_tuple)
except AttributeError:
# not a PyQt signal
# -> no signal name could be determined
signal_name = ""
if qt_api.is_pyqt:
try:
signal_name = self._extract_pyqt_signal_name(potential_signal_tuple)
except AttributeError:
# not a PyQt signal
# -> no signal name could be determined
signal_name = ""
elif qt_api.is_pyside:
signal_name = self._extract_pyside_signal_name(potential_signal_tuple)

return signal_name

Expand Down
19 changes: 7 additions & 12 deletions tests/test_wait_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ def test_empty_when_no_signal(self, qtbot, signaller):
pass
assert blocker.all_signals_and_args == []

def test_empty_when_no_signal_name_available(self, qtbot, signaller):
def test_non_empty_on_pyside(self, qtbot, signaller):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring and the pytest.skip call below don't make sense anymore with this change.

However, if we can adjust get_mixed_signals_with_guaranteed_name() to not require special handling of PySide anymore, I think the tests could be simplified a lot (no need for that helper function anymore), and then e.g. this test is probably completely superfluous anyways?

"""
Tests that all_signals_and_args is empty even though expected signals are emitted, but signal names aren't
available.
Expand All @@ -924,7 +924,7 @@ def test_empty_when_no_signal_name_available(self, qtbot, signaller):
) as blocker:
signaller.signal.emit()
signaller.signal_args.emit("1", 1)
assert blocker.all_signals_and_args == []
assert len(blocker.all_signals_and_args) == 2

def test_non_empty_on_timeout_no_cb(self, qtbot, signaller):
"""
Expand Down Expand Up @@ -1188,16 +1188,13 @@ def test_strict_order_violation(self, qtbot, signaller):
"Missing: [signal(), signal_args(QString,int), signal_args(QString,int)]"
).format(signal_args, signal_args)

def test_degenerate_error_msg(self, qtbot, signaller):
def test_error_msg_on_pyside(self, qtbot, signaller):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, when adjusting (or removing) get_mixed_signals_with_guaranteed_name, I think this won't be needed as a separate test anymore.

"""
Tests that the TimeoutError message is degenerate when using PySide6 signals for which no name is provided
by the user. This degenerate messages doesn't contain the signals' names, and includes a hint to the user how
to fix the situation.
Tests that the TimeoutError message is not degenerate when using PySide6 signals, since now
we can fetch the signal name in PySide6. The error message should provide the signal names.
"""
if qt_api.pytest_qt_api != "pyside6":
pytest.skip(
"test only makes sense for PySide, whose signals don't contain a name"
)
pytest.skip("test only makes sense for PySide")

with pytest.raises(TimeoutError) as excinfo:
with qtbot.waitSignals(
Expand All @@ -1214,9 +1211,7 @@ def test_degenerate_error_msg(self, qtbot, signaller):
signaller.signal.emit()
ex_msg = TestWaitSignalsTimeoutErrorMessage.get_exception_message(excinfo)
assert ex_msg == (
"Received 1 of the 3 expected signals. "
"To improve this error message, provide the names of the signals "
"in the waitSignals() call."
"Emitted signals: [signal]. Missing: [signal_args, signal_args]"
)

def test_self_defined_signal_name(self, qtbot, signaller):
Expand Down
Loading