@@ -918,7 +918,8 @@ def _is_unpacked_typevartuple(x: Any) -> bool:
918
918
919
919
920
920
def _is_typevar_like (x : Any ) -> bool :
921
- return isinstance (x , (TypeVar , ParamSpec )) or _is_unpacked_typevartuple (x )
921
+ # TODO(PEP 695): remove TypeVarTuple here
922
+ return isinstance (x , (TypeVar , ParamSpec , TypeVarTuple )) or _is_unpacked_typevartuple (x )
922
923
923
924
924
925
class _PickleUsingNameMixin :
@@ -1301,29 +1302,93 @@ def __typing_prepare_subst__(self, alias, args):
1301
1302
1302
1303
1303
1304
import builtins
1304
- if hasattr (builtins , "TypeVar" ):
1305
- class _Dummy [T , * Ts , ** P ]:
1306
- type_params = (T , Ts , P )
1307
1305
1308
- TypeVar = type (_Dummy .type_params [0 ])
1309
- TypeVarTuple = type (_Dummy .type_params [1 ])
1310
- ParamSpec = type (_Dummy .type_params [2 ])
1311
- ParamSpecArgs = type (ParamSpec ("P" ).args )
1312
- ParamSpecKwargs = type (ParamSpec ("P" ).kwargs )
1313
1306
1314
- del _Dummy
1307
+ @_tp_cache
1308
+ def _generic_class_getitem (cls , params ):
1309
+ """Parameterizes a generic class.
1315
1310
1316
- import copyreg
1311
+ At least, parameterizing a generic class is the *main* thing this method
1312
+ does. For example, for some generic class `Foo`, this is called when we
1313
+ do `Foo[int]` - there, with `cls=Foo` and `params=int`.
1317
1314
1318
- def _pickle_psargs (psargs ):
1319
- return ParamSpecArgs , (psargs .__origin__ ,)
1315
+ However, note that this method is also called when defining generic
1316
+ classes in the first place with `class Foo(Generic[T]): ...`.
1317
+ """
1318
+ if not isinstance (params , tuple ):
1319
+ params = (params ,)
1320
1320
1321
- copyreg .pickle (ParamSpecArgs , _pickle_psargs )
1321
+ params = tuple (_type_convert (p ) for p in params )
1322
+ if cls in (builtins .Generic , Protocol ):
1323
+ # Generic and Protocol can only be subscripted with unique type variables.
1324
+ if not params :
1325
+ raise TypeError (
1326
+ f"Parameter list to { cls .__qualname__ } [...] cannot be empty"
1327
+ )
1328
+ if not all (_is_typevar_like (p ) for p in params ):
1329
+ raise TypeError (
1330
+ f"Parameters to { cls .__name__ } [...] must all be type variables "
1331
+ f"or parameter specification variables." )
1332
+ if len (set (params )) != len (params ):
1333
+ raise TypeError (
1334
+ f"Parameters to { cls .__name__ } [...] must all be unique" )
1335
+ else :
1336
+ # Subscripting a regular Generic subclass.
1337
+ for param in cls .__parameters__ :
1338
+ prepare = getattr (param , '__typing_prepare_subst__' , None )
1339
+ if prepare is not None :
1340
+ params = prepare (cls , params )
1341
+ _check_generic (cls , params , len (cls .__parameters__ ))
1322
1342
1323
- def _pickle_pskwargs (pskwargs ):
1324
- return ParamSpecKwargs , (pskwargs .__origin__ ,)
1343
+ new_args = []
1344
+ for param , new_arg in zip (cls .__parameters__ , params ):
1345
+ if isinstance (param , TypeVarTuple ):
1346
+ new_args .extend (new_arg )
1347
+ else :
1348
+ new_args .append (new_arg )
1349
+ params = tuple (new_args )
1350
+
1351
+ return _GenericAlias (cls , params ,
1352
+ _paramspec_tvars = True )
1353
+
1354
+
1355
+ def _generic_init_subclass (cls , * args , ** kwargs ):
1356
+ super (builtins .Generic , cls ).__init_subclass__ (* args , ** kwargs )
1357
+ tvars = []
1358
+ if '__orig_bases__' in cls .__dict__ :
1359
+ error = builtins .Generic in cls .__orig_bases__
1360
+ else :
1361
+ error = (builtins .Generic in cls .__bases__ and
1362
+ cls .__name__ != 'Protocol' and
1363
+ type (cls ) != _TypedDictMeta )
1364
+ if error :
1365
+ raise TypeError ("Cannot inherit from plain Generic" )
1366
+ if '__orig_bases__' in cls .__dict__ :
1367
+ tvars = _collect_parameters (cls .__orig_bases__ )
1368
+ # Look for Generic[T1, ..., Tn].
1369
+ # If found, tvars must be a subset of it.
1370
+ # If not found, tvars is it.
1371
+ # Also check for and reject plain Generic,
1372
+ # and reject multiple Generic[...].
1373
+ gvars = None
1374
+ for base in cls .__orig_bases__ :
1375
+ if (isinstance (base , _GenericAlias ) and
1376
+ base .__origin__ is builtins .Generic ):
1377
+ if gvars is not None :
1378
+ raise TypeError (
1379
+ "Cannot inherit from Generic[...] multiple types." )
1380
+ gvars = base .__parameters__
1381
+ if gvars is not None :
1382
+ tvarset = set (tvars )
1383
+ gvarset = set (gvars )
1384
+ if not tvarset <= gvarset :
1385
+ s_vars = ', ' .join (str (t ) for t in tvars if t not in gvarset )
1386
+ s_args = ', ' .join (str (g ) for g in gvars )
1387
+ raise TypeError (f"Some type variables ({ s_vars } ) are"
1388
+ f" not listed in Generic[{ s_args } ]" )
1389
+ tvars = gvars
1390
+ cls .__parameters__ = tuple (tvars )
1325
1391
1326
- copyreg .pickle (ParamSpecKwargs , _pickle_pskwargs )
1327
1392
1328
1393
def _is_dunder (attr ):
1329
1394
return attr .startswith ('__' ) and attr .endswith ('__' )
@@ -1969,92 +2034,6 @@ def __init_subclass__(cls, *args, **kwargs):
1969
2034
cls .__parameters__ = tuple (tvars )
1970
2035
1971
2036
1972
- @_tp_cache
1973
- def _generic_class_getitem (cls , params ):
1974
- """Parameterizes a generic class.
1975
-
1976
- At least, parameterizing a generic class is the *main* thing this method
1977
- does. For example, for some generic class `Foo`, this is called when we
1978
- do `Foo[int]` - there, with `cls=Foo` and `params=int`.
1979
-
1980
- However, note that this method is also called when defining generic
1981
- classes in the first place with `class Foo(Generic[T]): ...`.
1982
- """
1983
- if not isinstance (params , tuple ):
1984
- params = (params ,)
1985
-
1986
- params = tuple (_type_convert (p ) for p in params )
1987
- if cls in (builtins .Generic , Protocol ):
1988
- # Generic and Protocol can only be subscripted with unique type variables.
1989
- if not params :
1990
- raise TypeError (
1991
- f"Parameter list to { cls .__qualname__ } [...] cannot be empty"
1992
- )
1993
- if not all (_is_typevar_like (p ) for p in params ):
1994
- raise TypeError (
1995
- f"Parameters to { cls .__name__ } [...] must all be type variables "
1996
- f"or parameter specification variables." )
1997
- if len (set (params )) != len (params ):
1998
- raise TypeError (
1999
- f"Parameters to { cls .__name__ } [...] must all be unique" )
2000
- else :
2001
- # Subscripting a regular Generic subclass.
2002
- for param in cls .__parameters__ :
2003
- prepare = getattr (param , '__typing_prepare_subst__' , None )
2004
- if prepare is not None :
2005
- params = prepare (cls , params )
2006
- _check_generic (cls , params , len (cls .__parameters__ ))
2007
-
2008
- new_args = []
2009
- for param , new_arg in zip (cls .__parameters__ , params ):
2010
- if isinstance (param , TypeVarTuple ):
2011
- new_args .extend (new_arg )
2012
- else :
2013
- new_args .append (new_arg )
2014
- params = tuple (new_args )
2015
-
2016
- return _GenericAlias (cls , params ,
2017
- _paramspec_tvars = True )
2018
-
2019
- import builtins
2020
-
2021
- def _generic_init_subclass (cls , * args , ** kwargs ):
2022
- super (builtins .Generic , cls ).__init_subclass__ (* args , ** kwargs )
2023
- tvars = []
2024
- if '__orig_bases__' in cls .__dict__ :
2025
- error = builtins .Generic in cls .__orig_bases__
2026
- else :
2027
- error = (builtins .Generic in cls .__bases__ and
2028
- cls .__name__ != 'Protocol' and
2029
- type (cls ) != _TypedDictMeta )
2030
- if error :
2031
- raise TypeError ("Cannot inherit from plain Generic" )
2032
- if '__orig_bases__' in cls .__dict__ :
2033
- tvars = _collect_parameters (cls .__orig_bases__ )
2034
- # Look for Generic[T1, ..., Tn].
2035
- # If found, tvars must be a subset of it.
2036
- # If not found, tvars is it.
2037
- # Also check for and reject plain Generic,
2038
- # and reject multiple Generic[...].
2039
- gvars = None
2040
- for base in cls .__orig_bases__ :
2041
- if (isinstance (base , _GenericAlias ) and
2042
- base .__origin__ is builtins .Generic ):
2043
- if gvars is not None :
2044
- raise TypeError (
2045
- "Cannot inherit from Generic[...] multiple types." )
2046
- gvars = base .__parameters__
2047
- if gvars is not None :
2048
- tvarset = set (tvars )
2049
- gvarset = set (gvars )
2050
- if not tvarset <= gvarset :
2051
- s_vars = ', ' .join (str (t ) for t in tvars if t not in gvarset )
2052
- s_args = ', ' .join (str (g ) for g in gvars )
2053
- raise TypeError (f"Some type variables ({ s_vars } ) are"
2054
- f" not listed in Generic[{ s_args } ]" )
2055
- tvars = gvars
2056
- cls .__parameters__ = tuple (tvars )
2057
-
2058
2037
2059
2038
class _TypingEllipsis :
2060
2039
"""Internal placeholder for ... (ellipsis)."""
@@ -2303,6 +2282,30 @@ def _proto_hook(other):
2303
2282
if cls .__init__ is Protocol .__init__ :
2304
2283
cls .__init__ = _no_init_or_replace_init
2305
2284
2285
+ if hasattr (builtins , "TypeVar" ):
2286
+ def _dummy [T , * Ts , ** P ]():
2287
+ pass
2288
+
2289
+ TypeVar = type (_dummy .__type_variables__ [0 ])
2290
+ TypeVarTuple = type (_dummy .__type_variables__ [1 ])
2291
+ ParamSpec = type (_dummy .__type_variables__ [2 ])
2292
+ ParamSpecArgs = type (ParamSpec ("P" ).args )
2293
+ ParamSpecKwargs = type (ParamSpec ("P" ).kwargs )
2294
+
2295
+ del _dummy
2296
+
2297
+ import copyreg
2298
+
2299
+ def _pickle_psargs (psargs ):
2300
+ return ParamSpecArgs , (psargs .__origin__ ,)
2301
+
2302
+ copyreg .pickle (ParamSpecArgs , _pickle_psargs )
2303
+
2304
+ def _pickle_pskwargs (pskwargs ):
2305
+ return ParamSpecKwargs , (pskwargs .__origin__ ,)
2306
+
2307
+ copyreg .pickle (ParamSpecKwargs , _pickle_pskwargs )
2308
+
2306
2309
2307
2310
class _AnnotatedAlias (_NotIterable , _GenericAlias , _root = True ):
2308
2311
"""Runtime representation of an annotated type.
0 commit comments