From 107812448e47021fabb80d2d814902459b1052cb Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 9 Sep 2022 12:49:35 +0300 Subject: [PATCH 1/2] refactor: Use `@overload` for `expand_type` --- mypy/checker.py | 1 - mypy/checkexpr.py | 2 +- mypy/checkmember.py | 4 ++-- mypy/expandtype.py | 25 +++++++++++++++++++++---- mypy/maptype.py | 3 +-- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 32b8d5a5a170..7e3aa2e91ee5 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -6762,7 +6762,6 @@ def overload_can_never_match(signature: CallableType, other: CallableType) -> bo exp_signature = expand_type( signature, {tvar.id: erase_def_to_union_or_bound(tvar) for tvar in signature.variables} ) - assert isinstance(exp_signature, ProperType) assert isinstance(exp_signature, CallableType) return is_callable_compatible( exp_signature, other, is_compat=is_more_precise, ignore_return=True diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 567d64fa05fa..a07a1a1c9258 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1506,7 +1506,7 @@ def analyze_type_type_callee(self, item: ProperType, context: Context) -> Type: res = type_object_type(item.type, self.named_type) if isinstance(res, CallableType): res = res.copy_modified(from_type_type=True) - expanded = get_proper_type(expand_type_by_instance(res, item)) + expanded = expand_type_by_instance(res, item) if isinstance(expanded, CallableType): # Callee of the form Type[...] should never be generic, only # proper class objects can be. diff --git a/mypy/checkmember.py b/mypy/checkmember.py index ef5f8ec484e3..89199cf8f553 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -731,7 +731,7 @@ def analyze_var( signature, dispatched_type, var.is_classmethod, mx.context, name, mx.msg ) signature = bind_self(signature, mx.self_type, var.is_classmethod) - expanded_signature = get_proper_type(expand_type_by_instance(signature, itype)) + expanded_signature = expand_type_by_instance(signature, itype) freeze_type_vars(expanded_signature) if var.is_property: # A property cannot have an overloaded type => the cast is fine. @@ -1111,7 +1111,7 @@ class B(A[str]): pass ] ) if isuper is not None: - t = cast(ProperType, expand_type_by_instance(t, isuper)) + t = expand_type_by_instance(t, isuper) return t diff --git a/mypy/expandtype.py b/mypy/expandtype.py index c8d15566e810..77bbb90faafb 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Iterable, Mapping, Sequence, TypeVar, cast +from typing import Iterable, Mapping, Sequence, TypeVar, cast, overload from mypy.types import ( AnyType, @@ -37,18 +37,36 @@ from mypy.typevartuples import split_with_instance, split_with_prefix_and_suffix +@overload +def expand_type(typ: ProperType, env: Mapping[TypeVarId, Type]) -> ProperType: + ... + + +@overload +def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: + ... + + def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: """Substitute any type variable references in a type given by a type environment. """ - # TODO: use an overloaded signature? (ProperType stays proper after expansion.) return typ.accept(ExpandTypeVisitor(env)) +@overload +def expand_type_by_instance(typ: ProperType, instance: Instance) -> ProperType: + ... + + +@overload +def expand_type_by_instance(typ: Type, instance: Instance) -> Type: + ... + + def expand_type_by_instance(typ: Type, instance: Instance) -> Type: """Substitute type variables in type using values from an Instance. Type variables are considered to be bound by the class declaration.""" - # TODO: use an overloaded signature? (ProperType stays proper after expansion.) if not instance.args: return typ else: @@ -87,7 +105,6 @@ def freshen_function_type_vars(callee: F) -> F: tvs = [] tvmap: dict[TypeVarId, Type] = {} for v in callee.variables: - # TODO(PEP612): fix for ParamSpecType if isinstance(v, TypeVarType): tv: TypeVarLikeType = TypeVarType.new_unification_variable(v) elif isinstance(v, TypeVarTupleType): diff --git a/mypy/maptype.py b/mypy/maptype.py index 2cec20a03189..f86c014166c2 100644 --- a/mypy/maptype.py +++ b/mypy/maptype.py @@ -37,7 +37,7 @@ def map_instance_to_supertype(instance: Instance, superclass: TypeInfo) -> Insta # Unfortunately we can't support this for generic recursive tuples. # If we skip this special casing we will fall back to tuple[Any, ...]. env = instance_to_type_environment(instance) - tuple_type = get_proper_type(expand_type(instance.type.tuple_type, env)) + tuple_type = expand_type(instance.type.tuple_type, env) if isinstance(tuple_type, TupleType): return mypy.typeops.tuple_fallback(tuple_type) @@ -101,7 +101,6 @@ def map_instance_to_direct_supertypes(instance: Instance, supertype: TypeInfo) - if b.type == supertype: env = instance_to_type_environment(instance) t = expand_type(b, env) - assert isinstance(t, ProperType) assert isinstance(t, Instance) result.append(t) From bc935d9151476add232b8a0670e1f0d46f38b20a Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Fri, 9 Sep 2022 12:58:51 +0300 Subject: [PATCH 2/2] Update maptype.py --- mypy/maptype.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/mypy/maptype.py b/mypy/maptype.py index f86c014166c2..b0f19376b4a2 100644 --- a/mypy/maptype.py +++ b/mypy/maptype.py @@ -3,17 +3,7 @@ import mypy.typeops from mypy.expandtype import expand_type from mypy.nodes import TypeInfo -from mypy.types import ( - AnyType, - Instance, - ProperType, - TupleType, - Type, - TypeOfAny, - TypeVarId, - get_proper_type, - has_type_vars, -) +from mypy.types import AnyType, Instance, TupleType, Type, TypeOfAny, TypeVarId, has_type_vars def map_instance_to_supertype(instance: Instance, superclass: TypeInfo) -> Instance: