Skip to content

Commit 129f1cb

Browse files
committed
consider redundant-casts, too
test case from @auntsaninja (slightly simplified)
1 parent 15f5740 commit 129f1cb

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

mypy/checker.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,8 @@ def accept_loop(
600600
# on without bound otherwise)
601601
widened_old = len(self.widened_vars)
602602

603-
# one set of `unreachable` and `redundant-expr`errors per iteration step:
603+
# one set of `unreachable`, `redundant-expr`, and `redundant-casts` errors
604+
# per iteration step:
604605
uselessness_errors = []
605606
# one set of unreachable line numbers per iteration step:
606607
unreachable_lines = []
@@ -640,8 +641,8 @@ def accept_loop(
640641
if iter == 20:
641642
raise RuntimeError("Too many iterations when checking a loop")
642643

643-
# Report only those `unreachable` and `redundant-expr` errors that could not
644-
# be ruled out in any iteration step:
644+
# Report only those `unreachable`, `redundant-expr`, and `redundant-casts`
645+
# errors that could not be ruled out in any iteration step:
645646
persistent_uselessness_errors = set()
646647
for candidate in set(itertools.chain(*uselessness_errors)):
647648
if all(

mypy/errors.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ def filtered_errors(self) -> list[ErrorInfo]:
222222

223223
class LoopErrorWatcher(ErrorWatcher):
224224
"""Error watcher that filters and separately collects `unreachable` errors,
225-
`redundant-expr` errors, and revealed types when analysing loops iteratively
226-
to help avoid making too-hasty reports."""
225+
`redundant-expr` and `redundant-casts` errors, and revealed types when analysing
226+
loops iteratively to help avoid making too-hasty reports."""
227227

228228
# Meaning of the tuple items: ErrorCode, message, line, column, end_line, end_column:
229229
uselessness_errors: set[tuple[ErrorCode, str, int, int, int, int]]
@@ -254,7 +254,7 @@ def __init__(
254254

255255
def on_error(self, file: str, info: ErrorInfo) -> bool:
256256

257-
if info.code in (codes.UNREACHABLE, codes.REDUNDANT_EXPR):
257+
if info.code in (codes.UNREACHABLE, codes.REDUNDANT_EXPR, codes.REDUNDANT_CAST):
258258
self.uselessness_errors.add(
259259
(info.code, info.message, info.line, info.column, info.end_line, info.end_column)
260260
)

test-data/unit/check-narrowing.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2382,6 +2382,28 @@ while True:
23822382

23832383
[builtins fixtures/bool.pyi]
23842384

2385+
[case testAvoidFalseRedundantCastInLoops]
2386+
# flags: --warn-redundant-casts
2387+
2388+
from typing import Callable, cast, Union
2389+
2390+
ProcessorReturnValue = Union[str, int]
2391+
Processor = Callable[[str], ProcessorReturnValue]
2392+
2393+
def main_cast(p: Processor) -> None:
2394+
ed: ProcessorReturnValue
2395+
ed = cast(str, ...)
2396+
while True:
2397+
ed = p(cast(str, ed))
2398+
2399+
def main_no_cast(p: Processor) -> None:
2400+
ed: ProcessorReturnValue
2401+
ed = cast(str, ...)
2402+
while True:
2403+
ed = p(ed) # E: Argument 1 has incompatible type "Union[str, int]"; expected "str"
2404+
2405+
[builtins fixtures/bool.pyi]
2406+
23852407
[case testAvoidFalseUnreachableInLoop1]
23862408
# flags: --warn-unreachable --python-version 3.11
23872409

0 commit comments

Comments
 (0)