Skip to content

Commit

Permalink
Get rid of ErrorType (#3103)
Browse files Browse the repository at this point in the history
Fixes #3063
  • Loading branch information
gvanrossum authored and JukkaL committed Apr 3, 2017
1 parent 5b2c626 commit ad2b32e
Show file tree
Hide file tree
Showing 12 changed files with 32 additions and 126 deletions.
5 changes: 1 addition & 4 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 1 addition & 4 deletions mypy/erasetype.py
Original file line number Diff line number Diff line change
@@ -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
)
Expand Down Expand Up @@ -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'

Expand Down
5 changes: 1 addition & 4 deletions mypy/expandtype.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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'

Expand Down
3 changes: 0 additions & 3 deletions mypy/indirection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
18 changes: 2 additions & 16 deletions mypy/join.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -101,20 +99,14 @@ 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):
return t
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'

Expand All @@ -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:
Expand Down Expand Up @@ -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):
Expand All @@ -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
Expand Down
38 changes: 11 additions & 27 deletions mypy/meet.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down Expand Up @@ -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:
Expand All @@ -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'

Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down
5 changes: 1 addition & 4 deletions mypy/sametypes.py
Original file line number Diff line number Diff line change
@@ -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
)
Expand Down Expand Up @@ -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'

Expand Down
7 changes: 2 additions & 5 deletions mypy/solve.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
5 changes: 1 addition & 4 deletions mypy/subtypes.py
Original file line number Diff line number Diff line change
@@ -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
)
Expand Down Expand Up @@ -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'

Expand Down
45 changes: 11 additions & 34 deletions mypy/test/testtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 1 addition & 2 deletions mypy/typefixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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()

Expand Down
Loading

0 comments on commit ad2b32e

Please sign in to comment.