-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incompatible ParamSpecs are not reported as issue #17766
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: