-
Notifications
You must be signed in to change notification settings - Fork 116
Description
(Sorry if the title is somewhat misleading or I did get some jargon wrong)
In version 5.1.1 methods decorated by decorate created with the decorator lib stopped working with qt(pyqt?) signals that inspect the signature of the connected slot (also tested with 4.0.2 with a slight different error).
Failing snippet:
@decorator
def dummy_decorator(f, *args, **kwargs):
return f(*args, **kwargs)
class Foo:
def __init__(self):
self.action = QAction()
self.action.triggered.connect(self.ActionCallbackNoArg)
@dummy_decorator
def ActionCallbackNoArg(self):
pass
foo = Foo()
foo.action.trigger()This was not an issue in 4.4.2.
While porting our code base to python 3.10 the decorator version also got upgraded, decorator version prior to this was 4.4.2.
We will probably be able to downgrade back for now.
I created a test to reproduce the error.
add_qt_test_patch.txt
Create env and install decorator in editable mode:
conda create -n decorator python=3.6 pyqt
conda activate decorator
pip install --editable .
Test with 4.4.2 (pass):
W:\my\Projects\decorator (master -> origin)
(decorator) λ git checkout -- src/tests/test.py
W:\my\Projects\decorator (master -> origin)
(decorator) λ git checkout 4.4.2
Note: switching to '4.4.2'.
...
HEAD is now at 55a68b5 Updated setup.py [skip CI]
W:\my\Projects\decorator (HEAD detached at 55a68b5)
(decorator) λ patch -i add_qt_test_patch.txt -p 1
patching file src/tests/test.py
Hunk #1 succeeded at 18 with fuzz 1 (offset 6 lines).
W:\my\Projects\decorator (HEAD detached at 55a68b5)
(decorator) λ python src/tests/test.py -v QtActionTestCase.test_qt_decorator_signature_preserving_interaction_methods
test_qt_decorator_signature_preserving_interaction_methods (__main__.QtActionTestCase) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Test with 5.1.1 (fail, at the time of this writing origin/master will also fail):
W:\my\Projects\decorator (HEAD detached at 55a68b5)
(decorator) λ git checkout -- src/tests/test.py
W:\my\Projects\decorator (HEAD detached at 55a68b5)
(decorator) λ git checkout 5.1.1
Previous HEAD position was 55a68b5 Updated setup.py [skip CI]
HEAD is now at ad013a2 Updated changelog and bumped version to 5.1.1
W:\my\Projects\decorator (HEAD detached at ad013a2)
(decorator) λ patch -i add_qt_test_patch.txt -p 1
patching file src/tests/test.py
W:\my\Projects\decorator (HEAD detached at ad013a2)
(decorator) λ python src/tests/test.py -v QtActionTestCase.test_qt_decorator_signature_preserving_interaction_methods
test_qt_decorator_signature_preserving_interaction_methods (__main__.QtActionTestCase) ... Traceback (most recent call last):
File "w:\my\projects\decorator\src\decorator.py", line 231, in fun
args, kw = fix(args, kw, sig)
File "w:\my\projects\decorator\src\decorator.py", line 203, in fix
ba = sig.bind(*args, **kwargs)
File "W:\my\envs\decorator\lib\inspect.py", line 2997, in bind
return args[0]._bind(args[1:], kwargs)
File "W:\my\envs\decorator\lib\inspect.py", line 2918, in _bind
raise TypeError('too many positional arguments') from None
TypeError: too many positional arguments
I also was somewhat curious.
"Plain" functions:
>>> plain.ActionCallbackNoArg.__func__.__code__.co_argcount
1
>>> plain.ActionCallbackNoArg.__func__.__code__.co_varnames
('self',)
>>> plain.ActionCallbackAnyArgs.__func__.__code__.co_argcount
1
>>> plain.ActionCallbackAnyArgs.__func__.__code__.co_varnames
('self', 'args', 'kwargs')
Decorated with 4.4.2:
>>> decorated.ActionCallbackNoArg.__func__.__code__.co_argcount
1
>>> decorated.ActionCallbackNoArg.__func__.__code__.co_varnames
('self',)
>>> decorated.ActionCallbackAnyArgs.__func__.__code__.co_argcount
1
>>> decorated.ActionCallbackAnyArgs.__func__.__code__.co_varnames
('self', 'args', 'kwargs')
Decorated with 5.1.1:
>>> decorated.ActionCallbackNoArg.__func__.__code__.co_argcount
0
>>> decorated.ActionCallbackNoArg.__func__.__code__.co_varnames
('args', 'kw')
>>> decorated.ActionCallbackAnyArgs.__func__.__code__.co_argcount
0
>>> decorated.ActionCallbackAnyArgs.__func__.__code__.co_varnames
('args', 'kw')