2011/10/13 Phil Thompson <p...@riverbankcomputing.com> > On Wed, 12 Oct 2011 15:57:17 +0200, Luper Rouch <luper.ro...@gmail.com> > wrote: > > 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 : > > > > import functools > > from PyQt4.QtCore import QObject, pyqtSignal > > > > class Sender(QObject): > > > > hello = pyqtSignal(bool) > > > > def receiver(): > > print "foo" > > > > def decorator(func): > > @functools.wraps(func) > > def wrapped(*args, **kwargs): > > return func(*args, **kwargs) > > return wrapped > > > > decorated_receiver = decorator(receiver) > > > > if __name__ == "__main__": > > sender = Sender() > > sender.hello.connect(receiver) > > sender.hello.connect(decorated_receiver) > > sender.hello.emit(True) > > > > When executed, the script gives the following error : > > > > $ python test_signature.py > > foo > > Traceback (most recent call last): > > File "test_signature.py", line 17, in wrapped > > return func(*args, **kwargs) > > TypeError: receiver() takes no arguments (1 given) > > > > 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]). > > > > 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. > > > > It would be nice if PyQt did some additional checks when connecting to a > > functools.partial object. > > Like what? > > The problem isn't when connecting but when emitting. PyQt emulates the Qt > behaviour of allowing a slot to take fewer arguments than the signal is > providing. It does this by detecting a TypeError raised by the act of > calling the slot. In this case the exception is raised in the body of the > slot and there is no way for PyQt to distinguish between that and any other > TypeError raised while executing the slot. > > Maybe with a special path for partials and the likes:
if hasattr(slot, "args"): # use slot.args to adapt slot call else: # call the slot the normally Could you please point me where the slot calling code lives so I can have a better understanding of how things work ? -- Luper Rouch
_______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt