diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index a23be464b825..65bbbe2c824b 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -244,6 +244,27 @@ def visit_sequence_pattern(self, o: SequencePattern) -> PatternType: # get inner types of original type # unpack_index = None + + if isinstance(current_type, UnionType): + union_captures: dict[Expression, Type] = {} + union_items: list[Type] = [] + for t in current_type.items: + typ, _, capture = self.accept(o, t) + if not is_uninhabited(get_proper_type(typ)): + union_items.append(typ) + union_captures.update(capture) + + rest_items: list[Type] = [] + for item in current_type.items: + if all(used_item != item for used_item in union_items): + rest_items.append(item) + + return PatternType( + type=UnionType.make_union(items=union_items), + rest_type=UnionType.make_union(items=rest_items), + captures=union_captures, + ) + if isinstance(current_type, TupleType): inner_types = current_type.items unpack_index = find_unpack_in_list(inner_types) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 5ecc69dc7c32..c4e777a79a52 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1777,12 +1777,11 @@ match foo: [case testMatchUnionTwoTuplesNoCrash] var: tuple[int, int] | tuple[str, str] -# TODO: we can infer better here. match var: case (42, a): - reveal_type(a) # N: Revealed type is "Union[builtins.int, builtins.str]" + reveal_type(a) # N: Revealed type is "builtins.int" case ("yes", b): - reveal_type(b) # N: Revealed type is "Union[builtins.int, builtins.str]" + reveal_type(b) # N: Revealed type is "builtins.str" [builtins fixtures/tuple.pyi] [case testMatchNamedAndKeywordsAreTheSame]