From 0857a9fe4185caddc31a1ca0088a34871ac434ee Mon Sep 17 00:00:00 2001 From: Shen Yi Hong Date: Thu, 7 Nov 2024 16:40:24 +0800 Subject: [PATCH 1/2] fix: modify `current_type` if not uninhabited --- mypy/checkpattern.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index 6b4fa35f9c490..4323daa68025f 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -158,7 +158,8 @@ def visit_or_pattern(self, o: OrPattern) -> PatternType: for pattern in o.patterns: pattern_type = self.accept(pattern, current_type) pattern_types.append(pattern_type) - current_type = pattern_type.rest_type + if not is_uninhabited(pattern_type.type): + current_type = pattern_type.rest_type # # Collect the final type From ff90fbbc5f17134b3d305fc95cc627aa54287b90 Mon Sep 17 00:00:00 2001 From: Shen Yi Hong Date: Sun, 10 Nov 2024 17:27:41 +0800 Subject: [PATCH 2/2] test: add unit test `testMatchOrPatternMatchExhaustivenes` --- test-data/unit/check-python310.test | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 58b70d7b74d85..3ef964d3c0b99 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1702,6 +1702,22 @@ def f(x: int | str) -> int: case str() as s: return 1 +[case testMatchOrPatternExhaustiveness] +from typing import NoReturn, Literal +def assert_never(x: NoReturn) -> None: ... + +Color = Literal["blue", "green", "red"] +c: Color + +match c: + case "blue": + reveal_type(c) # N: Revealed type is "Literal['blue']" + case "green" | "notColor": + reveal_type(c) # N: Revealed type is "Literal['green']" + case _: + assert_never(c) # E: Argument 1 to "assert_never" has incompatible type "Literal['red']"; expected "Never" +[typing fixtures/typing-typeddict.pyi] + [case testMatchAsPatternIntersection-skip] class A: pass class B: pass