Description
Bug Report
Using a decorator including a ParamSpec
variable on a function declaring multiple parameters from a generic protocol swaps any protocol argument to Never
(pheuh, having a bit of trouble phrasing this decently..)
To Reproduce
I drilled down an issue in our code base, when running with 1.7.0
, to the following script. This passes fine with 1.6.1
. It might probably be reduced further.
While I was at it I ran git bisect with the script below and ended up at 93d4cb0 (#16345) (CC @ilevkivskyi).
I see that there's a flag to run with the old type inference to resolve things for now.
from collections.abc import Callable
from typing import Concatenate, ParamSpec, Protocol, TypeVar
T = TypeVar("T")
P = ParamSpec("P")
V_co = TypeVar("V_co", covariant=True)
class Metric(Protocol[V_co]):
def __call__(self) -> V_co:
...
def simple_metric(func: Callable[Concatenate[int, P], T]) -> Callable[P, T]:
def inner(*args: P.args, **kwargs: P.kwargs) -> T:
return func(*args, **kwargs)
return inner
@simple_metric
def Negate(count: int, /, metric: Metric[float]) -> float:
return metric() * -1
@simple_metric
def Combine(count: int, m1: Metric[T], m2: Metric[T], /, *more: Metric[T]) -> T:
return m1()
reveal_type(simple_metric)
reveal_type(Negate)
reveal_type(Combine)
def m1() -> float:
return 0.0
def m2() -> float:
return 1.0
reveal_type(Combine(m1, m2))
Expected Behavior
There should be no Never
populated as generic argument and script should pass.
Actual Behavior
Some strategic reveals in the script but the 2 errors it spits back are:
main.py:41: error: Argument 1 to "Combine" has incompatible type "Callable[[], float]"; expected "Metric[Never]" [arg-type]
main.py:41: error: Argument 2 to "Combine" has incompatible type "Callable[[], float]"; expected "Metric[Never]" [arg-type]
Found 2 errors in 1 file (checked 1 source file)
What's interesting is that if I only keep 1 Metric[T]
argument e.g.
@simple_metric
def Combine(count: int, m1: Metric[T], /) -> T:
return m1()
It seems to get things right.
Your Environment
- Mypy version used:
1.7.0
(alsomaster
) - Mypy command-line flags: -
- Mypy configuration options from
mypy.ini
(and other config files): - - Python version used: Python3.11