-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
functools.partial should use PEP612 ParamSpec (depends on #8708) #8703
Comments
You can nearly get there with a combination of PEP 612 and PEP 646: import sys
from types import GenericAlias
from typing import Any, Callable, Concatenate, Generic, ParamSpec, TypeVar, TypeVarTuple, overload
_P1 = ParamSpec("_P1")
_P2 = ParamSpec("_P2")
_T = TypeVar("_T")
_R_co = TypeVar("_R_co", covariant=True)
_Ts = TypeVarTuple("_Ts")
class partial(Generic[_P1, _P2, _T, _R_co, *_Ts]):
@overload
def __new__(cls, __func: Callable[_P1, _R_co]) -> partial[_P1, _P1, Any, _R_co]: ...
@overload
def __new__(cls, __func: Callable[Concatenate[*_Ts, _P2], _R_co], *args: *_Ts) -> partial[Concatenate[*_Ts, _P2], _P2, Any, _R_co, *_Ts]: ...
@overload
def __new__(cls, __func: Callable[_P1, _R_co], *args: *_Ts, **kwargs: _T) -> partial[_P1, ..., _T, _R_co, *_Ts]: ...
def __call__(self, *args: _P2.args, **kwargs: _P2.kwargs) -> _R_co: ...
@property
def func(self) -> Callable[_P1, _R_co]: ...
@property
def args(self) -> tuple[*_Ts]: ...
@property
def keywords(self) -> dict[str, _T]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ... Mypy doesn't support PEP 646 yet, however. And even if it did, there would still be some corner cases that don't work (PyCQA/flake8-pyi#150 (comment)) |
Hmmm, I think that's probably the best we're gonna get for now. It's a strict improvement in my opinion. |
Cf. #8708 |
#8708 has been closed. Can this be un-deferred yet? |
No, pytype still crashes (meaning our CI would fail) if we make a class Generic over a TypeVarTuple, which is what the solution outlined in #8703 (comment) would require. |
Is that the one that has apparently been fixed a couple of days ago: google/pytype#1525 (comment) |
no |
@AlexWaygood |
Currently, functools.partial's
__call__
method takes*args: Any, **kwargs: Any
and returns_T
(a TypeVar for the return type of the callable the partial is wrapping). This is decent, but matching the parameter typing would make this more useful in more situations.I can sort of see how to deal with this, although I'll admit I'm unsure how to make this generically work. I imagine you could probably deal with some number of
Concatenate
s (maybe up to 5 or 10) to deal with most cases. It's possible fixing this requires another PEP to allow an arbitrary-lengthConcatenate
-type pattern.Related to python/mypy#1484
The text was updated successfully, but these errors were encountered: