Closed
Description
It feels like the classmethod typing is slightly wrong.
Typeshed defines it as:
class classmethod(Generic[_T, _P, _R_co]):
@property
def __isabstractmethod__(self) -> bool: ...
def __init__(self, __f: Callable[Concatenate[_T, _P], _R_co]) -> None: ...
def __get__(self, __instance: _T, __owner: type[_T] | None = None) -> Callable[_P, _R_co]: ...
...
With mypy the following program fails:
from typing import *
def foo(cls: Type['G'], x: int) -> str: return ""
def bar(cls: 'G' | None, x: int) -> str: return ""
class G:
x = classmethod(foo)
y = classmethod(bar)
G.x(1) # Fails
G.y(1) # Works
new.py:11: error: Argument 1 to "__get__" of "classmethod" has incompatible type "None"; expected "type[G]" [arg-type]
new.py:11: error: Argument 2 to "__get__" of "classmethod" has incompatible type "type[G]"; expected "type[type[G]] | None" [arg-type]
The proper solution would probably be to type __init__
as:
def __init__(self, __f: Callable[Concatenate[Type[_T], _P], _R_co]) -> None: ...
Would such a pull request be accepted? If I change this in Mypy it fails with error: Need type annotation for "x"
, which I think is much better (and Mypy could probably still infer the type variable _T
properly in the future). What do you think?
Metadata
Metadata
Assignees
Labels
No labels