diff --git a/mypy/constraints.py b/mypy/constraints.py index fe3c1a19ff18..0dd748ff85e1 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -420,8 +420,12 @@ def filter_satisfiable(option: list[Constraint] | None) -> list[Constraint] | No return option satisfiable = [] for c in option: - # TODO: add similar logic for TypeVar values (also in various other places)? - if mypy.subtypes.is_subtype(c.target, c.origin_type_var.upper_bound): + if isinstance(c.origin_type_var, TypeVarType) and c.origin_type_var.values: + if any( + mypy.subtypes.is_subtype(c.target, value) for value in c.origin_type_var.values + ): + satisfiable.append(c) + elif mypy.subtypes.is_subtype(c.target, c.origin_type_var.upper_bound): satisfiable.append(c) if not satisfiable: return None diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test index a561c29e54f7..4c4fbc32ec3f 100644 --- a/test-data/unit/check-unions.test +++ b/test-data/unit/check-unions.test @@ -1171,6 +1171,25 @@ def foo( foo([1]) [builtins fixtures/list.pyi] +[case testGenericUnionMemberWithTypeVarConstraints] + +from typing import Generic, TypeVar, Union + +T = TypeVar('T', str, int) + +class C(Generic[T]): ... + +def f(s: Union[T, C[T]]) -> T: ... + +ci: C[int] +cs: C[str] + +reveal_type(f(1)) # N: Revealed type is "builtins.int" +reveal_type(f('')) # N: Revealed type is "builtins.str" +reveal_type(f(ci)) # N: Revealed type is "builtins.int" +reveal_type(f(cs)) # N: Revealed type is "builtins.str" + + [case testNestedInstanceTypeAliasUnsimplifiedUnion] from typing import TypeVar, Union, Iterator, List, Any T = TypeVar("T")