Skip to content

Commit 89d911c

Browse files
committed
Avoid annoying redundant_expr warnings for exhaustiveness checks.
1 parent f59720d commit 89d911c

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

mypy/checker.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5042,6 +5042,41 @@ def visit_if_stmt(self, s: IfStmt) -> None:
50425042
if s.else_body:
50435043
self.accept(s.else_body)
50445044

5045+
def _visit_if_stmt_redundant_expr_helper(
5046+
self, stmt: IfStmt, expr: Expression, body: Body, if_map, else_map
5047+
) -> None:
5048+
5049+
if codes.REDUNDANT_EXPR not in self.options.enabled_error_codes:
5050+
return
5051+
if refers_to_fullname(
5052+
expr, ("typing.TYPE_CHECKING", "typing_extensions.TYPE_CHECKING")
5053+
):
5054+
return
5055+
5056+
if if_map is None:
5057+
if stmt.while_stmt:
5058+
self.msg.redundant_condition_in_while(expr)
5059+
else:
5060+
self.msg.redundant_condition_in_if(False, expr)
5061+
5062+
if else_map is None and not stmt.while_stmt:
5063+
if isinstance(body.body[0], ReturnStmt):
5064+
return
5065+
if (else_body := stmt.else_body) is not None:
5066+
s = else_body.body[0]
5067+
if isinstance(s, AssertStmt) and is_false_literal(s.expr):
5068+
return
5069+
if isinstance(s, RaiseStmt):
5070+
return
5071+
elif isinstance(s.expr, CallExpr):
5072+
with self.expr_checker.msg.filter_errors(filter_revealed_type=True):
5073+
typ = self.expr_checker.accept(
5074+
s.expr, allow_none_return=True, always_allow_any=True
5075+
)
5076+
if isinstance(get_proper_type(typ), UninhabitedType):
5077+
return
5078+
self.msg.redundant_condition_in_if(True, expr)
5079+
50455080
def visit_while_stmt(self, s: WhileStmt) -> None:
50465081
"""Type check a while statement."""
50475082
if_stmt = IfStmt([s.expr], [s.body], None, while_stmt=True)

test-data/unit/check-isinstance.test

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,3 +3079,48 @@ while False: # E: While condition is always false
30793079
...
30803080

30813081
[builtins fixtures/bool.pyi]
3082+
3083+
[case testNoRedundantExpressionWarningsForExhaustivenessChecks]
3084+
# flags: --enable-error-code=redundant-expr
3085+
from typing import Literal, Never, NoReturn
3086+
3087+
def assert_never(x: Never) -> NoReturn:
3088+
...
3089+
def f1(x: Literal[1, 2]) -> str:
3090+
if x == 1:
3091+
y = "a"
3092+
elif x == 2:
3093+
y = "b"
3094+
else:
3095+
assert_never(x)
3096+
return y
3097+
3098+
class ValueError: ...
3099+
def f2(x: Literal[1]) -> str:
3100+
if x == 1:
3101+
y = "a"
3102+
else:
3103+
raise ValueError
3104+
return y
3105+
3106+
def f3(x: Literal[1]) -> str:
3107+
if x == 1:
3108+
y = "a"
3109+
else:
3110+
assert False
3111+
return y
3112+
3113+
def f4(x: Literal[1, 2]) -> int:
3114+
if x == 1:
3115+
return 1
3116+
if x == 2:
3117+
return 2
3118+
3119+
def f5(x: Literal[1, 2]) -> str:
3120+
if x == 1:
3121+
y = "a"
3122+
elif x == 2: # E: If condition is always true
3123+
y = "b"
3124+
return y
3125+
3126+
[builtins fixtures/bool.pyi]

0 commit comments

Comments
 (0)