@@ -2338,17 +2338,10 @@ class Foo(Bar, Generic[T]): ...
23382338 removed : list [int ] = []
23392339 declared_tvars : TypeVarLikeList = []
23402340 is_protocol = False
2341- has_type_var_tuple = False
23422341 if defn .type_args is not None :
23432342 for p in defn .type_args :
23442343 node = self .get_defined_type_param (p .name )
2345- assert node is not None
23462344 assert isinstance (node , TypeVarLikeExpr )
2347- if isinstance (node , TypeVarTupleExpr ):
2348- if has_type_var_tuple :
2349- self .fail ("Can only use one type var tuple in a class def" , context )
2350- continue
2351- has_type_var_tuple = True
23522345 declared_tvars .append ((p .name , node ))
23532346
23542347 for i , base_expr in enumerate (base_type_exprs ):
@@ -2361,7 +2354,7 @@ class Foo(Bar, Generic[T]): ...
23612354 except TypeTranslationError :
23622355 # This error will be caught later.
23632356 continue
2364- result = self .analyze_class_typevar_declaration (base , has_type_var_tuple )
2357+ result = self .analyze_class_typevar_declaration (base )
23652358 if result is not None :
23662359 tvars = result [0 ]
23672360 is_protocol |= result [1 ]
@@ -2412,12 +2405,11 @@ class Foo(Bar, Generic[T]): ...
24122405 # grained incremental mode.
24132406 defn .removed_base_type_exprs .append (defn .base_type_exprs [i ])
24142407 del base_type_exprs [i ]
2408+ declared_tvars = self .pre_validate_declared_tvars (declared_tvars , context , "class" )
24152409 tvar_defs = self .tvar_defs_from_tvars (declared_tvars , context )
24162410 return base_type_exprs , tvar_defs , is_protocol , declared_tvars
24172411
2418- def analyze_class_typevar_declaration (
2419- self , base : Type , has_type_var_tuple : bool
2420- ) -> tuple [TypeVarLikeList , bool ] | None :
2412+ def analyze_class_typevar_declaration (self , base : Type ) -> tuple [TypeVarLikeList , bool ] | None :
24212413 """Analyze type variables declared using Generic[...] or Protocol[...].
24222414
24232415 Args:
@@ -2443,11 +2435,6 @@ def analyze_class_typevar_declaration(
24432435 tag = self .track_incomplete_refs ()
24442436 tvar = self .analyze_unbound_tvar (arg )
24452437 if tvar :
2446- if isinstance (tvar [1 ], TypeVarTupleExpr ):
2447- if has_type_var_tuple :
2448- self .fail ("Can only use one type var tuple in a class def" , base )
2449- continue
2450- has_type_var_tuple = True
24512438 tvars .append (tvar )
24522439 elif not self .found_incomplete_ref (tag ):
24532440 self .fail ("Free type variable expected in %s[...]" % sym .node .name , base )
@@ -4083,6 +4070,24 @@ def analyze_simple_literal_type(self, rvalue: Expression, is_final: bool) -> Typ
40834070 return typ .copy_modified (last_known_value = LiteralType (value = value , fallback = typ ))
40844071 return typ
40854072
4073+ def pre_validate_declared_tvars (
4074+ self , declared_tvars : TypeVarLikeList , ctx : Context , kind : str
4075+ ) -> TypeVarLikeList :
4076+ has_type_var_tuple = False
4077+ valid_declared_tvars = []
4078+ for name , node in declared_tvars :
4079+ if isinstance (node , TypeVarTupleExpr ):
4080+ if has_type_var_tuple :
4081+ self .fail (
4082+ f"Can only use one TypeVarTuple in a { kind } definition" ,
4083+ ctx ,
4084+ code = codes .TYPE_VAR ,
4085+ )
4086+ continue
4087+ has_type_var_tuple = True
4088+ valid_declared_tvars .append ((name , node ))
4089+ return valid_declared_tvars
4090+
40864091 def analyze_alias (
40874092 self ,
40884093 name : str ,
@@ -4119,6 +4124,7 @@ def analyze_alias(
41194124 found_type_vars = self .find_type_var_likes (typ )
41204125 namespace = self .qualified_name (name )
41214126 alias_type_vars = found_type_vars if declared_type_vars is None else declared_type_vars
4127+ alias_type_vars = self .pre_validate_declared_tvars (alias_type_vars , rvalue , "type alias" )
41224128 with self .tvar_scope_frame (self .tvar_scope .class_frame (namespace )):
41234129 tvar_defs = self .tvar_defs_from_tvars (alias_type_vars , typ )
41244130
@@ -4426,7 +4432,6 @@ def analyze_type_alias_type_params(
44264432
44274433 declared_tvars : TypeVarLikeList = []
44284434 all_declared_tvar_names : list [str ] = [] # includes bound type variables
4429- have_type_var_tuple = False
44304435 for tp_expr in type_params :
44314436 if isinstance (tp_expr , StarExpr ):
44324437 tp_expr .valid = False
@@ -4440,18 +4445,7 @@ def analyze_type_alias_type_params(
44404445
44414446 tag = self .track_incomplete_refs ()
44424447 tvar = self .analyze_unbound_tvar_impl (base , is_typealias_param = True )
4443- if tvar :
4444- if isinstance (tvar [1 ], TypeVarTupleExpr ):
4445- if have_type_var_tuple :
4446- self .fail (
4447- "Can only use one TypeVarTuple in type_params argument to TypeAliasType" ,
4448- base ,
4449- code = codes .TYPE_VAR ,
4450- )
4451- have_type_var_tuple = True
4452- continue
4453- have_type_var_tuple = True
4454- elif not self .found_incomplete_ref (tag ):
4448+ if not tvar and not self .found_incomplete_ref (tag ):
44554449 sym = self .lookup_qualified (base .name , base )
44564450 if sym and isinstance (sym .node , TypeVarLikeExpr ):
44574451 all_declared_tvar_names .append (sym .node .name ) # Error will be reported later
0 commit comments