@@ -212,6 +212,21 @@ def _check_generic(cls, parameters, elen):
212
212
raise TypeError (f"Too { 'many' if alen > elen else 'few' } parameters for { cls } ;"
213
213
f" actual { alen } , expected { elen } " )
214
214
215
+ def _prepare_paramspec_params (cls , params ):
216
+ """Prepares the parameters for a Generic containing ParamSpec
217
+ variables (internal helper).
218
+ """
219
+ # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
220
+ if len (cls .__parameters__ ) == 1 and len (params ) > 1 :
221
+ return params ,
222
+ else :
223
+ _params = []
224
+ # Convert lists to tuples to help other libraries cache the results.
225
+ for p , tvar in zip (params , cls .__parameters__ ):
226
+ if isinstance (tvar , ParamSpec ) and isinstance (p , list ):
227
+ p = tuple (p )
228
+ _params .append (p )
229
+ return tuple (_params )
215
230
216
231
def _deduplicate (params ):
217
232
# Weed out strict duplicates, preserving the first of each occurrence.
@@ -881,21 +896,26 @@ def __getitem__(self, params):
881
896
raise TypeError (f"Cannot subscript already-subscripted { self } " )
882
897
if not isinstance (params , tuple ):
883
898
params = (params ,)
884
- msg = "Parameters to generic types must be types."
885
- params = tuple (_type_check (p , msg ) for p in params )
899
+ params = tuple (_type_convert (p ) for p in params )
900
+ if any (isinstance (t , ParamSpec ) for t in self .__parameters__ ):
901
+ params = _prepare_paramspec_params (self , params )
886
902
_check_generic (self , params , len (self .__parameters__ ))
887
903
888
904
subst = dict (zip (self .__parameters__ , params ))
889
905
new_args = []
890
906
for arg in self .__args__ :
891
- if isinstance (arg , TypeVar ):
907
+ if isinstance (arg , ( TypeVar , ParamSpec ) ):
892
908
arg = subst [arg ]
893
909
elif isinstance (arg , (_GenericAlias , GenericAlias )):
894
910
subparams = arg .__parameters__
895
911
if subparams :
896
912
subargs = tuple (subst [x ] for x in subparams )
897
913
arg = arg [subargs ]
898
- new_args .append (arg )
914
+ # Required to flatten out the args for CallableGenericAlias
915
+ if self .__origin__ == collections .abc .Callable and isinstance (arg , tuple ):
916
+ new_args .extend (arg )
917
+ else :
918
+ new_args .append (arg )
899
919
return self .copy_with (tuple (new_args ))
900
920
901
921
def copy_with (self , params ):
@@ -1140,22 +1160,8 @@ def __class_getitem__(cls, params):
1140
1160
else :
1141
1161
# Subscripting a regular Generic subclass.
1142
1162
1143
- # Code below handles PEP 612 ParamSpec.
1144
1163
if any (isinstance (t , ParamSpec ) for t in cls .__parameters__ ):
1145
- # Special case where Z[[int, str, bool]] == Z[int, str, bool]
1146
- # in PEP 612.
1147
- if len (cls .__parameters__ ) == 1 and len (params ) > 1 :
1148
- params = (params ,)
1149
- else :
1150
- _params = []
1151
- # Convert lists to tuples to help other libraries cache the
1152
- # results.
1153
- for p , tvar in zip (params , cls .__parameters__ ):
1154
- if isinstance (tvar , ParamSpec ) and isinstance (p , list ):
1155
- p = tuple (p )
1156
- _params .append (p )
1157
- params = tuple (_params )
1158
-
1164
+ params = _prepare_paramspec_params (cls , params )
1159
1165
_check_generic (cls , params , len (cls .__parameters__ ))
1160
1166
return _GenericAlias (cls , params )
1161
1167
0 commit comments