Skip to content

Commit 05dbf01

Browse files
committed
Honor NoReturn as __setitem__ return type to mark unreachable code.
1 parent 74df7fb commit 05dbf01

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

mypy/checker.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3423,9 +3423,11 @@ def check_indexed_assignment(self, lvalue: IndexExpr,
34233423
'__setitem__', basetype, lvalue)
34243424

34253425
lvalue.method_type = method_type
3426-
self.expr_checker.check_method_call(
3426+
res_type, _ = self.expr_checker.check_method_call(
34273427
'__setitem__', basetype, method_type, [lvalue.index, rvalue],
34283428
[nodes.ARG_POS, nodes.ARG_POS], context)
3429+
if isinstance(get_proper_type(res_type), UninhabitedType):
3430+
self.binder.unreachable()
34293431

34303432
def try_infer_partial_type_from_indexed_assignment(
34313433
self, lvalue: IndexExpr, rvalue: Expression) -> None:

test-data/unit/check-unreachable-code.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,3 +1448,13 @@ a or a # E: Right operand of "or" is never evaluated
14481448
1 and a and 1 # E: Right operand of "and" is never evaluated
14491449
a and a # E: Right operand of "and" is never evaluated
14501450
[builtins fixtures/exception.pyi]
1451+
1452+
[case testSetitemNoReturn]
1453+
# flags: --warn-unreachable
1454+
from typing import NoReturn
1455+
class Foo:
1456+
def __setitem__(self, key: str, value: str) -> NoReturn:
1457+
raise Exception
1458+
Foo()['a'] = 'a'
1459+
x = 0 # E: Statement is unreachable
1460+
[builtins fixtures/exception.pyi]

0 commit comments

Comments
 (0)