@@ -3203,6 +3203,13 @@ def _is_unpacked_typevartuple(x) -> bool:
3203
3203
)
3204
3204
3205
3205
3206
+ def _is_typevar_like (x : Any ) -> bool :
3207
+ tv_types = (TypeVar , ParamSpec , typing .TypeVar )
3208
+ if hasattr ("typing" , "ParamSpec" ):
3209
+ tv_types += typing .ParamSpec
3210
+ return isinstance (x , tv_types ) or _is_unpacked_typevartuple (x )
3211
+
3212
+
3206
3213
# Python 3.11+ _collect_type_vars was renamed to _collect_parameters
3207
3214
if hasattr (typing , '_collect_type_vars' ):
3208
3215
def _collect_type_vars (types , typevar_types = None ):
@@ -4257,6 +4264,60 @@ def type_repr(value):
4257
4264
return repr (value )
4258
4265
4259
4266
4267
+ if sys .version_info < (3 , 11 ):
4268
+ def _generic_class_getitem (cls , params ):
4269
+ """Parameterizes a generic class.
4270
+
4271
+ At least, parameterizing a generic class is the *main* thing this method
4272
+ does. For example, for some generic class `Foo`, this is called when we
4273
+ do `Foo[int]` - there, with `cls=Foo` and `params=int`.
4274
+
4275
+ However, note that this method is also called when defining generic
4276
+ classes in the first place with `class Foo(Generic[T]): ...`.
4277
+ """
4278
+ if not isinstance (params , tuple ):
4279
+ params = (params ,)
4280
+
4281
+ params = tuple (typing ._type_convert (p ) for p in params )
4282
+ if cls in (Generic , Protocol ):
4283
+ # Generic and Protocol can only be subscripted with unique type variables.
4284
+ if not params :
4285
+ raise TypeError (
4286
+ f"Parameter list to { cls .__qualname__ } [...] cannot be empty"
4287
+ )
4288
+ if not all (_is_typevar_like (p ) for p in params ):
4289
+ raise TypeError (
4290
+ f"Parameters to { cls .__name__ } [...] must all be type variables "
4291
+ f"or parameter specification variables."
4292
+ )
4293
+ if len (set (params )) != len (params ):
4294
+ raise TypeError (
4295
+ f"Parameters to { cls .__name__ } [...] must all be unique"
4296
+ )
4297
+ else :
4298
+ # Subscripting a regular Generic subclass.
4299
+ for param in cls .__parameters__ :
4300
+ prepare = getattr (param , '__typing_prepare_subst__' , None )
4301
+ if prepare is not None :
4302
+ params = prepare (cls , params )
4303
+ _check_generic (cls , params , len (cls .__parameters__ ))
4304
+
4305
+ new_args = []
4306
+ for param , new_arg in zip (cls .__parameters__ , params ):
4307
+ if isinstance (param , TypeVarTuple ):
4308
+ new_args .extend (new_arg )
4309
+ else :
4310
+ new_args .append (new_arg )
4311
+ params = tuple (new_args )
4312
+
4313
+ return typing ._GenericAlias (
4314
+ cls , params ,
4315
+ _paramspec_tvars = True
4316
+ )
4317
+
4318
+ typing .Generic .__class_getitem__ = classmethod (_generic_class_getitem )
4319
+
4320
+
4260
4321
# Aliases for items that are in typing in all supported versions.
4261
4322
# We use hasattr() checks so this library will continue to import on
4262
4323
# future versions of Python that may remove these names.
0 commit comments