You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
It seems like the inferred signature of functions wrapped with @functools.wraps depends on the signature of the wrapper itself.
To be more specific, there are cases where the wrapper function should take a self argument, like so:
defwrapper(self, *args, **kwargs):
pass
In this case, the signature of the wrapped function is inferred as (*args: Unknown, **kwargs: Unknown) -> Unknown.
If however, the wrapper takes only *args and **kwargs, the signature is inferred properly.
To Reproduce
Refer to the attached code.
Expected behavior
It is perhaps unclear what exactly should happen here, but if we run the same code in the python shell, and inspect its signature with the inspect.signature module method, the original signature is returned.
I therefore suggest this behavior is maintained in the typechecker.
Screenshots or Code
Version with self in wrapper:
importfunctoolsfromtypingimportCallabledeftest_decorator(
func: Callable
):
@functools.wraps(func)defwrapper(self, *args, **kwargs):
# Do something with self hereret_val=func(self, *args, **kwargs)
# Do some cleanupreturnret_valreturnwrapperclassTestClass:
@test_decoratordeftest_func(self, arg1: int):
passTestClass().test_func()
Version without self in wrapper:
importfunctoolsfromtypingimportCallabledeftest_decorator(
func: Callable
):
@functools.wraps(func)defwrapper(*args, **kwargs):
# Do something with self hereself=Noneret_val=func(self, *args, **kwargs)
# Do some cleanupreturnret_valreturnwrapperclassTestClass:
@test_decoratordeftest_func(self, arg1: int):
passTestClass().test_func()
VS Code extension or command-line
Pylance: v2022.1.3
Additional context
It is perhaps also worth it to think about other custom arguments.
For example, what happens if the wrapper's signature clearly doesn't match the wrapped function's?
The text was updated successfully, but these errors were encountered:
There is no type inference involved with functools.wraps. Pyright is simply applying the standard typing rules for call expression evaluation. The problem here is that the type definition for wraps in the typeshed functools.pyi stub is wrong. It should use a ParamSpec, which will retain additional information about the signature, including the fact that it's an instance method that contains a self parameter. I've submitted a PR to typeshed to fix it, but the PR has yet to be accepted because mypy does not work well with the updated definition. Until that PR is accepted, I don't think there's much we can do about this in pyright.
Describe the bug
It seems like the inferred signature of functions wrapped with
@functools.wraps
depends on the signature of the wrapper itself.To be more specific, there are cases where the wrapper function should take a
self
argument, like so:In this case, the signature of the wrapped function is inferred as
(*args: Unknown, **kwargs: Unknown) -> Unknown
.If however, the wrapper takes only
*args
and**kwargs
, the signature is inferred properly.To Reproduce
Refer to the attached code.
Expected behavior
It is perhaps unclear what exactly should happen here, but if we run the same code in the python shell, and inspect its signature with the
inspect.signature
module method, the original signature is returned.I therefore suggest this behavior is maintained in the typechecker.
Screenshots or Code
Version with
self
in wrapper:Version without
self
in wrapper:VS Code extension or command-line
Pylance: v2022.1.3
Additional context
It is perhaps also worth it to think about other custom arguments.
For example, what happens if the wrapper's signature clearly doesn't match the wrapped function's?
The text was updated successfully, but these errors were encountered: