Skip to content

Commit 150e5b8

Browse files
committed
refactoring
1 parent 6d7ea08 commit 150e5b8

File tree

3 files changed

+42
-39
lines changed

3 files changed

+42
-39
lines changed

mypy/checker.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -641,10 +641,7 @@ def accept_loop(
641641
if iter == 20:
642642
raise RuntimeError("Too many iterations when checking a loop")
643643

644-
for error_info in watcher.yield_error_infos():
645-
self.msg.fail(*error_info[:2], code=error_info[2])
646-
for note_info, context in watcher.yield_note_infos():
647-
self.msg.reveal_type(note_info, context)
644+
self.msg.iteration_dependent_errors(iter_errors)
648645

649646
# If exit_condition is set, assume it must be False on exit from the loop:
650647
if exit_condition:
@@ -4984,11 +4981,7 @@ def visit_try_stmt(self, s: TryStmt) -> None:
49844981
if not self.binder.is_unreachable():
49854982
with IterationErrorWatcher(self.msg.errors, iter_errors) as watcher:
49864983
self.accept(s.finally_body)
4987-
4988-
for error_info in watcher.yield_error_infos():
4989-
self.msg.fail(*error_info[:2], code=error_info[2])
4990-
for note_info, context in watcher.yield_note_infos():
4991-
self.msg.reveal_type(note_info, context)
4984+
self.msg.iteration_dependent_errors(iter_errors)
49924985

49934986
def visit_try_without_finally(self, s: TryStmt, try_frame: bool) -> None:
49944987
"""Type check a try statement, ignoring the finally block.

mypy/errors.py

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,33 @@ def __init__(self) -> None:
255255
self.revealed_types = defaultdict(list)
256256

257257

258+
def yield_uselessness_error_infos(self) -> Iterator[tuple[str, Context, ErrorCode]]:
259+
"""Report only those `unreachable`, `redundant-expr`, and `redundant-casts`
260+
errors that could not be ruled out in any iteration step."""
261+
262+
persistent_uselessness_errors = set()
263+
for candidate in set(chain(*self.uselessness_errors)):
264+
if all(
265+
(candidate in errors) or (candidate[2] in lines)
266+
for errors, lines in zip(self.uselessness_errors, self.unreachable_lines)
267+
):
268+
persistent_uselessness_errors.add(candidate)
269+
for error_info in persistent_uselessness_errors:
270+
context = Context(line=error_info[2], column=error_info[3])
271+
context.end_line = error_info[4]
272+
context.end_column = error_info[5]
273+
yield error_info[1], context, error_info[0]
274+
275+
def yield_revealed_type_infos(self) -> Iterator[tuple[Type, Context]]:
276+
"""Yield all types revealed in at least one iteration step."""
277+
278+
for note_info, types in self.revealed_types.items():
279+
context = Context(line=note_info[0], column=note_info[1])
280+
context.end_line = note_info[2]
281+
context.end_column = note_info[3]
282+
yield make_simplified_union(types), context
283+
284+
258285
class IterationErrorWatcher(ErrorWatcher):
259286
"""Error watcher that filters and separately collects `unreachable` errors,
260287
`redundant-expr` and `redundant-casts` errors, and revealed types when analysing
@@ -297,35 +324,6 @@ def on_error(self, file: str, info: ErrorInfo) -> bool:
297324

298325
return super().on_error(file, info)
299326

300-
def yield_error_infos(self) -> Iterator[tuple[str, Context, ErrorCode]]:
301-
"""Report only those `unreachable`, `redundant-expr`, and `redundant-casts`
302-
errors that could not be ruled out in any iteration step."""
303-
304-
persistent_uselessness_errors = set()
305-
iter_errors = self.iteration_dependent_errors
306-
for candidate in set(chain(*iter_errors.uselessness_errors)):
307-
if all(
308-
(candidate in errors) or (candidate[2] in lines)
309-
for errors, lines in zip(
310-
iter_errors.uselessness_errors, iter_errors.unreachable_lines
311-
)
312-
):
313-
persistent_uselessness_errors.add(candidate)
314-
for error_info in persistent_uselessness_errors:
315-
context = Context(line=error_info[2], column=error_info[3])
316-
context.end_line = error_info[4]
317-
context.end_column = error_info[5]
318-
yield error_info[1], context, error_info[0]
319-
320-
def yield_note_infos(self) -> Iterator[tuple[Type, Context]]:
321-
"""Yield all types revealed in at least one iteration step."""
322-
323-
for note_info, types in self.iteration_dependent_errors.revealed_types.items():
324-
context = Context(line=note_info[0], column=note_info[1])
325-
context.end_line = note_info[2]
326-
context.end_column = note_info[3]
327-
yield make_simplified_union(types), context
328-
329327

330328
class Errors:
331329
"""Container for compile errors.

mypy/messages.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@
2323
from mypy import errorcodes as codes, message_registry
2424
from mypy.erasetype import erase_type
2525
from mypy.errorcodes import ErrorCode
26-
from mypy.errors import ErrorInfo, Errors, ErrorWatcher, IterationErrorWatcher
26+
from mypy.errors import (
27+
ErrorInfo,
28+
Errors,
29+
ErrorWatcher,
30+
IterationDependentErrors,
31+
IterationErrorWatcher,
32+
)
2733
from mypy.nodes import (
2834
ARG_NAMED,
2935
ARG_NAMED_OPT,
@@ -2501,6 +2507,12 @@ def match_statement_inexhaustive_match(self, typ: Type, context: Context) -> Non
25012507
code=codes.EXHAUSTIVE_MATCH,
25022508
)
25032509

2510+
def iteration_dependent_errors(self, iter_errors: IterationDependentErrors) -> None:
2511+
for error_info in iter_errors.yield_uselessness_error_infos():
2512+
self.fail(*error_info[:2], code=error_info[2])
2513+
for note_info, context in iter_errors.yield_revealed_type_infos():
2514+
self.reveal_type(note_info, context)
2515+
25042516

25052517
def quote_type_string(type_string: str) -> str:
25062518
"""Quotes a type representation for use in messages."""

0 commit comments

Comments
 (0)