diff --git a/mypy/checker.py b/mypy/checker.py index dde8a3441c35d..35dd2b246f936 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1995,10 +1995,9 @@ def is_raising_or_empty(self, s: Statement) -> bool: if isinstance(s.expr, EllipsisExpr): return True elif isinstance(s.expr, CallExpr): - self.expr_checker.msg.disable_errors() - typ = get_proper_type(self.expr_checker.accept( - s.expr, allow_none_return=True, always_allow_any=True)) - self.expr_checker.msg.enable_errors() + with self.expr_checker.msg.disable_errors(): + typ = get_proper_type(self.expr_checker.accept( + s.expr, allow_none_return=True, always_allow_any=True)) if isinstance(typ, UninhabitedType): return True @@ -3050,14 +3049,13 @@ def check_member_assignment(self, instance_type: Type, attribute_type: Type, # For non-overloaded setters, the result should be type-checked like a regular assignment. # Hence, we first only try to infer the type by using the rvalue as type context. type_context = rvalue - self.msg.disable_errors() - _, inferred_dunder_set_type = self.expr_checker.check_call( - dunder_set_type, - [TempNode(instance_type, context=context), type_context], - [nodes.ARG_POS, nodes.ARG_POS], - context, object_type=attribute_type, - callable_name=callable_name) - self.msg.enable_errors() + with self.msg.disable_errors(): + _, inferred_dunder_set_type = self.expr_checker.check_call( + dunder_set_type, + [TempNode(instance_type, context=context), type_context], + [nodes.ARG_POS, nodes.ARG_POS], + context, object_type=attribute_type, + callable_name=callable_name) # And now we in fact type check the call, to show errors related to wrong arguments # count, etc., replacing the type context for non-overloaded setters only. diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 3bfe0a306446f..8c8b442b09531 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -865,12 +865,12 @@ def check_union_call_expr(self, e: CallExpr, object_type: UnionType, member: str res = [] # type: List[Type] for typ in object_type.relevant_items(): # Member access errors are already reported when visiting the member expression. - self.msg.disable_errors() - item = analyze_member_access(member, typ, e, False, False, False, - self.msg, original_type=object_type, chk=self.chk, - in_literal_context=self.is_literal_context(), - self_type=typ) - self.msg.enable_errors() + with self.msg.disable_errors(): + item = analyze_member_access(member, typ, e, False, False, False, + self.msg, original_type=object_type, chk=self.chk, + in_literal_context=self.is_literal_context(), + self_type=typ) + narrowed = self.narrow_type_from_binder(e.callee, item, skip_non_overlapping=True) if narrowed is None: continue @@ -1203,12 +1203,9 @@ def infer_function_type_arguments(self, callee_type: CallableType, # due to partial available context information at this time, but # these errors can be safely ignored as the arguments will be # inferred again later. - self.msg.disable_errors() - - arg_types = self.infer_arg_types_in_context( - callee_type, args, arg_kinds, formal_to_actual) - - self.msg.enable_errors() + with self.msg.disable_errors(): + arg_types = self.infer_arg_types_in_context( + callee_type, args, arg_kinds, formal_to_actual) arg_pass_nums = self.get_arg_infer_passes( callee_type.arg_types, formal_to_actual, len(args)) @@ -2816,12 +2813,15 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type: left_map = None if right_map is None: - self.msg.disable_errors() - try: - right_type = self.analyze_cond_branch(right_map, e.right, left_type) - finally: - if right_map is None: - self.msg.enable_errors() + self.msg.disable_errors1() + right_type = self.analyze_cond_branch(map=right_map, + node=e.right, + context=left_type) + self.msg.enable_errors() + else: + right_type = self.analyze_cond_branch(map=right_map, + node=e.right, + context=left_type) if right_map is None: # The boolean expression is statically known to be the left value diff --git a/mypy/messages.py b/mypy/messages.py index 9038660c88246..e2a322ee94700 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -13,8 +13,9 @@ import re import difflib from textwrap import dedent +from contextlib import contextmanager -from typing import cast, List, Dict, Any, Sequence, Iterable, Tuple, Set, Optional, Union +from typing import cast, List, Dict, Any, Sequence, Iterable, Tuple, Set, Optional, Union, Iterator from typing_extensions import Final from mypy.erasetype import erase_type @@ -136,9 +137,17 @@ def add_errors(self, messages: 'MessageBuilder') -> None: for info in errs: self.errors.add_error_info(info) - def disable_errors(self) -> None: + def disable_errors1(self) -> None: self.disable_count += 1 + @contextmanager + def disable_errors(self) -> Iterator[None]: + self.disable_count += 1 + try: + yield + finally: + self.disable_count -= 1 + def enable_errors(self) -> None: self.disable_count -= 1