Closed bukzor closed 1 month ago
Thanks for the bug report. This will be addressed in the next release.
I dug into this and found that it seems to be a bug in typeshed, rather -- lru_cache wrapper uses ...
as the paramspec which means pyright loses the overload information. pyright
and mypy
give exactly matching results for the below program.
What did you find?
from typing import Callable, ParamSpec, TypeVar, assert_type, overload
P = ParamSpec("P")
T = TypeVar("T")
def cached_broken(f: Callable[..., T]) -> Callable[..., T]: return f
def cached_worken(f: Callable[P, T]) -> Callable[P, T]: return f
@overload
def g(x: float) -> complex: ...
@overload
def g(x: str) -> None: ...
def g(x: float | str) -> complex | None:
del x
return None
cg = cached_broken(g)
assert_type(cg(1.2), complex)
assert_type(cg("1.2"), complex)
cg = cached_worken(g)
assert_type(cg(1.2), complex)
assert_type(cg("1.2"), None)
This is addressed in pyright 1.1.376.
This is a simplified version of what's seen in stdlib
urllib.parse
.Code sample in pyright playground
As written, currently, this assert_type fails, but removing the lru_cache removes the error.