typeshed
typeshed copied to clipboard
Would it be possible to broaden classmethod to accept ParamSpec when MyPy's support is better?
It could be something like:
P = ParamSpec('P')
class classmethod(Generic[P, _R_co]):
@property
def __func__(self) -> Callable[P, _R_co]: ...
@property
def __isabstractmethod__(self) -> bool: ...
def __init__(self: classmethod[_R_co], __f: Callable[P, _R_co]) -> None: ...
def __get__(self, __obj: _T, __type: type[_T] | None = ...) -> Callable[P, _R_co]: ...
if sys.version_info >= (3, 10):
__name__: str
__qualname__: str
__wrapped__: Callable[P, _R_co]
This is on my to-do list for as soon as mypy 0.950 is released 🙂
Though I'm not sure how much of a difference this will make, considering how thoroughly type checkers special case classmethod (and staticmethod).
Also, staticmethod
is quite a lot easier than classmethod
. staticmethod
doesn't change the signature of the function it wraps, but classmethod
does -- it requires Concatenate
. It would be something like this:
import sys
from typing import TypeVar, Callable, Generic
from typing_extensions import ParamSpec, Concatenate
_P = ParamSpec("_P")
_R_co = TypeVar("_R_co", covariant=True)
_T = TypeVar("_T")
class classmethod(Generic[_P, _R_co, _T]):
@property
def __func__(self) -> Callable[Concatenate[_T, _P], _R_co]: ...
@property
def __isabstractmethod__(self) -> bool: ...
def __init__(self: classmethod[_P, _R_co, _T], __f: Callable[Concatenate[_T, _P], _R_co]) -> None: ...
def __get__(self, __obj: _T | None, __type: type[_T] | None = ...) -> Callable[_P, _R_co]: ...
if sys.version_info >= (3, 10):
__name__: str
__qualname__: str
@property
def __wrapped__(self) -> Callable[Concatenate[_T, _P], _R_co]: ...
@JelleZijlstra Yup, I just learned about that here. It's not too big a deal since it's very rare that you decorate class methods, but maybe after classmethod
is broadened they might consider producing a classmethod[P, R, T]
instead of a Callable[Concatenate[type[T], P], R]
.
Mypy 0.950 is now out, but sadly we still cannot use ParamSpec
in classmethod
or staticmethod
due to https://github.com/python/mypy/issues/12011. (abc.abstractclassmethod
and abc.abstractstaticmethod
inherit from classmethod
and staticmethod
respectively, so while that mypy issue is outstanding, we cannot make builtins.staticmethod
or builtins.classmethod
generic over a parameter specification without breaking those two classes.)