-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Incompatible ParamSpecs are not reported as issue #17766
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
I'm not sure what the right course of action is here. First of all, P in the snippet can be satisfied by def foo(cb1: Callable[P, None], cb2: Callable[P, None]) -> Callable[P, None]:
pass
def my_callback_1(x: int) -> None:
pass
def my_callback_2(x: str) -> None:
pass
reveal_type(foo(my_callback_1, my_callback_2)) # N: Revealed type is "def (x: Never)"
However, such functions are of rather limited use ( Current spec does not explicitly define incompatible ParamSpec caused by one or more args with constraints satisfied only by bottom type:
# Quoted from typing spec
P = ParamSpec("P")
def foo(x: Callable[P, int], y: Callable[P, int]) -> Callable[P, bool]: ...
def x_y(x: int, y: str) -> int: ...
def y_x(y: int, x: str) -> int: ...
foo(x_y, x_y) # Should return (x: int, y: str) -> bool
# (a callable with two positional-or-keyword parameters)
foo(x_y, y_x) # Could return (a: int, b: str, /) -> bool
# (a callable with two positional-only parameters)
# This works because both callables have types that are
# behavioral subtypes of Callable[[int, str], int]
def keyword_only_x(*, x: int) -> int: ...
def keyword_only_y(*, y: int) -> int: ...
foo(keyword_only_x, keyword_only_y) # Rejected There's nothing technically challenging in changing this behaviour: diff --git a/mypy/applytype.py b/mypy/applytype.py
index e87bf939c..e443f98db 100644
--- a/mypy/applytype.py
+++ b/mypy/applytype.py
@@ -43,6 +43,10 @@ def get_target_type(
if isinstance(p_type, UninhabitedType) and tvar.has_default():
return tvar.default
if isinstance(tvar, ParamSpecType):
+ if isinstance(p_type, Parameters) and any(isinstance(get_proper_type(p), UninhabitedType) for p in p_type.arg_types):
+ if skip_unsatisfied:
+ return None
+ report_incompatible_typevar_value(callable, type, tvar.name, context)
return type
if isinstance(tvar, TypeVarTupleType):
return type |
Bug Report
Hey everyone, thanks for all the great work on mypy!
I ran into an issue where mypy does not warn if 2 ParamSpecs need to align but they don't. Hard to describe, so here's an example:
To Reproduce
Playground link: https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=f2fac01dde7a953c5dec5117428350f6
Expected Behavior
I think mypy should error out on the
foo()
call since it's not possible to resolve both Callables to a common ParamSpecP
.When I put the same code into VSCode, pylance reports the following error:
Actual Behavior
mypy does not report any issues:
Your Environment
See the playground link above, but when I run into this locally, I have:
mypy 1.11.2 (compiled: yes)
--strict
mypy.ini
(and other config files):None
Python 3.12.2
The text was updated successfully, but these errors were encountered: