@@ -313,9 +313,14 @@ def _expand_once(self) -> Type:
313
313
# as their target.
314
314
assert isinstance (self .alias .target , Instance ) # type: ignore[misc]
315
315
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 )}
318
318
)
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
319
324
320
325
def _partial_expansion (self , nothing_args : bool = False ) -> tuple [ProperType , bool ]:
321
326
# Private method mostly for debugging and testing.
@@ -3243,49 +3248,6 @@ def is_named_instance(t: Type, fullnames: str | tuple[str, ...]) -> TypeGuard[In
3243
3248
return isinstance (t , Instance ) and t .type .fullname in fullnames
3244
3249
3245
3250
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
-
3289
3251
class LocationSetter (TypeTraverserVisitor ):
3290
3252
# TODO: Should we update locations of other Type subclasses?
3291
3253
def __init__ (self , line : int , column : int ) -> None :
@@ -3298,20 +3260,6 @@ def visit_instance(self, typ: Instance) -> None:
3298
3260
super ().visit_instance (typ )
3299
3261
3300
3262
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
-
3315
3263
class HasTypeVars (BoolTypeQuery ):
3316
3264
def __init__ (self ) -> None :
3317
3265
super ().__init__ (ANY_STRATEGY )
@@ -3408,36 +3356,20 @@ def callable_with_ellipsis(any_type: AnyType, ret_type: Type, fallback: Instance
3408
3356
)
3409
3357
3410
3358
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