diff --git a/mypy/fixup.py b/mypy/fixup.py index c9a45b890b92..f290dbab3b60 100644 --- a/mypy/fixup.py +++ b/mypy/fixup.py @@ -185,6 +185,10 @@ def visit_overloaded(self, t: Overloaded) -> None: for ct in t.items(): ct.accept(self) + def visit_erased_type(self, o: Any) -> None: + # This type should exist only temporarily during type inference + raise RuntimeError("Shouldn't get here", o) + def visit_deleted_type(self, o: Any) -> None: pass # Nothing to descend into. diff --git a/mypy/indirection.py b/mypy/indirection.py index b565d53fe61c..0d5b3135560b 100644 --- a/mypy/indirection.py +++ b/mypy/indirection.py @@ -1,6 +1,6 @@ from typing import Dict, Iterable, List, Optional, Set, Union -from mypy.types import SyntheticTypeVisitor +from mypy.types import TypeVisitor import mypy.types as types from mypy.util import split_module_names @@ -15,7 +15,7 @@ def extract_module_names(type_name: Optional[str]) -> List[str]: return [] -class TypeIndirectionVisitor(SyntheticTypeVisitor[Set[str]]): +class TypeIndirectionVisitor(TypeVisitor[Set[str]]): """Returns all module references within a particular type.""" def __init__(self) -> None: @@ -39,12 +39,6 @@ def _visit(self, typ_or_typs: Union[types.Type, Iterable[types.Type]]) -> Set[st def visit_unbound_type(self, t: types.UnboundType) -> Set[str]: return self._visit(t.args) - def visit_type_list(self, t: types.TypeList) -> Set[str]: - return self._visit(t.items) - - def visit_callable_argument(self, t: types.CallableArgument) -> Set[str]: - return self._visit(t.typ) - def visit_any(self, t: types.AnyType) -> Set[str]: return set() @@ -90,23 +84,14 @@ 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_raw_expression_type(self, t: types.RawExpressionType) -> Set[str]: - assert False, "Unexpected RawExpressionType after semantic analysis phase" - 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() - def visit_union_type(self, t: types.UnionType) -> Set[str]: return self._visit(t.items) def visit_partial_type(self, t: types.PartialType) -> Set[str]: return set() - def visit_ellipsis_type(self, t: types.EllipsisType) -> Set[str]: - return set() - def visit_type_type(self, t: types.TypeType) -> Set[str]: return self._visit(t.item) diff --git a/mypy/server/astmerge.py b/mypy/server/astmerge.py index 41b483a56502..ab3ce0e56c56 100644 --- a/mypy/server/astmerge.py +++ b/mypy/server/astmerge.py @@ -56,10 +56,10 @@ ) from mypy.traverser import TraverserVisitor from mypy.types import ( - Type, SyntheticTypeVisitor, Instance, AnyType, NoneType, CallableType, DeletedType, + Type, SyntheticTypeVisitor, Instance, AnyType, NoneType, CallableType, ErasedType, DeletedType, TupleType, TypeType, TypeVarType, TypedDictType, UnboundType, UninhabitedType, UnionType, Overloaded, TypeVarDef, TypeList, CallableArgument, EllipsisType, StarType, LiteralType, - RawExpressionType, PartialType, + RawExpressionType, PartialType, PlaceholderType, ) from mypy.util import get_prefix, replace_object_state from mypy.typestate import TypeState @@ -373,6 +373,10 @@ def visit_overloaded(self, t: Overloaded) -> None: if t.fallback is not None: t.fallback.accept(self) + def visit_erased_type(self, t: ErasedType) -> None: + # This type should exist only temporarily during type inference + raise RuntimeError + def visit_deleted_type(self, typ: DeletedType) -> None: pass @@ -429,6 +433,10 @@ def visit_union_type(self, typ: UnionType) -> None: for item in typ.items: item.accept(self) + def visit_placeholder_type(self, t: PlaceholderType) -> None: + for item in t.args: + item.accept(self) + # Helpers def fixup(self, node: SN) -> SN: diff --git a/mypy/server/deps.py b/mypy/server/deps.py index 6a35f1541af4..db457e3e9c72 100644 --- a/mypy/server/deps.py +++ b/mypy/server/deps.py @@ -96,7 +96,7 @@ class 'mod.Cls'. This can also refer to an attribute inherited from a from mypy.types import ( Type, Instance, AnyType, NoneType, TypeVisitor, CallableType, DeletedType, PartialType, TupleType, TypeType, TypeVarType, TypedDictType, UnboundType, UninhabitedType, UnionType, - FunctionLike, Overloaded, TypeOfAny, LiteralType, get_proper_type, ProperType + FunctionLike, Overloaded, TypeOfAny, LiteralType, ErasedType, get_proper_type, ProperType ) from mypy.server.trigger import make_trigger, make_wildcard_trigger from mypy.util import correct_relative_import @@ -901,6 +901,10 @@ def visit_overloaded(self, typ: Overloaded) -> List[str]: triggers.extend(self.get_type_triggers(item)) return triggers + def visit_erased_type(self, t: ErasedType) -> List[str]: + # This type should exist only temporarily during type inference + assert False, "Should not see an erased type here" + def visit_deleted_type(self, typ: DeletedType) -> List[str]: return [] diff --git a/mypy/type_visitor.py b/mypy/type_visitor.py index 17cf2b059cb6..7f001eed1f33 100644 --- a/mypy/type_visitor.py +++ b/mypy/type_visitor.py @@ -34,12 +34,6 @@ class TypeVisitor(Generic[T]): The parameter T is the return type of the visit methods. """ - def _notimplemented_helper(self, name: str) -> NotImplementedError: - return NotImplementedError("Method {}.visit_{}() not implemented\n" - .format(type(self).__name__, name) - + "This is a known bug, track development in " - + "'https://github.com/JukkaL/mypy/issues/730'") - @abstractmethod def visit_unbound_type(self, t: UnboundType) -> T: pass @@ -56,8 +50,9 @@ def visit_none_type(self, t: NoneType) -> T: def visit_uninhabited_type(self, t: UninhabitedType) -> T: pass + @abstractmethod def visit_erased_type(self, t: ErasedType) -> T: - raise self._notimplemented_helper('erased_type') + pass @abstractmethod def visit_deleted_type(self, t: DeletedType) -> T: @@ -75,8 +70,9 @@ def visit_instance(self, t: Instance) -> T: def visit_callable_type(self, t: CallableType) -> T: pass + @abstractmethod def visit_overloaded(self, t: Overloaded) -> T: - raise self._notimplemented_helper('overloaded') + pass @abstractmethod def visit_tuple_type(self, t: TupleType) -> T: @@ -105,9 +101,6 @@ def visit_type_type(self, t: TypeType) -> T: def visit_type_alias_type(self, t: TypeAliasType) -> T: raise NotImplementedError('TODO') - def visit_placeholder_type(self, t: PlaceholderType) -> T: - raise RuntimeError('Internal error: unresolved placeholder type {}'.format(t.fullname)) - @trait class SyntheticTypeVisitor(TypeVisitor[T]): @@ -135,6 +128,10 @@ def visit_ellipsis_type(self, t: EllipsisType) -> T: def visit_raw_expression_type(self, t: RawExpressionType) -> T: pass + @abstractmethod + def visit_placeholder_type(self, t: PlaceholderType) -> T: + pass + @trait class TypeTranslator(TypeVisitor[Type]): @@ -235,9 +232,6 @@ def visit_overloaded(self, t: Overloaded) -> Type: def visit_type_type(self, t: TypeType) -> Type: return TypeType.make_normalized(t.item.accept(self), line=t.line, column=t.column) - def visit_placeholder_type(self, t: PlaceholderType) -> Type: - return PlaceholderType(t.fullname, self.translate_types(t.args), t.line) - @trait class TypeQuery(SyntheticTypeVisitor[T]): diff --git a/mypy/typeanal.py b/mypy/typeanal.py index c05a599e878d..5b810193ed21 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -13,10 +13,10 @@ from mypy.options import Options from mypy.types import ( Type, UnboundType, TypeVarType, TupleType, TypedDictType, UnionType, Instance, AnyType, - CallableType, NoneType, DeletedType, TypeList, TypeVarDef, SyntheticTypeVisitor, + CallableType, NoneType, ErasedType, DeletedType, TypeList, TypeVarDef, SyntheticTypeVisitor, StarType, PartialType, EllipsisType, UninhabitedType, TypeType, replace_alias_tvars, CallableArgument, get_type_vars, TypeQuery, union_items, TypeOfAny, - LiteralType, RawExpressionType, PlaceholderType, get_proper_type, ProperType + LiteralType, RawExpressionType, PlaceholderType, Overloaded, get_proper_type, ProperType ) from mypy.nodes import ( @@ -456,6 +456,10 @@ def visit_none_type(self, t: NoneType) -> Type: def visit_uninhabited_type(self, t: UninhabitedType) -> Type: return t + def visit_erased_type(self, t: ErasedType) -> Type: + # This type should exist only temporarily during type inference + assert False, "Internal error: Unexpected erased type" + def visit_deleted_type(self, t: DeletedType) -> Type: return t @@ -490,6 +494,14 @@ def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type: variables=self.anal_var_defs(variables)) return ret + def visit_overloaded(self, t: Overloaded) -> Type: + # Overloaded types are manually constructed in semanal.py by analyzing the + # AST and combining together the Callable types this visitor converts. + # + # So if we're ever asked to reanalyze an Overloaded type, we know it's + # fine to just return it as-is. + return t + def visit_tuple_type(self, t: TupleType) -> Type: # Types such as (t1, t2, ...) only allowed in assignment statements. They'll # generate errors elsewhere, and Tuple[t1, t2, ...] must be used instead. diff --git a/mypy/types.py b/mypy/types.py index ad00a18830fd..528a5b5a696e 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1947,6 +1947,7 @@ def __init__(self, fullname: Optional[str], args: List[Type], line: int) -> None self.args = args def accept(self, visitor: 'TypeVisitor[T]') -> T: + assert isinstance(visitor, SyntheticTypeVisitor) return visitor.visit_placeholder_type(self) def serialize(self) -> str: