microsoft / microsoft/pyright

Wrong signature of decorated method seen inside the decorated method

Open
#11,173 1 comment 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.