From 66499bfb6a1c628c5e1478182605e073a6f24ce4 Mon Sep 17 00:00:00 2001 From: Stas Ilinskiy Date: Mon, 21 Nov 2022 16:39:05 -0600 Subject: [PATCH 1/5] support for unreachable if --- mypy/partially_defined.py | 4 ++++ test-data/unit/check-partially-defined.test | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/mypy/partially_defined.py b/mypy/partially_defined.py index 7d87315c23ad3..2a9f8690bb7a5 100644 --- a/mypy/partially_defined.py +++ b/mypy/partially_defined.py @@ -203,9 +203,13 @@ def visit_if_stmt(self, o: IfStmt) -> None: e.accept(self) self.tracker.start_branch_statement() for b in o.body: + if b.is_unreachable: + continue b.accept(self) self.tracker.next_branch() if o.else_body: + if o.else_body.is_unreachable: + self.tracker.skip_branch() o.else_body.accept(self) self.tracker.end_branch_statement() diff --git a/test-data/unit/check-partially-defined.test b/test-data/unit/check-partially-defined.test index d456568c1131d..f6934fb142d18 100644 --- a/test-data/unit/check-partially-defined.test +++ b/test-data/unit/check-partially-defined.test @@ -367,3 +367,22 @@ def f() -> None: d = a d = b [builtins fixtures/tuple.pyi] + +[case testUnreachable] +# flags: --enable-error-code partially-defined +import typing + +if typing.TYPE_CHECKING: + x = 1 +elif int(): + y = 1 +else: + y = 2 +a = x + +if not typing.TYPE_CHECKING: + pass +else: + z = 1 +a = z +[typing fixtures/typing-medium.pyi] From b864ae3933d5f224edaf1b50d5184bd13c6b8502 Mon Sep 17 00:00:00 2001 From: Stas Ilinskiy Date: Mon, 21 Nov 2022 17:20:20 -0600 Subject: [PATCH 2/5] support for unreachable match --- mypy/partially_defined.py | 4 ++++ test-data/unit/check-python310.test | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/mypy/partially_defined.py b/mypy/partially_defined.py index 2a9f8690bb7a5..6758a5dcb4177 100644 --- a/mypy/partially_defined.py +++ b/mypy/partially_defined.py @@ -217,6 +217,10 @@ def visit_match_stmt(self, o: MatchStmt) -> None: self.tracker.start_branch_statement() o.subject.accept(self) for i in range(len(o.patterns)): + if o.bodies[i].is_unreachable: + self.tracker.skip_branch() + self.tracker.next_branch() + continue pattern = o.patterns[i] pattern.accept(self) guard = o.guards[i] diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 3b90a910e943a..b36440e3d0d8b 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1787,8 +1787,33 @@ def f6(a: object) -> None: match a: case _ if y is not None: # E: Name "y" may be undefined pass + [builtins fixtures/tuple.pyi] +[case testPartiallyDefinedMatchUnreachable] +# flags: --enable-error-code partially-defined +import typing + +def f7(x: int) -> int: + match x: + case 1 if not typing.TYPE_CHECKING: + pass + case 2: + y = 2 + case _: + y = 3 + return y # No error. + +def f8(x: int) -> int: + match x: + case 1 if not typing.TYPE_CHECKING: + pass + case 2: + y = 2 + return y # E: Name "y" may be undefined + +[typing fixtures/typing-medium.pyi] + [case testTypeAliasWithNewUnionSyntaxAndNoneLeftOperand] from typing import overload class C: From 09c3f18f3cc62b65330b71cf2c4d4d925cef8ac2 Mon Sep 17 00:00:00 2001 From: Stas Ilinskiy Date: Mon, 21 Nov 2022 17:22:27 -0600 Subject: [PATCH 3/5] support for unreachable match --- test-data/unit/check-python310.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index b36440e3d0d8b..5a3e50e6a63dd 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1794,7 +1794,7 @@ def f6(a: object) -> None: # flags: --enable-error-code partially-defined import typing -def f7(x: int) -> int: +def f0(x: int) -> int: match x: case 1 if not typing.TYPE_CHECKING: pass @@ -1804,7 +1804,7 @@ def f7(x: int) -> int: y = 3 return y # No error. -def f8(x: int) -> int: +def f1(x: int) -> int: match x: case 1 if not typing.TYPE_CHECKING: pass From ccf8fc9e1cd8f733734ccbaaa5ac15fc5ea3cff6 Mon Sep 17 00:00:00 2001 From: Stas Ilinskiy Date: Mon, 21 Nov 2022 17:44:18 -0600 Subject: [PATCH 4/5] clean up match handling --- mypy/partially_defined.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mypy/partially_defined.py b/mypy/partially_defined.py index 6758a5dcb4177..5854036c0df3f 100644 --- a/mypy/partially_defined.py +++ b/mypy/partially_defined.py @@ -217,16 +217,15 @@ def visit_match_stmt(self, o: MatchStmt) -> None: self.tracker.start_branch_statement() o.subject.accept(self) for i in range(len(o.patterns)): - if o.bodies[i].is_unreachable: - self.tracker.skip_branch() - self.tracker.next_branch() - continue pattern = o.patterns[i] pattern.accept(self) guard = o.guards[i] if guard is not None: guard.accept(self) - o.bodies[i].accept(self) + if not o.bodies[i].is_unreachable: + o.bodies[i].accept(self) + else: + self.tracker.skip_branch() is_catchall = infer_pattern_value(pattern) == ALWAYS_TRUE if not is_catchall: self.tracker.next_branch() From 951924dfc50db552c49a89a44a1cdbd2c4ca9847 Mon Sep 17 00:00:00 2001 From: Stas Ilinskiy Date: Mon, 21 Nov 2022 17:52:41 -0600 Subject: [PATCH 5/5] remove whitespace --- test-data/unit/check-python310.test | 1 - 1 file changed, 1 deletion(-) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 5a3e50e6a63dd..1967e7f4810b1 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1787,7 +1787,6 @@ def f6(a: object) -> None: match a: case _ if y is not None: # E: Name "y" may be undefined pass - [builtins fixtures/tuple.pyi] [case testPartiallyDefinedMatchUnreachable]