From 52d3141ad9251828d31d37a9c2cb1c6d25aa43cd Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 31 Mar 2017 21:01:09 -0700 Subject: [PATCH] Get rid of ErrorType Fixes #3063 --- mypy/checker.py | 5 +---- mypy/erasetype.py | 5 +---- mypy/expandtype.py | 5 +---- mypy/indirection.py | 3 --- mypy/join.py | 18 ++--------------- mypy/meet.py | 38 +++++++++++------------------------ mypy/sametypes.py | 5 +---- mypy/solve.py | 7 ++----- mypy/subtypes.py | 5 +---- mypy/test/testtypes.py | 45 +++++++++++------------------------------- mypy/typefixture.py | 3 +-- mypy/types.py | 19 ------------------ 12 files changed, 32 insertions(+), 126 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 6c5ca121120e..5f68357db55b 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -31,7 +31,7 @@ from mypy import nodes from mypy.types import ( Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType, - Instance, NoneTyp, ErrorType, strip_type, TypeType, + Instance, NoneTyp, strip_type, TypeType, UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef, true_only, false_only, function_type, is_named_instance ) @@ -2133,9 +2133,6 @@ def analyze_iterable_item_type(self, expr: Expression) -> Type: joined = UninhabitedType() # type: Type for item in iterable.items: joined = join_types(joined, item) - if isinstance(joined, ErrorType): - self.fail(messages.CANNOT_INFER_ITEM_TYPE, expr) - return AnyType() return joined else: # Non-tuple iterable. diff --git a/mypy/erasetype.py b/mypy/erasetype.py index 9a44b0456522..8ba45d52d508 100644 --- a/mypy/erasetype.py +++ b/mypy/erasetype.py @@ -1,7 +1,7 @@ from typing import Optional, Container, Callable from mypy.types import ( - Type, TypeVisitor, UnboundType, ErrorType, AnyType, NoneTyp, TypeVarId, + Type, TypeVisitor, UnboundType, AnyType, NoneTyp, TypeVarId, Instance, TypeVarType, CallableType, TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType, DeletedType, TypeTranslator, TypeList, UninhabitedType, TypeType ) @@ -29,9 +29,6 @@ class EraseTypeVisitor(TypeVisitor[Type]): def visit_unbound_type(self, t: UnboundType) -> Type: assert False, 'Not supported' - def visit_error_type(self, t: ErrorType) -> Type: - return t - def visit_type_list(self, t: TypeList) -> Type: assert False, 'Not supported' diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 41c74daf6ea3..a526ddd2e020 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -1,7 +1,7 @@ from typing import Dict, Iterable, List, TypeVar, Mapping, cast from mypy.types import ( - Type, Instance, CallableType, TypeVisitor, UnboundType, ErrorType, AnyType, + Type, Instance, CallableType, TypeVisitor, UnboundType, AnyType, NoneTyp, TypeVarType, Overloaded, TupleType, TypedDictType, UnionType, ErasedType, TypeList, PartialType, DeletedType, UninhabitedType, TypeType, TypeVarId, FunctionLike, TypeVarDef @@ -63,9 +63,6 @@ def __init__(self, variables: Mapping[TypeVarId, Type]) -> None: def visit_unbound_type(self, t: UnboundType) -> Type: return t - def visit_error_type(self, t: ErrorType) -> Type: - return t - def visit_type_list(self, t: TypeList) -> Type: assert False, 'Not supported' diff --git a/mypy/indirection.py b/mypy/indirection.py index a604899031c2..cf22648b664b 100644 --- a/mypy/indirection.py +++ b/mypy/indirection.py @@ -45,9 +45,6 @@ def visit_unbound_type(self, t: types.UnboundType) -> Set[str]: def visit_type_list(self, t: types.TypeList) -> Set[str]: return self._visit(*t.items) - def visit_error_type(self, t: types.ErrorType) -> Set[str]: - return set() - def visit_any(self, t: types.AnyType) -> Set[str]: return set() diff --git a/mypy/join.py b/mypy/join.py index 06d5416cd2ea..170460811b87 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -5,7 +5,7 @@ from mypy.types import ( Type, AnyType, NoneTyp, TypeVisitor, Instance, UnboundType, - ErrorType, TypeVarType, CallableType, TupleType, TypedDictType, ErasedType, TypeList, + TypeVarType, CallableType, TupleType, TypedDictType, ErasedType, TypeList, UnionType, FunctionLike, Overloaded, PartialType, DeletedType, UninhabitedType, TypeType, true_or_false ) @@ -63,8 +63,6 @@ def join_types(s: Type, t: Type) -> Type: """Return the least upper bound of s and t. For example, the join of 'int' and 'object' is 'object'. - - If the join does not exist, return an ErrorType instance. """ if (s.can_be_true, s.can_be_false) != (t.can_be_true, t.can_be_false): # if types are restricted in different ways, use the more general versions @@ -101,10 +99,7 @@ def __init__(self, s: Type) -> None: self.s = s def visit_unbound_type(self, t: UnboundType) -> Type: - if isinstance(self.s, ErrorType): - return ErrorType() - else: - return AnyType() + return AnyType() def visit_union_type(self, t: UnionType) -> Type: if is_subtype(self.s, t): @@ -112,9 +107,6 @@ def visit_union_type(self, t: UnionType) -> Type: else: return UnionType.make_simplified_union([self.s, t]) - def visit_error_type(self, t: ErrorType) -> Type: - return t - def visit_type_list(self, t: TypeList) -> Type: assert False, 'Not supported' @@ -127,8 +119,6 @@ def visit_none_type(self, t: NoneTyp) -> Type: return t elif isinstance(self.s, UnboundType): return AnyType() - elif isinstance(self.s, ErrorType): - return ErrorType() else: return UnionType.make_simplified_union([self.s, t]) else: @@ -264,8 +254,6 @@ def default(self, typ: Type) -> Type: return object_from_instance(typ) elif isinstance(typ, UnboundType): return AnyType() - elif isinstance(typ, ErrorType): - return ErrorType() elif isinstance(typ, TupleType): return self.default(typ.fallback) elif isinstance(typ, TypedDictType): @@ -280,8 +268,6 @@ def default(self, typ: Type) -> Type: def join_instances(t: Instance, s: Instance) -> Type: """Calculate the join of two instance types. - - Return ErrorType if the result is ambiguous. """ if t.type == s.type: # Simplest case: join two types with the same base type (but diff --git a/mypy/meet.py b/mypy/meet.py index 22d0a709838b..ee03748982e9 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -3,7 +3,7 @@ from mypy.join import is_similar_callables, combine_similar_callables, join_type_list from mypy.types import ( - Type, AnyType, TypeVisitor, UnboundType, ErrorType, NoneTyp, TypeVarType, + Type, AnyType, TypeVisitor, UnboundType, NoneTyp, TypeVarType, Instance, CallableType, TupleType, TypedDictType, ErasedType, TypeList, UnionType, PartialType, DeletedType, UninhabitedType, TypeType ) @@ -124,9 +124,7 @@ def __init__(self, s: Type) -> None: self.s = s def visit_unbound_type(self, t: UnboundType) -> Type: - if isinstance(self.s, ErrorType): - return ErrorType() - elif isinstance(self.s, NoneTyp): + if isinstance(self.s, NoneTyp): if experiments.STRICT_OPTIONAL: return AnyType() else: @@ -136,9 +134,6 @@ def visit_unbound_type(self, t: UnboundType) -> Type: else: return AnyType() - def visit_error_type(self, t: ErrorType) -> Type: - return t - def visit_type_list(self, t: TypeList) -> Type: assert False, 'Not supported' @@ -164,30 +159,21 @@ def visit_none_type(self, t: NoneTyp) -> Type: else: return UninhabitedType() else: - if not isinstance(self.s, ErrorType): - return t - else: - return ErrorType() + return t def visit_uninhabited_type(self, t: UninhabitedType) -> Type: - if not isinstance(self.s, ErrorType): - return t - else: - return ErrorType() + return t def visit_deleted_type(self, t: DeletedType) -> Type: - if not isinstance(self.s, ErrorType): - if isinstance(self.s, NoneTyp): - if experiments.STRICT_OPTIONAL: - return t - else: - return self.s - elif isinstance(self.s, UninhabitedType): - return self.s - else: + if isinstance(self.s, NoneTyp): + if experiments.STRICT_OPTIONAL: return t + else: + return self.s + elif isinstance(self.s, UninhabitedType): + return self.s else: - return ErrorType() + return t def visit_erased_type(self, t: ErasedType) -> Type: return self.s @@ -288,8 +274,6 @@ def meet(self, s: Type, t: Type) -> Type: def default(self, typ: Type) -> Type: if isinstance(typ, UnboundType): return AnyType() - elif isinstance(typ, ErrorType): - return ErrorType() else: if experiments.STRICT_OPTIONAL: return UninhabitedType() diff --git a/mypy/sametypes.py b/mypy/sametypes.py index d3f283d449ea..f1a697ced4c9 100644 --- a/mypy/sametypes.py +++ b/mypy/sametypes.py @@ -1,7 +1,7 @@ from typing import Sequence from mypy.types import ( - Type, UnboundType, ErrorType, AnyType, NoneTyp, TupleType, TypedDictType, + Type, UnboundType, AnyType, NoneTyp, TupleType, TypedDictType, UnionType, CallableType, TypeVarType, Instance, TypeVisitor, ErasedType, TypeList, Overloaded, PartialType, DeletedType, UninhabitedType, TypeType ) @@ -55,9 +55,6 @@ def __init__(self, right: Type) -> None: def visit_unbound_type(self, left: UnboundType) -> bool: return True - def visit_error_type(self, left: ErrorType) -> bool: - return False - def visit_type_list(self, t: TypeList) -> bool: assert False, 'Not supported' diff --git a/mypy/solve.py b/mypy/solve.py index dda9a0950b90..5d2cca0edef8 100644 --- a/mypy/solve.py +++ b/mypy/solve.py @@ -3,7 +3,7 @@ from typing import List, Dict from collections import defaultdict -from mypy.types import Type, NoneTyp, AnyType, ErrorType, UninhabitedType, TypeVarId +from mypy.types import Type, NoneTyp, AnyType, UninhabitedType, TypeVarId from mypy.constraints import Constraint, SUPERTYPE_OF from mypy.join import join_types from mypy.meet import meet_types @@ -68,9 +68,6 @@ def solve_constraints(vars: List[TypeVarId], constraints: List[Constraint], candidate = bottom else: candidate = None - if isinstance(candidate, ErrorType): - res.append(None) - else: - res.append(candidate) + res.append(candidate) return res diff --git a/mypy/subtypes.py b/mypy/subtypes.py index c98bb8e8d144..abe825dddfb7 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -1,7 +1,7 @@ from typing import List, Optional, Dict, Callable from mypy.types import ( - Type, AnyType, UnboundType, TypeVisitor, ErrorType, FormalArgument, NoneTyp, + Type, AnyType, UnboundType, TypeVisitor, FormalArgument, NoneTyp, Instance, TypeVarType, CallableType, TupleType, TypedDictType, UnionType, Overloaded, ErasedType, TypeList, PartialType, DeletedType, UninhabitedType, TypeType, is_named_instance ) @@ -94,9 +94,6 @@ def __init__(self, right: Type, def visit_unbound_type(self, left: UnboundType) -> bool: return True - def visit_error_type(self, left: ErrorType) -> bool: - return False - def visit_type_list(self, t: TypeList) -> bool: assert False, 'Not supported' diff --git a/mypy/test/testtypes.py b/mypy/test/testtypes.py index 9fc6a71b5594..f2d17bff0680 100644 --- a/mypy/test/testtypes.py +++ b/mypy/test/testtypes.py @@ -11,7 +11,7 @@ from mypy.meet import meet_types from mypy.types import ( UnboundType, AnyType, CallableType, TupleType, TypeVarDef, Type, - Instance, NoneTyp, ErrorType, Overloaded, TypeType, UnionType, UninhabitedType, + Instance, NoneTyp, Overloaded, TypeType, UnionType, UninhabitedType, true_only, false_only, TypeVarId ) from mypy.nodes import ARG_POS, ARG_OPT, ARG_STAR, CONTRAVARIANT, INVARIANT, COVARIANT @@ -136,8 +136,7 @@ def assert_expand(self, # erase_type def test_trivial_erase(self) -> None: - for t in (self.fx.a, self.fx.o, self.fx.nonet, - self.fx.anyt, self.fx.err): + for t in (self.fx.a, self.fx.o, self.fx.nonet, self.fx.anyt): self.assert_erase(t, t) def test_erase_with_type_variable(self) -> None: @@ -456,15 +455,6 @@ def test_other_mixed_types(self) -> None: if str(t1) != str(t2): self.assert_join(t1, t2, self.fx.o) - def test_error_type(self) -> None: - self.assert_join(self.fx.err, self.fx.anyt, self.fx.anyt) - - # Meet against any type except dynamic results in ErrorType. - for t in [self.fx.a, self.fx.o, NoneTyp(), UnboundType('x'), - self.fx.t, self.tuple(), - self.callable(self.fx.a, self.fx.b)]: - self.assert_join(t, self.fx.err, self.fx.err) - def test_simple_generics(self) -> None: self.assert_join(self.fx.ga, self.fx.ga, self.fx.ga) self.assert_join(self.fx.ga, self.fx.gb, self.fx.ga) @@ -553,7 +543,7 @@ def test_join_class_types_with_interface_result(self) -> None: self.assert_join(self.fx.e, self.fx.e2, self.fx.f) # Ambiguous result - self.assert_join(self.fx.e2, self.fx.e3, self.fx.err) + self.assert_join(self.fx.e2, self.fx.e3, self.fx.anyt) def test_generic_interfaces(self) -> None: self.skip() # FIX @@ -604,12 +594,10 @@ def assert_simple_join(self, s: Type, t: Type, join: Type) -> None: expected = str(join) assert_equal(actual, expected, 'join({}, {}) == {{}} ({{}} expected)'.format(s, t)) - if not isinstance(s, ErrorType) and not isinstance(result, ErrorType): - assert_true(is_subtype(s, result), - '{} not subtype of {}'.format(s, result)) - if not isinstance(t, ErrorType) and not isinstance(result, ErrorType): - assert_true(is_subtype(t, result), - '{} not subtype of {}'.format(t, result)) + assert_true(is_subtype(s, result), + '{} not subtype of {}'.format(s, result)) + assert_true(is_subtype(t, result), + '{} not subtype of {}'.format(t, result)) def tuple(self, *a: Type) -> TupleType: return TupleType(list(a), self.fx.std_tuple) @@ -710,15 +698,6 @@ def test_dynamic_type(self) -> None: self.callable(self.fx.a, self.fx.b)]: self.assert_meet(t, self.fx.anyt, t) - def test_error_type(self) -> None: - self.assert_meet(self.fx.err, self.fx.anyt, self.fx.err) - - # Meet against any type except dynamic results in ErrorType. - for t in [self.fx.a, self.fx.o, NoneTyp(), UnboundType('x'), - self.fx.t, self.tuple(), - self.callable(self.fx.a, self.fx.b)]: - self.assert_meet(t, self.fx.err, self.fx.err) - def test_simple_generics(self) -> None: self.assert_meet(self.fx.ga, self.fx.ga, self.fx.ga) self.assert_meet(self.fx.ga, self.fx.o, self.fx.ga) @@ -805,12 +784,10 @@ def assert_simple_meet(self, s: Type, t: Type, meet: Type) -> None: expected = str(meet) assert_equal(actual, expected, 'meet({}, {}) == {{}} ({{}} expected)'.format(s, t)) - if not isinstance(s, ErrorType) and not isinstance(result, ErrorType): - assert_true(is_subtype(result, s), - '{} not subtype of {}'.format(result, s)) - if not isinstance(t, ErrorType) and not isinstance(result, ErrorType): - assert_true(is_subtype(result, t), - '{} not subtype of {}'.format(result, t)) + assert_true(is_subtype(result, s), + '{} not subtype of {}'.format(result, s)) + assert_true(is_subtype(result, t), + '{} not subtype of {}'.format(result, t)) def tuple(self, *a: Type) -> TupleType: return TupleType(list(a), self.fx.std_tuple) diff --git a/mypy/typefixture.py b/mypy/typefixture.py index 23089419215d..40211b09a52a 100644 --- a/mypy/typefixture.py +++ b/mypy/typefixture.py @@ -6,7 +6,7 @@ from typing import List from mypy.types import ( - Type, TypeVarType, AnyType, ErrorType, NoneTyp, + Type, TypeVarType, AnyType, NoneTyp, Instance, CallableType, TypeVarDef, TypeType, UninhabitedType ) from mypy.nodes import ( @@ -41,7 +41,6 @@ def make_type_var(name: str, id: int, values: List[Type], upper_bound: Type, # Simple types self.anyt = AnyType() - self.err = ErrorType() self.nonet = NoneTyp() self.uninhabited = UninhabitedType() diff --git a/mypy/types.py b/mypy/types.py index 41ef8ec238f5..e182806a4f39 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -223,13 +223,6 @@ def deserialize(cls, data: JsonDict) -> 'UnboundType': [deserialize_type(a) for a in data['args']]) -class ErrorType(Type): - """The error type is used as the result of failed type operations.""" - - def accept(self, visitor: 'TypeVisitor[T]') -> T: - return visitor.visit_error_type(self) - - class TypeList(Type): """A list of types [...]. @@ -1188,9 +1181,6 @@ def visit_unbound_type(self, t: UnboundType) -> T: def visit_type_list(self, t: TypeList) -> T: raise self._notimplemented_helper('type_list') - def visit_error_type(self, t: ErrorType) -> T: - raise self._notimplemented_helper('error_type') - @abstractmethod def visit_any(self, t: AnyType) -> T: pass @@ -1265,9 +1255,6 @@ def visit_unbound_type(self, t: UnboundType) -> Type: def visit_type_list(self, t: TypeList) -> Type: return t - def visit_error_type(self, t: ErrorType) -> Type: - return t - def visit_any(self, t: AnyType) -> Type: return t @@ -1364,9 +1351,6 @@ def visit_unbound_type(self, t: UnboundType)-> str: def visit_type_list(self, t: TypeList) -> str: return ''.format(self.list_str(t.items)) - def visit_error_type(self, t: ErrorType) -> str: - return '' - def visit_any(self, t: AnyType) -> str: return 'Any' @@ -1533,9 +1517,6 @@ def visit_unbound_type(self, t: UnboundType) -> bool: def visit_type_list(self, t: TypeList) -> bool: return self.default - def visit_error_type(self, t: ErrorType) -> bool: - return self.default - def visit_any(self, t: AnyType) -> bool: return self.default