You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mypy doesn't take value restrictions into account when solving type variables #11880
fromtypingimportAny, TypeVar, UnionT=TypeVar("T")
V=TypeVar("V", str, bytes)
defcheck_t(x: T|list[T]) ->T: ...
defcheck_v(x: V|list[V]) ->V: ...
x_str: strx_list_any: list[Any]
x_str_list_any: str|list[Any]
# mypy does the correct thing herereveal_type(check_t(x_str)) # strreveal_type(check_t(x_list_any)) # list[Any] | Anyreveal_type(check_t(x_str_list_any)) # str | list[Any] | Anyreveal_type(check_v(x_str)) # str# but maybe not here# E: Value of type variable "V" of "check_v" cannot be "Union[List[Any], Any]"# N: Revealed type is "Union[builtins.list[Any], Any]"reveal_type(check_v(x_list_any))
# E: Value of type variable "V" of "check_v" cannot be "Union[str, List[Any], Any]"# N: Revealed type is "Union[builtins.str, builtins.list[Any], Any]"reveal_type(check_v(x_str_list_any))
Looking at the output, my guess is that mypy isn't taking value restrictions into account when solving constraints and only using value restriction as a check later. That is, list[Any] cannot match the T part of T | list[T] because it would violate the value restriction.
Reacted by Martin Fischer, SpaghettDev, Alex Waygood and Arseniy Terekhin
Playing around with the following as a potential fix, but I think there are some other issues with how mypy handles this kind of thing.
diff --git a/mypy/constraints.py b/mypy/constraints.py
index 5a78cdb94..9ca16bcaf 100644
--- a/mypy/constraints.py
+++ b/mypy/constraints.py
@@ -199,6 +199,12 @@ def infer_constraints_if_possible(template: Type, actual: Type,
# This is not caught by the above branch because of the erase_typevars() call,
# that would return 'Any' for a type variable.
return None
+ if (
+ isinstance(template, TypeVarType) and
+ template.values and
+ all(not mypy.subtypes.is_equivalent(actual, erase_typevars(t)) for t in template.values)
+ ):
+ return None
return infer_constraints(template, actual, direction)
Activity
hauntsaninja commentedon Jan 1, 2022
Playing around with the following as a potential fix, but I think there are some other issues with how mypy handles this kind of thing.
JelleZijlstra commentedon Jan 9, 2022
#3644 is a similar issue with
T | Cls[T].