Skip to content

Commit

Permalink
Convert MessageBuilder.disable_errors to a context manager (#10569)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikonst committed Jun 2, 2021
1 parent 8853f22 commit 28718fa
Show file tree
Hide file tree
Showing 25 changed files with 79 additions and 69 deletions.
18 changes: 18 additions & 0 deletions mypy/backports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import sys
from contextlib import contextmanager
from typing import Iterator

if sys.version_info < (3, 6):
from collections import OrderedDict as OrderedDict # noqa: F401
else:
# OrderedDict is kind of slow, so for most of our uses in Python 3.6
# and later we'd rather just use dict
OrderedDict = dict


if sys.version_info < (3, 7):
@contextmanager
def nullcontext() -> Iterator[None]:
yield
else:
from contextlib import nullcontext as nullcontext # noqa: F401
22 changes: 10 additions & 12 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
36 changes: 13 additions & 23 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Expression type checker. This file is conceptually part of TypeChecker."""

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict, nullcontext
from contextlib import contextmanager
import itertools
from typing import (
Expand Down Expand Up @@ -865,12 +865,11 @@ 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
Expand Down Expand Up @@ -1203,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))
Expand Down Expand Up @@ -2798,10 +2794,6 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type:
if left_map is None:
self.msg.redundant_left_operand(e.op, e.left)

# If right_map is None then we know mypy considers the right branch
# to be unreachable and therefore any errors found in the right branch
# should be suppressed.
#
# Note that we perform these checks *before* we take into account
# the analysis from the semanal phase below. We assume that nodes
# marked as unreachable during semantic analysis were done so intentionally.
Expand All @@ -2815,13 +2807,11 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type:
elif e.right_always:
left_map = None

if right_map is None:
self.msg.disable_errors()
try:
# If right_map is None then we know mypy considers the right branch
# to be unreachable and therefore any errors found in the right branch
# should be suppressed.
with (self.msg.disable_errors() if right_map is None else nullcontext()):
right_type = self.analyze_cond_branch(right_map, e.right, left_type)
finally:
if right_map is None:
self.msg.enable_errors()

if right_map is None:
# The boolean expression is statically known to be the left value
Expand Down
2 changes: 1 addition & 1 deletion mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def analyze_type_type_member_access(name: str,
item = None
fallback = mx.builtin_type('builtins.type')
ignore_messages = mx.msg.copy()
ignore_messages.disable_errors()
ignore_messages.disable_errors().__enter__()
if isinstance(typ.item, Instance):
item = typ.item
elif isinstance(typ.item, AnyType):
Expand Down
2 changes: 1 addition & 1 deletion mypy/errors.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os.path
import sys
import traceback
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from collections import defaultdict

from typing import Tuple, List, TypeVar, Set, Dict, Optional, TextIO, Callable
Expand Down
2 changes: 1 addition & 1 deletion mypy/join.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Calculation of the least upper bound types (joins)."""

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import List, Optional

from mypy.types import (
Expand Down
2 changes: 1 addition & 1 deletion mypy/meet.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import List, Optional, Tuple, Callable

from mypy.join import (
Expand Down
15 changes: 9 additions & 6 deletions mypy/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
Historically we tried to avoid all message string literals in the type
checker but we are moving away from this convention.
"""
from contextlib import contextmanager

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
import re
import difflib
from textwrap import dedent

from typing import cast, List, Dict, Any, Sequence, Iterable, Tuple, Set, Optional, Union
from typing import cast, List, Dict, Any, Sequence, Iterable, Iterator, Tuple, Set, Optional, Union
from typing_extensions import Final

from mypy.erasetype import erase_type
Expand Down Expand Up @@ -136,11 +137,13 @@ 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

def enable_errors(self) -> None:
self.disable_count -= 1
try:
yield
finally:
self.disable_count -= 1

def is_errors(self) -> bool:
return self.errors.is_errors()
Expand Down
2 changes: 1 addition & 1 deletion mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import os
from abc import abstractmethod
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from collections import defaultdict
from typing import (
Any, TypeVar, List, Tuple, cast, Set, Dict, Union, Optional, Callable, Sequence, Iterator
Expand Down
10 changes: 10 additions & 0 deletions mypy/nullcontext.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sys
from contextlib import contextmanager
from typing import Iterator

if sys.version_info < (3, 7):
@contextmanager
def nullcontext() -> Iterator[None]:
yield
else:
from contextlib import nullcontext as nullcontext, contextmanager # noqa: F401
2 changes: 1 addition & 1 deletion mypy/options.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
import re
import pprint
import sys
Expand Down
9 changes: 0 additions & 9 deletions mypy/ordered_dict.py
Original file line number Diff line number Diff line change
@@ -1,9 +0,0 @@
# OrderedDict is kind of slow, so for most of our uses in Python 3.6
# and later we'd rather just use dict

import sys

if sys.version_info < (3, 6):
from collections import OrderedDict as OrderedDict
else:
OrderedDict = dict
2 changes: 1 addition & 1 deletion mypy/plugins/attrs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Plugin for supporting the attrs library (http://www.attrs.org)"""

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from typing import Optional, Dict, List, cast, Tuple, Iterable
from typing_extensions import Final
Expand Down
2 changes: 1 addition & 1 deletion mypy/semanal_typeddict.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Semantic analysis of TypedDict definitions."""

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import Optional, List, Set, Tuple
from typing_extensions import Final

Expand Down
2 changes: 1 addition & 1 deletion mypy/type_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"""

from abc import abstractmethod
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import Generic, TypeVar, cast, Any, List, Callable, Iterable, Optional, Set, Sequence
from mypy_extensions import trait, mypyc_attr

Expand Down
2 changes: 1 addition & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import itertools
from itertools import chain
from contextlib import contextmanager
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from typing import Callable, List, Optional, Set, Tuple, Iterator, TypeVar, Iterable, Sequence
from typing_extensions import Final
Expand Down
2 changes: 1 addition & 1 deletion mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import copy
import sys
from abc import abstractmethod
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from typing import (
Any, TypeVar, Dict, List, Tuple, cast, Set, Optional, Union, Iterable, NamedTuple,
Expand Down
2 changes: 1 addition & 1 deletion mypyc/codegen/emit.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Utilities for emitting C code."""

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import List, Set, Dict, Optional, Callable, Union, Tuple
import sys

Expand Down
2 changes: 1 addition & 1 deletion mypyc/codegen/emitclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import Optional, List, Tuple, Dict, Callable, Mapping, Set

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from mypyc.common import PREFIX, NATIVE_PREFIX, REG_PREFIX, use_fastcall
from mypyc.codegen.emit import Emitter, HeaderDeclaration
Expand Down
2 changes: 1 addition & 1 deletion mypyc/codegen/emitmodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import os
import json
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import List, Tuple, Dict, Iterable, Set, TypeVar, Optional

from mypy.nodes import MypyFile
Expand Down
2 changes: 1 addition & 1 deletion mypyc/ir/class_ir.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Intermediate representation of classes."""

from typing import List, Optional, Set, Tuple, Dict, NamedTuple
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from mypyc.common import JsonDict
from mypyc.ir.ops import Value, DeserMaps
Expand Down
2 changes: 1 addition & 1 deletion mypyc/irbuild/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from typing import Callable, Dict, List, Tuple, Optional, Union, Sequence, Set, Any
from typing_extensions import overload
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from mypy.build import Graph
from mypy.nodes import (
Expand Down
2 changes: 1 addition & 1 deletion mypyc/irbuild/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def f(x: int) -> int:
below, mypyc.irbuild.builder, and mypyc.irbuild.visitor.
"""

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from typing import List, Dict, Callable, Any, TypeVar, cast

from mypy.nodes import MypyFile, Expression, ClassDef
Expand Down
2 changes: 1 addition & 1 deletion mypyc/test/test_emitfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import List, Optional

from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict

from mypy.test.helpers import assert_string_arrays_equal

Expand Down
2 changes: 1 addition & 1 deletion mypyc/test/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# contain its own tests so that pytest will rewrite the asserts...

from typing import Any, Dict, Tuple
from mypy.ordered_dict import OrderedDict
from mypy.backports import OrderedDict
from collections.abc import Iterable

from mypyc.ir.ops import DeserMaps
Expand Down

0 comments on commit 28718fa

Please sign in to comment.