Open supersergiy opened 1 year ago
Bug Report Concatenate-ing a TypeVar in return type of a decorator results in the first constraint being selected.
Concatenate
TypeVar
To Reproduce
from __future__ import annotations from typing import Any, Callable, TypeVar, Union from typing_extensions import Concatenate, ParamSpec T = TypeVar("T", int, dict) P = ParamSpec("P") def accepts_mapping( func: Callable[P, Any] ) -> Callable[Concatenate[T, P], T]: def wrapper(data: T, *args: P.args, **kwargs: P.kwargs) -> T: if isinstance(data, dict): return {} else: return 1 return wrapper @accepts_mapping def fn(): return reveal_type(fn) # main.py:26: note: Revealed type is "def (builtins.dict[Any, builtins.int]) -> builtins.dict[Any, builtins.int]" mapping_res = fn({"a": 1}) # main.py:28: error: Argument 1 to "fn" has incompatible type "dict[str, int]"; expected "int" [arg-type]
[playground link]
Expected Behavior
Decorated function should accept either dict or int. pyright works as expected -- [pyright playground link]
Same example works as expected without Concatenate:
from __future__ import annotations from typing import Any, Callable, TypeVar, Union from typing_extensions import Concatenate, ParamSpec T = TypeVar("T", int, dict) P = ParamSpec("P") def accepts_mapping( func: Callable[[], Any] ) -> Callable[[T], T]: def wrapper(data: T, *args: P.args, **kwargs: P.kwargs) -> T: if isinstance(data, dict): return {} else: return 1 return wrapper @accepts_mapping def fn(): return reveal_type(fn) # main.py:26: note: Revealed type is "def [T in (builtins.int, builtins.dict[Any, Any])] (T`-1) -> T`-1" mapping_res = fn({"a": 1})
Your Environment
Mypy playground, tested with master and 1.5.1
master
1.5.1
This seems to work as expected on master now: https://mypy-play.net/?mypy=master&python=3.11&gist=c3b411fa0131d9d88de54eb24026e964&flags=strict
Bug Report
Concatenate
-ing aTypeVar
in return type of a decorator results in the first constraint being selected.To Reproduce
[playground link]
Expected Behavior
Decorated function should accept either dict or int. pyright works as expected -- [pyright playground link]
Same example works as expected without
Concatenate
:Your Environment
Mypy playground, tested with
master
and1.5.1