@@ -1808,7 +1808,26 @@ def analyze_type_param(
18081808 upper_bound = self .named_type ("builtins.tuple" , [self .object_type ()])
18091809 else :
18101810 upper_bound = self .object_type ()
1811- default = AnyType (TypeOfAny .from_omitted_generics )
1811+ if type_param .default :
1812+ default = self .anal_type (
1813+ type_param .default ,
1814+ allow_placeholder = True ,
1815+ allow_unbound_tvars = True ,
1816+ report_invalid_types = False ,
1817+ allow_param_spec_literals = type_param .kind == PARAM_SPEC_KIND ,
1818+ allow_tuple_literal = type_param .kind == PARAM_SPEC_KIND ,
1819+ allow_unpack = type_param .kind == TYPE_VAR_TUPLE_KIND ,
1820+ )
1821+ if default is None :
1822+ default = PlaceholderType (None , [], context .line )
1823+ elif type_param .kind == TYPE_VAR_KIND :
1824+ default = self .check_typevar_default (default , type_param .default )
1825+ elif type_param .kind == PARAM_SPEC_KIND :
1826+ default = self .check_paramspec_default (default , type_param .default )
1827+ elif type_param .kind == TYPE_VAR_TUPLE_KIND :
1828+ default = self .check_typevartuple_default (default , type_param .default )
1829+ else :
1830+ default = AnyType (TypeOfAny .from_omitted_generics )
18121831 if type_param .kind == TYPE_VAR_KIND :
18131832 values = []
18141833 if type_param .values :
@@ -2243,21 +2262,7 @@ class Foo(Bar, Generic[T]): ...
22432262 # grained incremental mode.
22442263 defn .removed_base_type_exprs .append (defn .base_type_exprs [i ])
22452264 del base_type_exprs [i ]
2246- tvar_defs : list [TypeVarLikeType ] = []
2247- last_tvar_name_with_default : str | None = None
2248- for name , tvar_expr in declared_tvars :
2249- tvar_expr .default = tvar_expr .default .accept (
2250- TypeVarDefaultTranslator (self , tvar_expr .name , context )
2251- )
2252- tvar_def = self .tvar_scope .bind_new (name , tvar_expr )
2253- if last_tvar_name_with_default is not None and not tvar_def .has_default ():
2254- self .msg .tvar_without_default_type (
2255- tvar_def .name , last_tvar_name_with_default , context
2256- )
2257- tvar_def .default = AnyType (TypeOfAny .from_error )
2258- elif tvar_def .has_default ():
2259- last_tvar_name_with_default = tvar_def .name
2260- tvar_defs .append (tvar_def )
2265+ tvar_defs = self .tvar_defs_from_tvars (declared_tvars , context )
22612266 return base_type_exprs , tvar_defs , is_protocol
22622267
22632268 def analyze_class_typevar_declaration (self , base : Type ) -> tuple [TypeVarLikeList , bool ] | None :
@@ -2358,6 +2363,26 @@ def get_all_bases_tvars(
23582363 tvars .extend (base_tvars )
23592364 return remove_dups (tvars )
23602365
2366+ def tvar_defs_from_tvars (
2367+ self , tvars : TypeVarLikeList , context : Context
2368+ ) -> list [TypeVarLikeType ]:
2369+ tvar_defs : list [TypeVarLikeType ] = []
2370+ last_tvar_name_with_default : str | None = None
2371+ for name , tvar_expr in tvars :
2372+ tvar_expr .default = tvar_expr .default .accept (
2373+ TypeVarDefaultTranslator (self , tvar_expr .name , context )
2374+ )
2375+ tvar_def = self .tvar_scope .bind_new (name , tvar_expr )
2376+ if last_tvar_name_with_default is not None and not tvar_def .has_default ():
2377+ self .msg .tvar_without_default_type (
2378+ tvar_def .name , last_tvar_name_with_default , context
2379+ )
2380+ tvar_def .default = AnyType (TypeOfAny .from_error )
2381+ elif tvar_def .has_default ():
2382+ last_tvar_name_with_default = tvar_def .name
2383+ tvar_defs .append (tvar_def )
2384+ return tvar_defs
2385+
23612386 def get_and_bind_all_tvars (self , type_exprs : list [Expression ]) -> list [TypeVarLikeType ]:
23622387 """Return all type variable references in item type expressions.
23632388
@@ -3833,21 +3858,8 @@ def analyze_alias(
38333858 tvar_defs : list [TypeVarLikeType ] = []
38343859 namespace = self .qualified_name (name )
38353860 alias_type_vars = found_type_vars if declared_type_vars is None else declared_type_vars
3836- last_tvar_name_with_default : str | None = None
38373861 with self .tvar_scope_frame (self .tvar_scope .class_frame (namespace )):
3838- for name , tvar_expr in alias_type_vars :
3839- tvar_expr .default = tvar_expr .default .accept (
3840- TypeVarDefaultTranslator (self , tvar_expr .name , typ )
3841- )
3842- tvar_def = self .tvar_scope .bind_new (name , tvar_expr )
3843- if last_tvar_name_with_default is not None and not tvar_def .has_default ():
3844- self .msg .tvar_without_default_type (
3845- tvar_def .name , last_tvar_name_with_default , typ
3846- )
3847- tvar_def .default = AnyType (TypeOfAny .from_error )
3848- elif tvar_def .has_default ():
3849- last_tvar_name_with_default = tvar_def .name
3850- tvar_defs .append (tvar_def )
3862+ tvar_defs = self .tvar_defs_from_tvars (alias_type_vars , typ )
38513863
38523864 if python_3_12_type_alias :
38533865 with self .allow_unbound_tvars_set ():
@@ -4615,6 +4627,40 @@ def process_typevar_declaration(self, s: AssignmentStmt) -> bool:
46154627 self .add_symbol (name , call .analyzed , s )
46164628 return True
46174629
4630+ def check_typevar_default (self , default : Type , context : Context ) -> Type :
4631+ typ = get_proper_type (default )
4632+ if isinstance (typ , AnyType ) and typ .is_from_error :
4633+ self .fail (
4634+ message_registry .TYPEVAR_ARG_MUST_BE_TYPE .format ("TypeVar" , "default" ), context
4635+ )
4636+ return default
4637+
4638+ def check_paramspec_default (self , default : Type , context : Context ) -> Type :
4639+ typ = get_proper_type (default )
4640+ if isinstance (typ , Parameters ):
4641+ for i , arg_type in enumerate (typ .arg_types ):
4642+ arg_ptype = get_proper_type (arg_type )
4643+ if isinstance (arg_ptype , AnyType ) and arg_ptype .is_from_error :
4644+ self .fail (f"Argument { i } of ParamSpec default must be a type" , context )
4645+ elif (
4646+ isinstance (typ , AnyType )
4647+ and typ .is_from_error
4648+ or not isinstance (typ , (AnyType , UnboundType ))
4649+ ):
4650+ self .fail (
4651+ "The default argument to ParamSpec must be a list expression, ellipsis, or a ParamSpec" ,
4652+ context ,
4653+ )
4654+ default = AnyType (TypeOfAny .from_error )
4655+ return default
4656+
4657+ def check_typevartuple_default (self , default : Type , context : Context ) -> Type :
4658+ typ = get_proper_type (default )
4659+ if not isinstance (typ , UnpackType ):
4660+ self .fail ("The default argument to TypeVarTuple must be an Unpacked tuple" , context )
4661+ default = AnyType (TypeOfAny .from_error )
4662+ return default
4663+
46184664 def check_typevarlike_name (self , call : CallExpr , name : str , context : Context ) -> bool :
46194665 """Checks that the name of a TypeVar or ParamSpec matches its variable."""
46204666 name = unmangle (name )
@@ -4822,23 +4868,7 @@ def process_paramspec_declaration(self, s: AssignmentStmt) -> bool:
48224868 report_invalid_typevar_arg = False ,
48234869 )
48244870 default = tv_arg or AnyType (TypeOfAny .from_error )
4825- if isinstance (tv_arg , Parameters ):
4826- for i , arg_type in enumerate (tv_arg .arg_types ):
4827- typ = get_proper_type (arg_type )
4828- if isinstance (typ , AnyType ) and typ .is_from_error :
4829- self .fail (
4830- f"Argument { i } of ParamSpec default must be a type" , param_value
4831- )
4832- elif (
4833- isinstance (default , AnyType )
4834- and default .is_from_error
4835- or not isinstance (default , (AnyType , UnboundType ))
4836- ):
4837- self .fail (
4838- "The default argument to ParamSpec must be a list expression, ellipsis, or a ParamSpec" ,
4839- param_value ,
4840- )
4841- default = AnyType (TypeOfAny .from_error )
4871+ default = self .check_paramspec_default (default , param_value )
48424872 else :
48434873 # ParamSpec is different from a regular TypeVar:
48444874 # arguments are not semantically valid. But, allowed in runtime.
@@ -4899,12 +4929,7 @@ def process_typevartuple_declaration(self, s: AssignmentStmt) -> bool:
48994929 allow_unpack = True ,
49004930 )
49014931 default = tv_arg or AnyType (TypeOfAny .from_error )
4902- if not isinstance (default , UnpackType ):
4903- self .fail (
4904- "The default argument to TypeVarTuple must be an Unpacked tuple" ,
4905- param_value ,
4906- )
4907- default = AnyType (TypeOfAny .from_error )
4932+ default = self .check_typevartuple_default (default , param_value )
49084933 else :
49094934 self .fail (f'Unexpected keyword argument "{ param_name } " for "TypeVarTuple"' , s )
49104935
@@ -5503,6 +5528,7 @@ def visit_type_alias_stmt(self, s: TypeAliasStmt) -> None:
55035528 eager = eager ,
55045529 python_3_12_type_alias = True ,
55055530 )
5531+ s .alias_node = alias_node
55065532
55075533 if (
55085534 existing
0 commit comments