<span style="font-family: courier new,monospace;" class="gI"><font face="arial,helvetica,sans-serif">PyQt seems to ignore the signature of functools.partial objects (the 'args' and 'keywords' attributes [1]), when connecting a callable. Here is an example demonstrating the problem : </font><br>
<br>import functools<br>from PyQt4.QtCore import QObject, pyqtSignal<br><br>class Sender(QObject):<br><br> hello = pyqtSignal(bool)<br><br>def receiver():<br> print "foo"<br><br>def decorator(func):<br> @functools.wraps(func)<br>
def wrapped(*args, **kwargs):<br> return func(*args, **kwargs)<br> return wrapped<br><br>decorated_receiver = decorator(receiver)<br><br>if __name__ == "__main__":<br> sender = Sender()<br> sender.hello.connect(receiver)<br>
sender.hello.connect(decorated_receiver)<br> sender.hello.emit(True)</span><br><br>When executed, the script gives the following error :<br><br><span style="font-family: courier new,monospace;">$ python test_signature.py</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">foo</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Traceback (most recent call last):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> File "test_signature.py", line 17, in wrapped</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> return func(*args, **kwargs)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">TypeError: receiver() takes no arguments (1 given)</span><br><br>Connecting to a lambda is not a good solution, because PyQt increases its reference count to keep it alive ("However, if a slot
is a lambda function or a partial function then its reference count is
automatically incremented to prevent it from being immediately garbage
collected", see [2]).<br><br>If you do this in a widget that is later deleted, the lambda stays alive, leading to complex bugs. The only solution is to connect to a normal method calling the decorated method, which can quickly become cumbersome.<br>
<br>It would be nice if PyQt did some additional checks when connecting to a functools.partial object.<br><br clear="all">[1] <a href="http://docs.python.org/library/functools.html#partial-objects">http://docs.python.org/library/functools.html#partial-objects</a><br>
[2] <a href="http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/old_style_signals_slots.html#pyqt-slots-and-qt-slots">http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/old_style_signals_slots.html#pyqt-slots-and-qt-slots</a><br>
<br>-- <br>Luper Rouch<br>