@@ -313,9 +313,14 @@ def _expand_once(self) -> Type:
313313 # as their target.
314314 assert isinstance (self .alias .target , Instance ) # type: ignore[misc]
315315 return self .alias .target .copy_modified (args = self .args )
316- return replace_alias_tvars (
317- self . alias . target , self .alias .alias_tvars , self .args , self . line , self . column
316+ replacer = InstantiateAliasVisitor (
317+ { v . id : s for ( v , s ) in zip ( self .alias .alias_tvars , self .args )}
318318 )
319+ new_tp = self .alias .target .accept (replacer )
320+ new_tp .accept (LocationSetter (self .line , self .column ))
321+ new_tp .line = self .line
322+ new_tp .column = self .column
323+ return new_tp
319324
320325 def _partial_expansion (self , nothing_args : bool = False ) -> tuple [ProperType , bool ]:
321326 # Private method mostly for debugging and testing.
@@ -3243,49 +3248,6 @@ def is_named_instance(t: Type, fullnames: str | tuple[str, ...]) -> TypeGuard[In
32433248 return isinstance (t , Instance ) and t .type .fullname in fullnames
32443249
32453250
3246- class InstantiateAliasVisitor (TrivialSyntheticTypeTranslator ):
3247- def __init__ (self , vars : list [TypeVarLikeType ], subs : list [Type ]) -> None :
3248- self .replacements = {v .id : s for (v , s ) in zip (vars , subs )}
3249-
3250- def visit_type_alias_type (self , typ : TypeAliasType ) -> Type :
3251- return typ .copy_modified (args = [t .accept (self ) for t in typ .args ])
3252-
3253- def visit_type_var (self , typ : TypeVarType ) -> Type :
3254- if typ .id in self .replacements :
3255- return self .replacements [typ .id ]
3256- return typ
3257-
3258- def visit_callable_type (self , t : CallableType ) -> Type :
3259- param_spec = t .param_spec ()
3260- if param_spec is not None :
3261- # TODO: this branch duplicates the one in expand_type(), find a way to reuse it
3262- # without import cycle types <-> typeanal <-> expandtype.
3263- repl = get_proper_type (self .replacements .get (param_spec .id ))
3264- if isinstance (repl , (CallableType , Parameters )):
3265- prefix = param_spec .prefix
3266- t = t .expand_param_spec (repl , no_prefix = True )
3267- return t .copy_modified (
3268- arg_types = [t .accept (self ) for t in prefix .arg_types ] + t .arg_types ,
3269- arg_kinds = prefix .arg_kinds + t .arg_kinds ,
3270- arg_names = prefix .arg_names + t .arg_names ,
3271- ret_type = t .ret_type .accept (self ),
3272- type_guard = (t .type_guard .accept (self ) if t .type_guard is not None else None ),
3273- )
3274- return super ().visit_callable_type (t )
3275-
3276- def visit_param_spec (self , typ : ParamSpecType ) -> Type :
3277- if typ .id in self .replacements :
3278- repl = get_proper_type (self .replacements [typ .id ])
3279- # TODO: all the TODOs from same logic in expand_type() apply here.
3280- if isinstance (repl , Instance ):
3281- return repl
3282- elif isinstance (repl , (ParamSpecType , Parameters , CallableType )):
3283- return expand_param_spec (typ , repl )
3284- else :
3285- return repl
3286- return typ
3287-
3288-
32893251class LocationSetter (TypeTraverserVisitor ):
32903252 # TODO: Should we update locations of other Type subclasses?
32913253 def __init__ (self , line : int , column : int ) -> None :
@@ -3298,20 +3260,6 @@ def visit_instance(self, typ: Instance) -> None:
32983260 super ().visit_instance (typ )
32993261
33003262
3301- def replace_alias_tvars (
3302- tp : Type , vars : list [TypeVarLikeType ], subs : list [Type ], newline : int , newcolumn : int
3303- ) -> Type :
3304- """Replace type variables in a generic type alias tp with substitutions subs
3305- resetting context. Length of subs should be already checked.
3306- """
3307- replacer = InstantiateAliasVisitor (vars , subs )
3308- new_tp = tp .accept (replacer )
3309- new_tp .accept (LocationSetter (newline , newcolumn ))
3310- new_tp .line = newline
3311- new_tp .column = newcolumn
3312- return new_tp
3313-
3314-
33153263class HasTypeVars (BoolTypeQuery ):
33163264 def __init__ (self ) -> None :
33173265 super ().__init__ (ANY_STRATEGY )
@@ -3408,36 +3356,20 @@ def callable_with_ellipsis(any_type: AnyType, ret_type: Type, fallback: Instance
34083356 )
34093357
34103358
3411- def expand_param_spec (
3412- t : ParamSpecType , repl : ParamSpecType | Parameters | CallableType
3413- ) -> ProperType :
3414- """This is shared part of the logic w.r.t. ParamSpec instantiation.
3415-
3416- It is shared between type aliases and proper types, that currently use somewhat different
3417- logic for instantiation."""
3418- if isinstance (repl , ParamSpecType ):
3419- return repl .copy_modified (
3420- flavor = t .flavor ,
3421- prefix = t .prefix .copy_modified (
3422- arg_types = t .prefix .arg_types + repl .prefix .arg_types ,
3423- arg_kinds = t .prefix .arg_kinds + repl .prefix .arg_kinds ,
3424- arg_names = t .prefix .arg_names + repl .prefix .arg_names ,
3425- ),
3426- )
3427- else :
3428- # if the paramspec is *P.args or **P.kwargs:
3429- if t .flavor != ParamSpecFlavor .BARE :
3430- assert isinstance (repl , CallableType ), "Should not be able to get here."
3431- # Is this always the right thing to do?
3432- param_spec = repl .param_spec ()
3433- if param_spec :
3434- return param_spec .with_flavor (t .flavor )
3435- else :
3436- return repl
3437- else :
3438- return Parameters (
3439- t .prefix .arg_types + repl .arg_types ,
3440- t .prefix .arg_kinds + repl .arg_kinds ,
3441- t .prefix .arg_names + repl .arg_names ,
3442- variables = [* t .prefix .variables , * repl .variables ],
3443- )
3359+ # This cyclic import is unfortunate, but to avoid it we would need to move away all uses
3360+ # of get_proper_type() from types.py. Majority of them have been removed, but few remaining
3361+ # are quite tricky to get rid of, but ultimately we want to do it at some point.
3362+ from mypy .expandtype import ExpandTypeVisitor
3363+
3364+
3365+ class InstantiateAliasVisitor (ExpandTypeVisitor ):
3366+ def visit_union_type (self , t : UnionType ) -> Type :
3367+ # Unlike regular expand_type(), we don't do any simplification for unions,
3368+ # not even removing strict duplicates. There are three reasons for this:
3369+ # * get_proper_type() is a very hot function, even slightest slow down will
3370+ # cause a perf regression
3371+ # * We want to preserve this historical behaviour, to avoid possible
3372+ # regressions
3373+ # * Simplifying unions may (indirectly) call get_proper_type(), causing
3374+ # infinite recursion.
3375+ return TypeTranslator .visit_union_type (self , t )
0 commit comments