Skip to content

Arg(T, 'name') not equivalent to T in Callable #13429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
matteosantama opened this issue Aug 15, 2022 · 2 comments · Fixed by #13777
Closed

Arg(T, 'name') not equivalent to T in Callable #13429

matteosantama opened this issue Aug 15, 2022 · 2 comments · Fixed by #13777
Labels
bug mypy got something wrong topic-calls Function calls, *args, **kwargs, defaults

Comments

@matteosantama
Copy link

Given the code

T = TypeVar("T", bound="Foo")
P = ParamSpec("P")

# this class serves as a decorator
class print_y_first:
    def __call__(
        self, method: Callable[Concatenate[T, P], str]
    ) -> Callable[Concatenate[T, P], str]:
        def wrapper(_self: T, *args: P.args, **kwargs: P.kwargs) -> str:
            print(_self.y)
            return method(*args, **kwargs)

        return wrapper


class Foo:

    y: int

    @print_y_first()
    def stringify(self, x: int) -> str:
        return str(x)

Mypy reports

error: Incompatible return value type (got "Callable[[Arg(T, '_self'), **P], str]", expected "Callable[[T, **P], str]")  [return-value]
note: This may be because "wrapper" has arguments named: "_self"

It does not recognize that

Callable[[Arg(T, '_self'), **P], str] == Callable[[T, **P], str]

Mypy version: mypy 0.971 (compiled: yes)
Mypy config options: --strict=True
Python version: 3.10.4

@matteosantama matteosantama added the bug mypy got something wrong label Aug 15, 2022
@JelleZijlstra JelleZijlstra added the topic-calls Function calls, *args, **kwargs, defaults label Aug 16, 2022
@A5rocks
Copy link
Collaborator

A5rocks commented Sep 13, 2022

Heya! This was a bit confusing while I was implementing Concatenate which is why I added that note -- it doesn't seem to be helping so I may have to reconsider wording...

But AFAICT, this is because:

@print_y_first()
def blah(self: str, _self: int) -> str:
    return str(_self)

Now, blah("m", _self=42) would be accepted if blah were a Callable[[str, _self: int], str]... But you can probably see the unsafety here :P

The solution is either to stick a / after _self in the decorator, or --no-strict-concatenate (I think that was the flag?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-calls Function calls, *args, **kwargs, defaults
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
@JelleZijlstra @matteosantama @A5rocks and others