From 57f83ea29a52a2fcf4e754dd561790240e4bd7ab Mon Sep 17 00:00:00 2001 From: "dixith@hotmail.com" <7497698+dixith@users.noreply.github.com> Date: Sat, 27 Mar 2021 20:05:16 +0530 Subject: [PATCH 1/6] Use context managers for disable_errors() --- mypy/checker.py | 22 ++++++++++------------ mypy/checkexpr.py | 37 +++++++++++++++++++------------------ mypy/messages.py | 8 ++++++-- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index fce7e7d7a08e2..b520d977dd66b 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1992,10 +1992,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 @@ -3047,14 +3046,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 cbfa5dbc0b4e0..e082a107dd3a2 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -864,12 +864,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 @@ -1202,12 +1202,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)) @@ -2809,12 +2806,16 @@ 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() + with self.msg.disable_errors(): + try: + right_type = self.analyze_cond_branch(right_map, e.right, left_type) + finally: + pass + else: + try: + right_type = self.analyze_cond_branch(right_map, e.right, left_type) + finally: + pass 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 cd0b491768a9d..7de95eac82e8f 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,8 +137,11 @@ def add_errors(self, messages: 'MessageBuilder') -> None: for info in errs: self.errors.add_error_info(info) - def disable_errors(self) -> None: + @contextmanager + def disable_errors(self) -> Iterator[None]: self.disable_count += 1 + yield + self.disable_count -= 1 def enable_errors(self) -> None: self.disable_count -= 1 From 52db50ae9d4163233f72cdaee9709d9316241772 Mon Sep 17 00:00:00 2001 From: "dixith@hotmail.com" <7497698+dixith@users.noreply.github.com> Date: Sat, 27 Mar 2021 20:35:32 +0530 Subject: [PATCH 2/6] Remove unused function enable_errors() --- mypy/messages.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 7de95eac82e8f..83f97be6f9f05 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -143,9 +143,6 @@ def disable_errors(self) -> Iterator[None]: yield self.disable_count -= 1 - def enable_errors(self) -> None: - self.disable_count -= 1 - def is_errors(self) -> bool: return self.errors.is_errors() From 8860575a2134d87d890119015a9ead172f7fdfb1 Mon Sep 17 00:00:00 2001 From: "dixith@hotmail.com" <7497698+dixith@users.noreply.github.com> Date: Sat, 27 Mar 2021 20:57:06 +0530 Subject: [PATCH 3/6] Change to make sure cleanup always happens by using try-finally --- mypy/messages.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 83f97be6f9f05..0148f3de5137e 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -140,8 +140,10 @@ def add_errors(self, messages: 'MessageBuilder') -> None: @contextmanager def disable_errors(self) -> Iterator[None]: self.disable_count += 1 - yield - self.disable_count -= 1 + try: + yield + finally: + self.disable_count -= 1 def is_errors(self) -> bool: return self.errors.is_errors() From c62147d9924569265c7068a197c67d277f190345 Mon Sep 17 00:00:00 2001 From: "dixith@hotmail.com" <7497698+dixith@users.noreply.github.com> Date: Sun, 28 Mar 2021 00:27:52 +0530 Subject: [PATCH 4/6] Removed redundant try-finally --- mypy/checkexpr.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index e082a107dd3a2..b896dbf6458c4 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2807,15 +2807,9 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type: if right_map is None: with self.msg.disable_errors(): - try: - right_type = self.analyze_cond_branch(right_map, e.right, left_type) - finally: - pass + right_type = self.analyze_cond_branch(right_map, e.right, left_type) else: - try: - right_type = self.analyze_cond_branch(right_map, e.right, left_type) - finally: - pass + right_type = self.analyze_cond_branch(right_map, e.right, left_type) if right_map is None: # The boolean expression is statically known to be the left value From db293552dd4f68e8c0898a75eca4caf6e75ee6a7 Mon Sep 17 00:00:00 2001 From: "dixith@hotmail.com" <7497698+dixith@users.noreply.github.com> Date: Sun, 28 Mar 2021 01:06:06 +0530 Subject: [PATCH 5/6] Removed extra white space --- mypy/checkexpr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index b896dbf6458c4..50c1fed70b2d0 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2807,7 +2807,7 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type: if right_map is None: with self.msg.disable_errors(): - right_type = self.analyze_cond_branch(right_map, e.right, left_type) + right_type = self.analyze_cond_branch(right_map, e.right, left_type) else: right_type = self.analyze_cond_branch(right_map, e.right, left_type) From a83a5701cf0f0b40ea6d3fad4520459f9057172e Mon Sep 17 00:00:00 2001 From: "dixith@hotmail.com" <7497698+dixith@users.noreply.github.com> Date: Sat, 3 Apr 2021 12:25:37 +0530 Subject: [PATCH 6/6] Remove context manager from analyze_cond_branch call --- mypy/checkexpr.py | 11 ++++++++--- mypy/messages.py | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 50c1fed70b2d0..b5018f4c929e4 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2806,10 +2806,15 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type: left_map = None if right_map is None: - with self.msg.disable_errors(): - right_type = self.analyze_cond_branch(right_map, e.right, left_type) + 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(right_map, e.right, left_type) + 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 0148f3de5137e..d8389aedad7c4 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -137,6 +137,9 @@ def add_errors(self, messages: 'MessageBuilder') -> None: for info in errs: self.errors.add_error_info(info) + def disable_errors1(self) -> None: + self.disable_count += 1 + @contextmanager def disable_errors(self) -> Iterator[None]: self.disable_count += 1 @@ -145,6 +148,9 @@ def disable_errors(self) -> Iterator[None]: finally: self.disable_count -= 1 + def enable_errors(self) -> None: + self.disable_count -= 1 + def is_errors(self) -> bool: return self.errors.is_errors()