Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LiteralType and stub methods to type visitors #5934

Merged
merged 2 commits into from
Nov 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mypy/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from mypy.types import (
CallableType, Type, TypeVisitor, UnboundType, AnyType, NoneTyp, TypeVarType, Instance,
TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType, DeletedType,
UninhabitedType, TypeType, TypeVarId, TypeQuery, is_named_instance, TypeOfAny
UninhabitedType, TypeType, TypeVarId, TypeQuery, is_named_instance, TypeOfAny, LiteralType,
)
from mypy.maptype import map_instance_to_supertype
from mypy import nodes
Expand Down Expand Up @@ -506,6 +506,9 @@ def visit_typeddict_type(self, template: TypedDictType) -> List[Constraint]:
else:
return []

def visit_literal_type(self, template: LiteralType) -> List[Constraint]:
raise NotImplementedError()

def visit_union_type(self, template: UnionType) -> List[Constraint]:
assert False, ("Unexpected UnionType in ConstraintBuilderVisitor"
" (should have been handled in infer_constraints)")
Expand Down
8 changes: 7 additions & 1 deletion mypy/erasetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from mypy.types import (
Type, TypeVisitor, UnboundType, AnyType, NoneTyp, TypeVarId, Instance, TypeVarType,
CallableType, TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType,
DeletedType, TypeTranslator, UninhabitedType, TypeType, TypeOfAny
DeletedType, TypeTranslator, UninhabitedType, TypeType, TypeOfAny, LiteralType,
)
from mypy.nodes import ARG_STAR, ARG_STAR2

Expand Down Expand Up @@ -78,6 +78,12 @@ def visit_tuple_type(self, t: TupleType) -> Type:
def visit_typeddict_type(self, t: TypedDictType) -> Type:
return t.fallback.accept(self)

def visit_literal_type(self, t: LiteralType) -> Type:
# The fallback for literal types should always be either
# something like int or str, or an enum class -- types that
# don't contain any TypeVars. So there's no need to visit it.
return t

def visit_union_type(self, t: UnionType) -> Type:
erased_items = [erase_type(item) for item in t.items]
return UnionType.make_simplified_union(erased_items)
Expand Down
6 changes: 5 additions & 1 deletion mypy/expandtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Type, Instance, CallableType, TypeVisitor, UnboundType, AnyType,
NoneTyp, TypeVarType, Overloaded, TupleType, TypedDictType, UnionType,
ErasedType, PartialType, DeletedType, UninhabitedType, TypeType, TypeVarId,
FunctionLike, TypeVarDef
FunctionLike, TypeVarDef, LiteralType,
)


Expand Down Expand Up @@ -111,6 +111,10 @@ def visit_tuple_type(self, t: TupleType) -> Type:
def visit_typeddict_type(self, t: TypedDictType) -> Type:
return t.copy_modified(item_types=self.expand_types(t.items.values()))

def visit_literal_type(self, t: LiteralType) -> Type:
# TODO: Verify this implementation is correct
return t

def visit_union_type(self, t: UnionType) -> Type:
# After substituting for type variables in t.items,
# some of the resulting types might be subtypes of others.
Expand Down
5 changes: 4 additions & 1 deletion mypy/fixup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
)
from mypy.types import (
CallableType, Instance, Overloaded, TupleType, TypedDictType,
TypeVarType, UnboundType, UnionType, TypeVisitor,
TypeVarType, UnboundType, UnionType, TypeVisitor, LiteralType,
TypeType, NOT_READY
)
from mypy.visitor import NodeVisitor
Expand Down Expand Up @@ -206,6 +206,9 @@ def visit_typeddict_type(self, tdt: TypedDictType) -> None:
if tdt.fallback is not None:
tdt.fallback.accept(self)

def visit_literal_type(self, lt: LiteralType) -> None:
lt.fallback.accept(self)

def visit_type_var(self, tvt: TypeVarType) -> None:
if tvt.values:
for vt in tvt.values:
Expand Down
3 changes: 3 additions & 0 deletions mypy/indirection.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ def visit_tuple_type(self, t: types.TupleType) -> Set[str]:
def visit_typeddict_type(self, t: types.TypedDictType) -> Set[str]:
return self._visit(t.items.values()) | self._visit(t.fallback)

def visit_literal_type(self, t: types.LiteralType) -> Set[str]:
return self._visit(t.fallback)

def visit_star_type(self, t: types.StarType) -> Set[str]:
return set()

Expand Down
7 changes: 5 additions & 2 deletions mypy/join.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

from mypy.types import (
Type, AnyType, NoneTyp, TypeVisitor, Instance, UnboundType, TypeVarType, CallableType,
TupleType, TypedDictType, ErasedType, UnionType, FunctionLike, Overloaded,
PartialType, DeletedType, UninhabitedType, TypeType, true_or_false, TypeOfAny
TupleType, TypedDictType, ErasedType, UnionType, FunctionLike, Overloaded, LiteralType,
PartialType, DeletedType, UninhabitedType, TypeType, true_or_false, TypeOfAny,
)
from mypy.maptype import map_instance_to_supertype
from mypy.subtypes import (
Expand Down Expand Up @@ -267,6 +267,9 @@ def visit_typeddict_type(self, t: TypedDictType) -> Type:
else:
return self.default(self.s)

def visit_literal_type(self, t: LiteralType) -> Type:
raise NotImplementedError()

def visit_partial_type(self, t: PartialType) -> Type:
# We only have partial information so we can't decide the join result. We should
# never get here.
Expand Down
5 changes: 4 additions & 1 deletion mypy/meet.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from mypy.types import (
Type, AnyType, TypeVisitor, UnboundType, NoneTyp, TypeVarType, Instance, CallableType,
TupleType, TypedDictType, ErasedType, UnionType, PartialType, DeletedType,
UninhabitedType, TypeType, TypeOfAny, Overloaded, FunctionLike,
UninhabitedType, TypeType, TypeOfAny, Overloaded, FunctionLike, LiteralType,
)
from mypy.subtypes import (
is_equivalent, is_subtype, is_protocol_implementation, is_callable_compatible,
Expand Down Expand Up @@ -520,6 +520,9 @@ def visit_typeddict_type(self, t: TypedDictType) -> Type:
else:
return self.default(self.s)

def visit_literal_type(self, t: LiteralType) -> Type:
raise NotImplementedError()

def visit_partial_type(self, t: PartialType) -> Type:
# We can't determine the meet of partial types. We should never get here.
assert False, 'Internal error'
Expand Down
10 changes: 9 additions & 1 deletion mypy/sametypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from mypy.types import (
Type, UnboundType, AnyType, NoneTyp, TupleType, TypedDictType,
UnionType, CallableType, TypeVarType, Instance, TypeVisitor, ErasedType,
Overloaded, PartialType, DeletedType, UninhabitedType, TypeType
Overloaded, PartialType, DeletedType, UninhabitedType, TypeType, LiteralType,
)


Expand Down Expand Up @@ -114,6 +114,14 @@ def visit_typeddict_type(self, left: TypedDictType) -> bool:
else:
return False

def visit_literal_type(self, left: LiteralType) -> bool:
if isinstance(self.right, LiteralType):
if left.value != self.right.value:
return False
return is_same_type(left.fallback, self.right.fallback)
else:
return False

def visit_union_type(self, left: UnionType) -> bool:
if isinstance(self.right, UnionType):
# Check that everything in left is in right
Expand Down
5 changes: 4 additions & 1 deletion mypy/server/astdiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class level -- these are handled at attribute level (say, 'mod.Cls.method'
from mypy.types import (
Type, TypeVisitor, UnboundType, AnyType, NoneTyp, UninhabitedType,
ErasedType, DeletedType, Instance, TypeVarType, CallableType, TupleType, TypedDictType,
UnionType, Overloaded, PartialType, TypeType
UnionType, Overloaded, PartialType, TypeType, LiteralType,
)
from mypy.util import get_prefix

Expand Down Expand Up @@ -315,6 +315,9 @@ def visit_typeddict_type(self, typ: TypedDictType) -> SnapshotItem:
required = tuple(sorted(typ.required_keys))
return ('TypedDictType', items, required)

def visit_literal_type(self, typ: LiteralType) -> SnapshotItem:
return ('LiteralType', typ.value, snapshot_type(typ.fallback))

def visit_union_type(self, typ: UnionType) -> SnapshotItem:
# Sort and remove duplicates so that we can use equality to test for
# equivalent union type snapshots.
Expand Down
5 changes: 4 additions & 1 deletion mypy/server/astmerge.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from mypy.types import (
Type, SyntheticTypeVisitor, Instance, AnyType, NoneTyp, CallableType, DeletedType, PartialType,
TupleType, TypeType, TypeVarType, TypedDictType, UnboundType, UninhabitedType, UnionType,
Overloaded, TypeVarDef, TypeList, CallableArgument, EllipsisType, StarType
Overloaded, TypeVarDef, TypeList, CallableArgument, EllipsisType, StarType, LiteralType,
)
from mypy.util import get_prefix, replace_object_state
from mypy.typestate import TypeState
Expand Down Expand Up @@ -391,6 +391,9 @@ def visit_typeddict_type(self, typ: TypedDictType) -> None:
value_type.accept(self)
typ.fallback.accept(self)

def visit_literal_type(self, typ: LiteralType) -> None:
typ.fallback.accept(self)

def visit_unbound_type(self, typ: UnboundType) -> None:
for arg in typ.args:
arg.accept(self)
Expand Down
5 changes: 4 additions & 1 deletion mypy/server/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class 'mod.Cls'. This can also refer to an attribute inherited from a
from mypy.types import (
Type, Instance, AnyType, NoneTyp, TypeVisitor, CallableType, DeletedType, PartialType,
TupleType, TypeType, TypeVarType, TypedDictType, UnboundType, UninhabitedType, UnionType,
FunctionLike, ForwardRef, Overloaded, TypeOfAny
FunctionLike, ForwardRef, Overloaded, TypeOfAny, LiteralType,
)
from mypy.server.trigger import make_trigger, make_wildcard_trigger
from mypy.util import correct_relative_import
Expand Down Expand Up @@ -949,6 +949,9 @@ def visit_typeddict_type(self, typ: TypedDictType) -> List[str]:
triggers.extend(self.get_type_triggers(typ.fallback))
return triggers

def visit_literal_type(self, typ: LiteralType) -> List[str]:
return self.get_type_triggers(typ.fallback)

def visit_unbound_type(self, typ: UnboundType) -> List[str]:
return []

Expand Down
8 changes: 7 additions & 1 deletion mypy/subtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Type, AnyType, UnboundType, TypeVisitor, FormalArgument, NoneTyp, function_type,
Instance, TypeVarType, CallableType, TupleType, TypedDictType, UnionType, Overloaded,
ErasedType, PartialType, DeletedType, UninhabitedType, TypeType, is_named_instance,
FunctionLike, TypeOfAny
FunctionLike, TypeOfAny, LiteralType,
)
import mypy.applytype
import mypy.constraints
Expand Down Expand Up @@ -327,6 +327,9 @@ def visit_typeddict_type(self, left: TypedDictType) -> bool:
else:
return False

def visit_literal_type(self, t: LiteralType) -> bool:
raise NotImplementedError()

def visit_overloaded(self, left: Overloaded) -> bool:
right = self.right
if isinstance(right, Instance):
Expand Down Expand Up @@ -1168,6 +1171,9 @@ def visit_typeddict_type(self, left: TypedDictType) -> bool:
return True
return self._is_proper_subtype(left.fallback, right)

def visit_literal_type(self, left: LiteralType) -> bool:
raise NotImplementedError()

def visit_overloaded(self, left: Overloaded) -> bool:
# TODO: What's the right thing to do here?
return False
Expand Down
19 changes: 18 additions & 1 deletion mypy/type_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
T = TypeVar('T')

from mypy.types import (
Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType,
Type, AnyType, CallableType, FunctionLike, Overloaded, TupleType, TypedDictType, LiteralType,
Instance, NoneTyp, TypeType, TypeOfAny,
UnionType, TypeVarId, TypeVarType, PartialType, DeletedType, UninhabitedType, TypeVarDef,
UnboundType, ErasedType, ForwardRef, StarType, EllipsisType, TypeList, CallableArgument,
Expand Down Expand Up @@ -85,6 +85,10 @@ def visit_tuple_type(self, t: TupleType) -> T:
def visit_typeddict_type(self, t: TypedDictType) -> T:
pass

@abstractmethod
def visit_literal_type(self, t: LiteralType) -> T:
pass

@abstractmethod
def visit_union_type(self, t: UnionType) -> T:
pass
Expand Down Expand Up @@ -181,6 +185,16 @@ def visit_typeddict_type(self, t: TypedDictType) -> Type:
cast(Any, t.fallback.accept(self)),
t.line, t.column)

def visit_literal_type(self, t: LiteralType) -> Type:
fallback = t.fallback.accept(self)
assert isinstance(fallback, Instance)
return LiteralType(
value=t.value,
fallback=fallback,
line=t.line,
column=t.column,
)

def visit_union_type(self, t: UnionType) -> Type:
return UnionType(self.translate_types(t.items), t.line, t.column)

Expand Down Expand Up @@ -264,6 +278,9 @@ def visit_tuple_type(self, t: TupleType) -> T:
def visit_typeddict_type(self, t: TypedDictType) -> T:
return self.query_types(t.items.values())

def visit_literal_type(self, t: LiteralType) -> T:
return self.strategy([])

def visit_star_type(self, t: StarType) -> T:
return t.type.accept(self)

Expand Down
9 changes: 8 additions & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
Type, UnboundType, TypeVarType, TupleType, TypedDictType, UnionType, Instance, AnyType,
CallableType, NoneTyp, DeletedType, TypeList, TypeVarDef, TypeVisitor, SyntheticTypeVisitor,
StarType, PartialType, EllipsisType, UninhabitedType, TypeType, get_typ_args, set_typ_args,
CallableArgument, get_type_vars, TypeQuery, union_items, TypeOfAny, ForwardRef, Overloaded
CallableArgument, get_type_vars, TypeQuery, union_items, TypeOfAny, ForwardRef, Overloaded,
LiteralType,
)

from mypy.nodes import (
Expand Down Expand Up @@ -459,6 +460,9 @@ def visit_typeddict_type(self, t: TypedDictType) -> Type:
])
return TypedDictType(items, set(t.required_keys), t.fallback)

def visit_literal_type(self, t: LiteralType) -> Type:
raise NotImplementedError()

def visit_star_type(self, t: StarType) -> Type:
return StarType(self.anal_type(t.type), t.line)

Expand Down Expand Up @@ -754,6 +758,9 @@ def visit_typeddict_type(self, t: TypedDictType) -> None:
for item_type in t.items.values():
item_type.accept(self)

def visit_literal_type(self, t: LiteralType) -> None:
raise NotImplementedError()

def visit_union_type(self, t: UnionType) -> None:
for item in t.items:
item.accept(self)
Expand Down
Loading