Wrong signature of decorated method seen inside the decorated method
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
I have a decorator injecting extra positional parameter into the method. Inside the decorated method, the own changed signature is recognized in the simple case (call). But failed to be recognized in more complex case: applying the ParamSpec'ced function and only if result is actually accessed.
The peer method of the same class see the decorated method correctly.
Minimal example:
```python
from functools import wraps
from typing import Callable, Concatenate
def inject_extra_arg[
TCls: object, **P
](f: Callable[Concatenate[TCls, str, int, P], None]) -> Callable[Concatenate[TCls, str, P], None]:
@wraps(f)
def _wrapper(self: TCls, req: str, /, *args: P.args, **kwargs: P.kwargs):
extra_arg = 42
return f(self, req, extra_arg, *args, **kwargs)
return _wrapper
def take_args[
**P
](meth: Callable[Concatenate[str, P], None], /, *args: P.args, **kwargs: P.kwargs,):
return f"{args} {kwargs}"
class Resource:
@inject_extra_arg
def meth_with_extra_arg(self, req: str, injected: int, thing: str):
# Ok, no 'injected' in parameters: Type of "self.meth_with_extra_arg" is "(str, thing: str) "
reveal_type(self.meth_with_extra_arg)
# Call is ok
self.meth_with_extra_arg("foo", thing="bar")
# Seems to be ok too, until the result is accessed
take_args(self.meth_with_extra_arg, thing="1")
# Error: Argument missing for parameter "injected"
take_args(self.meth_with_extra_arg, thing="1").capitalize()
return None
def friend_of_decorated_meth(self):
# Type is ok
reveal_type(self.meth_with_extra_arg)
# Ok
take_args(self.meth_with_extra_arg, thing="1").capitalize()
return None
```
Changing first args to be positional-only makes no difference.
**pyright 1.1.407**
Contributor guide
Research direction
Start by running the minimal Python example with pyright 1.1.407 and compare the revealed type and errors inside Resource.meth_with_extra_arg with those in friend_of_decorated_meth. Trace the handling of the decorated method when take_args returns a value and capitalize() is accessed; done means the reproduced error is resolved without regressing the direct call or peer-method cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100