-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Bug Report
Wrapping a function that accepts TypeVar arguments in a staticmethod will fool mypy into thinking that the first TypeVar argument is of type <classname> | None. This only applies if a function is wrapped, not when a method decorated.
To Reproduce
from typing import TypeVar
T = TypeVar("T")
def foo(a: T) -> T:
return a
class Foo:
foo = staticmethod(foo)
@staticmethod
def bar(a: T) -> T:
return a
reveal_type(foo) # Revealed type is "def [T] (a: T`-1) -> T`-1"
reveal_type(Foo.foo) # Revealed type is "def [T] (a: Union[__main__.Foo, None]) -> Union[__main__.Foo, None]"
reveal_type(Foo.bar) # Revealed type is "def [T] (a: T`-1) -> T`-1"
Foo.foo("a") # error: Argument 1 has incompatible type "str"; expected "Foo | None" [arg-type]
Foo.bar("a") # no issuehttps://mypy-play.net/?mypy=latest&python=3.11&gist=2c0e679c14a40c36932905bdc4299cc1
The issue persists if the TypeVar is not the first variable, e.g. def foo(a: str, b: T) has the same issue. If there are multiple TypeVars, then the issue is only with the first one, e.g. def foo(a: T1, b: T2).
The issue was introduced in mypy 1.2.0 -- the example works fine in 1.1.1.
Expected Behavior
I would expect mypy to behave identical for the invocations of staticmethod as an applied function and as a decorator. Both should behave as the staticmethod decorator does (Foo.bar).
Actual Behavior
Mypy incorrectly thinks that the first TypeVar becomes Foo | None, whereas it should still be a fully generic TypeVar.
Your Environment
- Mypy version used: 1.2.0 - 1.4.1
- Mypy command-line flags:
- Mypy configuration options from
mypy.ini(and other config files): - Python version used: 3.11