@@ -2856,6 +2856,21 @@ def _check_generic(cls, parameters, elen):
28562856if not _PEP_696_IMPLEMENTED :
28572857 typing ._check_generic = _check_generic
28582858
2859+
2860+ _TYPEVARTUPLE_TYPES = {TypeVarTuple , getattr (typing , "TypeVarTuple" , None )}
2861+
2862+
2863+ def _is_unpacked_typevartuple (x ) -> bool :
2864+ if get_origin (x ) is not Unpack :
2865+ return False
2866+ args = get_args (x )
2867+ return (
2868+ bool (args )
2869+ and len (args ) == 1
2870+ and type (args [0 ]) in _TYPEVARTUPLE_TYPES
2871+ )
2872+
2873+
28592874# Python 3.11+ _collect_type_vars was renamed to _collect_parameters
28602875if hasattr (typing , '_collect_type_vars' ):
28612876 def _collect_type_vars (types , typevar_types = None ):
@@ -2869,13 +2884,17 @@ def _collect_type_vars(types, typevar_types=None):
28692884 tvars = []
28702885 # required TypeVarLike cannot appear after TypeVarLike with default
28712886 default_encountered = False
2887+ # or after TypeVarTuple
2888+ type_var_tuple_encountered = False
28722889 for t in types :
2873- if (
2874- isinstance (t , typevar_types ) and
2875- t not in tvars and
2876- not _is_unpack (t )
2877- ):
2878- if getattr (t , '__default__' , NoDefault ) is not NoDefault :
2890+ if _is_unpacked_typevartuple (t ):
2891+ type_var_tuple_encountered = True
2892+ elif isinstance (t , typevar_types ) and t not in tvars :
2893+ has_default = getattr (t , '__default__' , NoDefault ) is not NoDefault
2894+ if has_default :
2895+ if type_var_tuple_encountered :
2896+ raise TypeError ('Type parameter with a default'
2897+ ' follows TypeVarTuple' )
28792898 default_encountered = True
28802899 elif default_encountered :
28812900 raise TypeError (f'Type parameter { t !r} without a default'
@@ -2899,6 +2918,8 @@ def _collect_parameters(args):
28992918 parameters = []
29002919 # required TypeVarLike cannot appear after TypeVarLike with default
29012920 default_encountered = False
2921+ # or after TypeVarTuple
2922+ type_var_tuple_encountered = False
29022923 for t in args :
29032924 if isinstance (t , type ):
29042925 # We don't want __parameters__ descriptor of a bare Python class.
@@ -2912,14 +2933,22 @@ def _collect_parameters(args):
29122933 parameters .append (collected )
29132934 elif hasattr (t , '__typing_subst__' ):
29142935 if t not in parameters :
2915- if getattr (t , '__default__' , NoDefault ) is not NoDefault :
2936+ has_default = getattr (t , '__default__' , NoDefault ) is not NoDefault
2937+
2938+ if type_var_tuple_encountered and has_default :
2939+ raise TypeError ('Type parameter with a default'
2940+ ' follows TypeVarTuple' )
2941+
2942+ if has_default :
29162943 default_encountered = True
29172944 elif default_encountered :
29182945 raise TypeError (f'Type parameter { t !r} without a default'
29192946 ' follows type parameter with a default' )
29202947
29212948 parameters .append (t )
29222949 else :
2950+ if _is_unpacked_typevartuple (t ):
2951+ type_var_tuple_encountered = True
29232952 for x in getattr (t , '__parameters__' , ()):
29242953 if x not in parameters :
29252954 parameters .append (x )
0 commit comments