Skip to content

Commit cc16b25

Browse files
committed
Revert "Don't use a heuristic for ParamSpec inference from arguments"
This reverts commit 9e768ae.
1 parent 5e02904 commit cc16b25

File tree

2 files changed

+12
-28
lines changed

2 files changed

+12
-28
lines changed

mypy/constraints.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,18 @@ def infer_constraints_for_callable(
228228
if param_spec and callee.arg_kinds[i] in (ARG_STAR, ARG_STAR2):
229229
# If actual arguments are mapped to ParamSpec type, we can't infer individual
230230
# constraints, instead store them and infer single constraint at the end.
231+
# It is impossible to map actual kind to formal kind, so use some heuristic.
232+
# This inference is used as a fallback, so relying on heuristic should be OK.
231233
if not incomplete_star_mapping:
232234
param_spec_arg_types.append(
233235
mapper.expand_actual_type(
234236
actual_arg_type, arg_kinds[actual], None, arg_kinds[actual]
235237
)
236238
)
237-
param_spec_arg_kinds.append(arg_kinds[actual])
239+
actual_kind = arg_kinds[actual]
240+
param_spec_arg_kinds.append(
241+
ARG_POS if actual_kind not in (ARG_STAR, ARG_STAR2) else actual_kind
242+
)
238243
param_spec_arg_names.append(arg_names[actual] if arg_names else None)
239244
else:
240245
actual_type = mapper.expand_actual_type(

test-data/unit/check-parameter-specification.test

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -440,16 +440,13 @@ def f(x: int) -> None: pass
440440
def g(x: int, y: str) -> None: pass
441441

442442
reveal_type(register(lambda: f(1))) # N: Revealed type is "def ()"
443-
reveal_type(register(lambda x: f(x), x=1)) # N: Revealed type is "def (*, x: Literal[1]?)" \
444-
# E: Cannot infer type of lambda
443+
reveal_type(register(lambda x: f(x), x=1)) # N: Revealed type is "def (x: Literal[1]?)"
445444
register(lambda x: f(x)) # E: Cannot infer type of lambda \
446445
# E: Argument 1 to "register" has incompatible type "Callable[[Any], None]"; expected "Callable[[], None]"
447-
register(lambda x: f(x), y=1) # E: Cannot infer type of lambda \
448-
# E: Argument 1 to "register" has incompatible type "Callable[[Any], None]"; expected "Callable[[NamedArg(int, 'y')], None]"
446+
register(lambda x: f(x), y=1) # E: Argument 1 to "register" has incompatible type "Callable[[Arg(int, 'x')], None]"; expected "Callable[[Arg(int, 'y')], None]"
449447
reveal_type(register(lambda x: f(x), 1)) # N: Revealed type is "def (Literal[1]?)"
450448
reveal_type(register(lambda x, y: g(x, y), 1, "a")) # N: Revealed type is "def (Literal[1]?, Literal['a']?)"
451-
reveal_type(register(lambda x, y: g(x, y), 1, y="a")) # N: Revealed type is "def (Literal[1]?, *, y: Literal['a']?)" \
452-
# E: Cannot infer type of lambda
449+
reveal_type(register(lambda x, y: g(x, y), 1, y="a")) # N: Revealed type is "def (Literal[1]?, y: Literal['a']?)"
453450
[builtins fixtures/dict.pyi]
454451

455452
[case testParamSpecInvalidCalls]
@@ -1681,7 +1678,7 @@ class Foo(Generic[P]):
16811678
def test(*args: P.args, **kwargs: P.kwargs) -> Foo[P]: ...
16821679

16831680
reveal_type(test(1, 2)) # N: Revealed type is "__main__.Foo[[Literal[1]?, Literal[2]?]]"
1684-
reveal_type(test(x=1, y=2)) # N: Revealed type is "__main__.Foo[[*, x: Literal[1]?, y: Literal[2]?]]"
1681+
reveal_type(test(x=1, y=2)) # N: Revealed type is "__main__.Foo[[x: Literal[1]?, y: Literal[2]?]]"
16851682
ints = [1, 2, 3]
16861683
reveal_type(test(*ints)) # N: Revealed type is "__main__.Foo[[*builtins.int]]"
16871684
[builtins fixtures/paramspec.pyi]
@@ -1736,7 +1733,7 @@ apply(apply, test2, 42, "yes")
17361733
apply(apply, test2, "no", 42) # E: Argument 1 to "apply" has incompatible type "Callable[[Callable[P, T], **P], None]"; expected "Callable[[Callable[[int, str], None], str, int], None]"
17371734
apply(apply, test2, x=42, y="yes")
17381735
apply(apply, test2, y="yes", x=42)
1739-
apply(apply, test2, y=42, x="no") # E: Argument 1 to "apply" has incompatible type "Callable[[Callable[P, T], **P], None]"; expected "Callable[[Callable[[int, str], None], NamedArg(int, 'y'), NamedArg(str, 'x')], None]"
1736+
apply(apply, test2, y=42, x="no") # E: Argument 1 to "apply" has incompatible type "Callable[[Callable[P, T], **P], None]"; expected "Callable[[Callable[[int, str], None], int, str], None]"
17401737
[builtins fixtures/paramspec.pyi]
17411738

17421739
[case testParamSpecApplyPosVsNamedOptional]
@@ -2161,7 +2158,7 @@ reveal_type(submit( # N: Revealed type is "__main__.Result"
21612158
backend="asyncio",
21622159
))
21632160
submit(
2164-
run, # E: Argument 1 to "submit" has incompatible type "Callable[[Callable[[], R], VarArg(object), DefaultNamedArg(str, 'backend')], R]"; expected "Callable[[Callable[[], Result], NamedArg(int, 'backend')], Result]"
2161+
run, # E: Argument 1 to "submit" has incompatible type "Callable[[Callable[[], R], VarArg(object), DefaultNamedArg(str, 'backend')], R]"; expected "Callable[[Callable[[], Result], int], Result]"
21652162
run_portal,
21662163
backend=int(),
21672164
)
@@ -2537,24 +2534,6 @@ class GenericWrapper(Generic[P]):
25372534
def inherits(*args: P.args, **kwargs: P.kwargs) -> None: ...
25382535
[builtins fixtures/paramspec.pyi]
25392536

2540-
[case testParamSpecInferenceFromArgs]
2541-
from typing_extensions import ParamSpec
2542-
from typing import Any, Callable, Union
2543-
2544-
P = ParamSpec("P")
2545-
2546-
def into(f: Callable[P, None], *args: P.args, **kwargs: P.kwargs) -> None:
2547-
return None
2548-
2549-
class C:
2550-
def f(self, y: bool = False, *, x: int = 42) -> None:
2551-
return None
2552-
2553-
ex: Union[C, Any] = C()
2554-
2555-
into(ex.f, x=-1)
2556-
[builtins fixtures/paramspec.pyi]
2557-
25582537
[case testCallbackProtocolClassObjectParamSpec]
25592538
from typing import Any, Callable, Protocol, Optional, Generic
25602539
from typing_extensions import ParamSpec

0 commit comments

Comments
 (0)