@@ -1992,38 +1992,42 @@ def analyze_class_typevar_declaration(self, base: Type) -> tuple[TypeVarLikeList
19921992 return None
19931993
19941994 def analyze_unbound_tvar (self , t : Type ) -> tuple [str , TypeVarLikeExpr ] | None :
1995- if not isinstance (t , UnboundType ):
1996- return None
1997- unbound = t
1998- sym = self .lookup_qualified (unbound .name , unbound )
1995+ if isinstance (t , UnpackType ) and isinstance (t .type , UnboundType ):
1996+ return self .analyze_unbound_tvar_impl (t .type , allow_tvt = True )
1997+ if isinstance (t , UnboundType ):
1998+ sym = self .lookup_qualified (t .name , t )
1999+ if sym and sym .fullname in ("typing.Unpack" , "typing_extensions.Unpack" ):
2000+ inner_t = t .args [0 ]
2001+ if isinstance (inner_t , UnboundType ):
2002+ return self .analyze_unbound_tvar_impl (inner_t , allow_tvt = True )
2003+ return None
2004+ return self .analyze_unbound_tvar_impl (t )
2005+ return None
2006+
2007+ def analyze_unbound_tvar_impl (
2008+ self , t : UnboundType , allow_tvt : bool = False
2009+ ) -> tuple [str , TypeVarLikeExpr ] | None :
2010+ sym = self .lookup_qualified (t .name , t )
19992011 if sym and isinstance (sym .node , PlaceholderNode ):
20002012 self .record_incomplete_ref ()
2001- if sym and isinstance (sym .node , ParamSpecExpr ):
2013+ if not allow_tvt and sym and isinstance (sym .node , ParamSpecExpr ):
20022014 if sym .fullname and not self .tvar_scope .allow_binding (sym .fullname ):
20032015 # It's bound by our type variable scope
20042016 return None
2005- return unbound .name , sym .node
2006- if sym and sym . fullname in ( "typing.Unpack" , "typing_extensions.Unpack" ):
2007- inner_t = unbound . args [ 0 ]
2008- if not isinstance ( inner_t , UnboundType ):
2017+ return t .name , sym .node
2018+ if allow_tvt and sym and isinstance ( sym . node , TypeVarTupleExpr ):
2019+ if sym . fullname and not self . tvar_scope . allow_binding ( sym . fullname ):
2020+ # It's bound by our type variable scope
20092021 return None
2010- inner_unbound = inner_t
2011- inner_sym = self .lookup_qualified (inner_unbound .name , inner_unbound )
2012- if inner_sym and isinstance (inner_sym .node , PlaceholderNode ):
2013- self .record_incomplete_ref ()
2014- if inner_sym and isinstance (inner_sym .node , TypeVarTupleExpr ):
2015- if inner_sym .fullname and not self .tvar_scope .allow_binding (inner_sym .fullname ):
2016- # It's bound by our type variable scope
2017- return None
2018- return inner_unbound .name , inner_sym .node
2019- if sym is None or not isinstance (sym .node , TypeVarExpr ):
2022+ return t .name , sym .node
2023+ if sym is None or not isinstance (sym .node , TypeVarExpr ) or allow_tvt :
20202024 return None
20212025 elif sym .fullname and not self .tvar_scope .allow_binding (sym .fullname ):
20222026 # It's bound by our type variable scope
20232027 return None
20242028 else :
20252029 assert isinstance (sym .node , TypeVarExpr )
2026- return unbound .name , sym .node
2030+ return t .name , sym .node
20272031
20282032 def get_all_bases_tvars (
20292033 self , base_type_exprs : list [Expression ], removed : list [int ]
@@ -5333,7 +5337,9 @@ def analyze_type_application_args(self, expr: IndexExpr) -> list[Type] | None:
53335337 has_param_spec = False
53345338 num_args = - 1
53355339 elif isinstance (base , RefExpr ) and isinstance (base .node , TypeInfo ):
5336- allow_unpack = base .node .has_type_var_tuple_type
5340+ allow_unpack = (
5341+ base .node .has_type_var_tuple_type or base .node .fullname == "builtins.tuple"
5342+ )
53375343 has_param_spec = base .node .has_param_spec_type
53385344 num_args = len (base .node .type_vars )
53395345 else :
@@ -5343,7 +5349,7 @@ def analyze_type_application_args(self, expr: IndexExpr) -> list[Type] | None:
53435349
53445350 for item in items :
53455351 try :
5346- typearg = self .expr_to_unanalyzed_type (item )
5352+ typearg = self .expr_to_unanalyzed_type (item , allow_unpack = True )
53475353 except TypeTranslationError :
53485354 self .fail ("Type expected within [...]" , expr )
53495355 return None
@@ -6608,8 +6614,10 @@ def type_analyzer(
66086614 tpan .global_scope = not self .type and not self .function_stack
66096615 return tpan
66106616
6611- def expr_to_unanalyzed_type (self , node : Expression ) -> ProperType :
6612- return expr_to_unanalyzed_type (node , self .options , self .is_stub_file )
6617+ def expr_to_unanalyzed_type (self , node : Expression , allow_unpack : bool = False ) -> ProperType :
6618+ return expr_to_unanalyzed_type (
6619+ node , self .options , self .is_stub_file , allow_unpack = allow_unpack
6620+ )
66136621
66146622 def anal_type (
66156623 self ,
0 commit comments