Skip to content

Wrong signature of decorated method seen inside the decorated method #11173

@jkmnt

Description

@jkmnt

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:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions