Skip to content

Commit b30977e

Browse files
The-CompilerPierre-Sassoulas
authored andcommitted
qt brain: Make slot argument optional for disconnect() (#1550)
* qt brain: Make slot argument optional for disconnect() Discussed here: #1531 (comment) PyQt supports calling .disconnect() without any arguments in order to disconnect all slots: https://www.riverbankcomputing.com/static/Docs/PyQt6/signals_slots.html#disconnect Strictly speaking, slot=None is a wrong call, as actually passing None does not work: python-qt-tools/PyQt5-stubs#103 However, pylint/astroid does not support overloads needed to properly express this: pylint-dev/pylint#5264 So, while this is "wrong", it's less wrong than before - without this change, pylint expects a mandatory argument, thus raising a false-positive here: from PyQt5.QtCore import QTimer t = QTimer() t.timeout.connect(lambda: None) t.timeout.disconnect() despite running fine, pylint complains: test.py:4:0: E1120: No value for argument 'slot' in method call (no-value-for-parameter) while with this change, things work fine.
1 parent 218ed2b commit b30977e

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ What's New in astroid 2.11.6?
1313
=============================
1414
Release date: TBA
1515

16+
* The Qt brain now correctly treats calling ``.disconnect()`` (with no
17+
arguments) on a slot as valid.
1618

1719

1820
What's New in astroid 2.11.5?

astroid/brain/brain_qt.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ def _looks_like_signal(node, signal_name="pyqtSignal"):
2424
def transform_pyqt_signal(node: nodes.FunctionDef) -> None:
2525
module = parse(
2626
"""
27+
_UNSET = object()
28+
2729
class pyqtSignal(object):
2830
def connect(self, slot, type=None, no_receiver_check=False):
2931
pass
30-
def disconnect(self, slot):
32+
def disconnect(self, slot=_UNSET):
3133
pass
3234
def emit(self, *args):
3335
pass

tests/unittest_brain_qt.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,21 @@ def test_implicit_parameters() -> None:
5252
pytest.skip("PyQt6 C bindings may not be installed?")
5353
assert isinstance(attribute_node, FunctionDef)
5454
assert attribute_node.implicit_parameters() == 1
55+
56+
@staticmethod
57+
def test_slot_disconnect_no_args() -> None:
58+
"""Test calling .disconnect() on a signal.
59+
60+
See https://github.com/PyCQA/astroid/pull/1531#issuecomment-1111963792
61+
"""
62+
src = """
63+
from PyQt6.QtCore import QTimer
64+
timer = QTimer()
65+
timer.timeout.disconnect #@
66+
"""
67+
node = extract_node(src)
68+
attribute_node = node.inferred()[0]
69+
if attribute_node is Uninferable:
70+
pytest.skip("PyQt6 C bindings may not be installed?")
71+
assert isinstance(attribute_node, FunctionDef)
72+
assert attribute_node.args.defaults

0 commit comments

Comments
 (0)