Skip to content

Commit f3c57e5

Browse files
dhalenokMichael0x2a
authored andcommitted
Add new error code for unreachable errors (#8312)
Closes #8190. This introduces a new error code for errors shown when using the `--warn-unreachable` flag, such as the "Statement is unreachable" error.
1 parent 0e8e135 commit f3c57e5

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

docs/source/error_code_list2.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,22 @@ that ``Cat`` falls back to ``Any`` in a type annotation:
174174
# Error: Argument 1 to "feed" becomes "Any" due to an unfollowed import [no-any-unimported]
175175
def feed(cat: Cat) -> None:
176176
...
177+
178+
Check that statement or expression is unreachable [unreachable]
179+
---------------------------------------------------------------
180+
181+
If you use :option:`--warn-unreachable <mypy --warn-unreachable>`, mypy generates an error if it
182+
thinks that a statement or expression will never be executed. In most cases, this is due to
183+
incorrect control flow or conditional checks that are accidentally always true or false.
184+
185+
.. code-block:: python
186+
187+
# mypy: warn-unreachable
188+
189+
def example(x: int) -> None:
190+
# Error: Right operand of 'or' is never evaluated [unreachable]
191+
assert isinstance(x, int) or x == 'unused'
192+
193+
return
194+
# Error: Statement is unreachable [unreachable]
195+
print('unreachable')

mypy/errorcodes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ def __str__(self) -> str:
103103
NO_ANY_RETURN = ErrorCode(
104104
'no-any-return', 'Reject returning value with "Any" type if return type is not "Any"',
105105
'General') # type: Final
106+
UNREACHABLE = ErrorCode(
107+
'unreachable', "Warn about unreachable statements or expressions", 'General') # type: Final
106108

107109
# Syntax errors are often blocking.
108110
SYNTAX = ErrorCode(

mypy/messages.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ def note_call(self,
12351235
context, code=code)
12361236

12371237
def unreachable_statement(self, context: Context) -> None:
1238-
self.fail("Statement is unreachable", context)
1238+
self.fail("Statement is unreachable", context, code=codes.UNREACHABLE)
12391239

12401240
def redundant_left_operand(self, op_name: str, context: Context) -> None:
12411241
"""Indicates that the left operand of a boolean expression is redundant:
@@ -1249,7 +1249,8 @@ def redundant_right_operand(self, op_name: str, context: Context) -> None:
12491249
it does not change the truth value of the entire condition as a whole.
12501250
'op_name' should either be the string "and" or the string "or".
12511251
"""
1252-
self.fail("Right operand of '{}' is never evaluated".format(op_name), context)
1252+
self.fail("Right operand of '{}' is never evaluated".format(op_name),
1253+
context, code=codes.UNREACHABLE)
12531254

12541255
def redundant_condition_in_comprehension(self, truthiness: bool, context: Context) -> None:
12551256
self.redundant_expr("If condition in comprehension", truthiness, context)
@@ -1261,7 +1262,8 @@ def redundant_condition_in_assert(self, truthiness: bool, context: Context) -> N
12611262
self.redundant_expr("Condition in assert", truthiness, context)
12621263

12631264
def redundant_expr(self, description: str, truthiness: bool, context: Context) -> None:
1264-
self.fail("{} is always {}".format(description, str(truthiness).lower()), context)
1265+
self.fail("{} is always {}".format(description, str(truthiness).lower()),
1266+
context, code=codes.UNREACHABLE)
12651267

12661268
def report_protocol_problems(self,
12671269
subtype: Union[Instance, TupleType, TypedDictType],

0 commit comments

Comments
 (0)