-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
When specifying a TypeVar to be a Callable, or union of Callables, ParamSpec cannot be used to indicate parameter types #14777
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.
8000By 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
The bounds of a TypeVar are not allowed to be generic, so they cannot include TypeVars, TypeVarTuples, or ParamSpecs. Mypy's error message could perhaps be clearer in this case. |
The motivating problem behind the bug report looks like this:
Obviously this is a trivial example, but the structure is real and is taken from our codebase. This Bug report is notthe only problem MyPy has with this code at the moment. But I hope you'd agree this is more specific (and useful, to a sufficiently powerful static analyser) than omitting |
Fixes #14832, fixes #13966, fixes #14622. Still does not report error in #14777, I'll work separately on that. Move all `ParamSpec` validity checking to `typeanal.py`. Stop treating `P.args` and `P.kwargs` as binding - only bare typevar makes it available in scope. Reject keyword arguments following `P.args`. This also makes one more conformance test pass.
This is still wrong - there is no way to "carry on" some type variables bound to another TypeVar. HKTs do not exist in python (yet?). This Yes, typing a decorator that supports both sync and async interfaces is challenging (impossible to achieve without ignore/cast AFAIC). You can't unwrap import time
import asyncio
import functools
from typing import Any, Awaitable, Callable, ParamSpec, Protocol, TypeVar, cast
P = ParamSpec('P')
R = TypeVar('R')
class Retrier(Protocol):
def __call__(self, fn: Callable[P, R], /) -> Callable[P, R]: ...
def retry_forever() -> Retrier:
def __decorator(f: Callable[P, R]) -> Callable[P, R]:
if asyncio.iscoroutinefunction(f):
@functools.wraps(f)
async def __ainner(*args: P.args, **kwargs: P.kwargs) -> R:
while True:
try:
return await cast("Callable[P, Awaitable[R]]", f)(*args, **kwargs)
except Exception:
await asyncio.sleep(1)
return cast("Callable[P, R]", __ainner)
else:
@functools.wraps(f)
def __inner(*args: P.args, **kwargs: P.kwargs) -> R:
while True:
try:
return f(*args, **kwargs)
except Exception:
time.sleep(1)
return __inner
return __decorator But this isn't a |
Bug Report
The declarations of
F
,G
andH
all result in the following error:The first argument to Callable must be a list of types, parameter specification, or "..." [valid-type]
Despite the first argument to the callable being a parameter specification.
To Reproduce
https://mypy-play.net/?mypy=latest&python=3.11&gist=191e47b4afd74e307a3042dfedac77d4
Expected Behavior
Either these should pass type checking, or the error message should be updated to indicate what the problem actually is.
Your Environment
The text was updated successfully, but these errors were encountered: