-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Cannot infer type argument with TypeVarTuple and Callback protocol #17453
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
Comments
It seems to me you are confusing this with class Job[**P]:
def __init__(self, target: Callable[P, None]) -> None:
self.target = target
def run_job[**P](job: Job[P], *args: P.args, **kwargs: P.kwargs) -> None: ... Btw with the new syntax underscores are not needed, and not recommended. |
@ilevkivskyi, I agree this is a gray area in the typing spec. We should collectively decide whether this is something that should be supported for TypeVarTuples. I managed to support the above code in pyright (inspired in part by your work in mypy), but we may want to ultimately disallow this in the spec. I don't have a strong opinion one way or the other. In the off chance that this is helpful, I'll explain how I implemented this in pyright. I'm not that familiar with mypy's internals, so I don't know if the approach I used in pyright is feasible for you. When pyright records the specialized type arguments for a tuple, it stores not only the type of the type argument but also a flag Code sample in pyright playground from typing import Callable, Protocol
class ActionType(Protocol):
def __call__(self, var: str, context: int = 2) -> None: ...
class Job[*_Ts]:
def __init__(self, target: Callable[[*_Ts], None]) -> None:
self.target = target
def run_job[*_Ts](job: Job[*_Ts], *args: *_Ts) -> None: ...
def a1(action: ActionType) -> None:
job = Job(action)
run_job(job, "Hello") # OK
run_job(job, "Hello", 1) # OK
run_job(job, "Hello", "1") # Type error |
No. I can't use
Strictly speaking, you're correct. However as Eric already pointed out, you implemented something like this for Callables already. The
I'm strongly in favor of keeping the existing support for default arguments. Without that the usefulness of TypeVarTuples for Callable and *args typing would be severely limited. There are quite a few functions (especially in the |
No, I didn't. I know the callables in Python are a mess. I would personally prefer if they were all like class ActionType(Protocol):
def __call__(self, var: str, context: int = ...) -> None: ...
class Job[*Ts]:
attr: tuple[*Ts]
def __init__(self, target: Callable[[*Ts], None]) -> None: ...
action: ActionType
job = Job(action)
reveal_type(job.attr) # What should this be? tuple[str], tuple[str, int], or tuple[str] | tuple[str, int]? Of course this is an artificial example, but it shows how we quickly get into the formal kind vs actual kind confusion again. Btw I did implement ~similar horrible special-casing for |
To Reproduce
Actual Behavior
Expected Behavior
No error. Mypy should be able to tell that
context
has a default value and is thus optional. It already works from pure Callables (without the intermediate generic class).Your Environment
mypy 1.11.0+dev.177c8ee7b8166b3dcf89c034a676ef5818edbc38 (compiled: no)
(current master)--enable-incomplete-feature=NewGenericSyntax
(the bug exists with the old generic syntax as well)3.12
The text was updated successfully, but these errors were encountered: