@@ -195,15 +195,17 @@ def _type_repr(obj):
195
195
return repr (obj )
196
196
197
197
198
- def _collect_type_vars (types ):
199
- """Collect all type variable-like variables contained
198
+ def _collect_type_vars (types , typevar_types = None ):
199
+ """Collect all type variable contained
200
200
in types in order of first appearance (lexicographic order). For example::
201
201
202
202
_collect_type_vars((T, List[S, T])) == (T, S)
203
203
"""
204
+ if typevar_types is None :
205
+ typevar_types = TypeVar
204
206
tvars = []
205
207
for t in types :
206
- if isinstance (t , _TypeVarLike ) and t not in tvars :
208
+ if isinstance (t , typevar_types ) and t not in tvars :
207
209
tvars .append (t )
208
210
if isinstance (t , (_GenericAlias , GenericAlias )):
209
211
tvars .extend ([t for t in t .__parameters__ if t not in tvars ])
@@ -932,7 +934,8 @@ def __getattr__(self, attr):
932
934
raise AttributeError (attr )
933
935
934
936
def __setattr__ (self , attr , val ):
935
- if _is_dunder (attr ) or attr in ('_name' , '_inst' , '_nparams' ):
937
+ if _is_dunder (attr ) or attr in {'_name' , '_inst' , '_nparams' ,
938
+ '_typevar_types' , '_paramspec_tvars' }:
936
939
super ().__setattr__ (attr , val )
937
940
else :
938
941
setattr (self .__origin__ , attr , val )
@@ -957,14 +960,18 @@ def __subclasscheck__(self, cls):
957
960
958
961
959
962
class _GenericAlias (_BaseGenericAlias , _root = True ):
960
- def __init__ (self , origin , params , * , inst = True , name = None ):
963
+ def __init__ (self , origin , params , * , inst = True , name = None ,
964
+ _typevar_types = TypeVar ,
965
+ _paramspec_tvars = False ):
961
966
super ().__init__ (origin , inst = inst , name = name )
962
967
if not isinstance (params , tuple ):
963
968
params = (params ,)
964
969
self .__args__ = tuple (... if a is _TypingEllipsis else
965
970
() if a is _TypingEmpty else
966
971
a for a in params )
967
- self .__parameters__ = _collect_type_vars (params )
972
+ self .__parameters__ = _collect_type_vars (params , typevar_types = _typevar_types )
973
+ self ._typevar_types = _typevar_types
974
+ self ._paramspec_tvars = _paramspec_tvars
968
975
if not name :
969
976
self .__module__ = origin .__module__
970
977
@@ -991,14 +998,15 @@ def __getitem__(self, params):
991
998
if not isinstance (params , tuple ):
992
999
params = (params ,)
993
1000
params = tuple (_type_convert (p ) for p in params )
994
- if any (isinstance (t , ParamSpec ) for t in self .__parameters__ ):
995
- params = _prepare_paramspec_params (self , params )
1001
+ if self ._paramspec_tvars :
1002
+ if any (isinstance (t , ParamSpec ) for t in self .__parameters__ ):
1003
+ params = _prepare_paramspec_params (self , params )
996
1004
_check_generic (self , params , len (self .__parameters__ ))
997
1005
998
1006
subst = dict (zip (self .__parameters__ , params ))
999
1007
new_args = []
1000
1008
for arg in self .__args__ :
1001
- if isinstance (arg , _TypeVarLike ):
1009
+ if isinstance (arg , self . _typevar_types ):
1002
1010
arg = subst [arg ]
1003
1011
elif isinstance (arg , (_GenericAlias , GenericAlias )):
1004
1012
subparams = arg .__parameters__
@@ -1115,7 +1123,9 @@ def __reduce__(self):
1115
1123
class _CallableType (_SpecialGenericAlias , _root = True ):
1116
1124
def copy_with (self , params ):
1117
1125
return _CallableGenericAlias (self .__origin__ , params ,
1118
- name = self ._name , inst = self ._inst )
1126
+ name = self ._name , inst = self ._inst ,
1127
+ _typevar_types = (TypeVar , ParamSpec ),
1128
+ _paramspec_tvars = True )
1119
1129
1120
1130
def __getitem__ (self , params ):
1121
1131
if not isinstance (params , tuple ) or len (params ) != 2 :
@@ -1208,7 +1218,10 @@ def __hash__(self):
1208
1218
1209
1219
1210
1220
class _ConcatenateGenericAlias (_GenericAlias , _root = True ):
1211
- pass
1221
+ def __init__ (self , * args , ** kwargs ):
1222
+ super ().__init__ (* args , ** kwargs ,
1223
+ _typevar_types = (TypeVar , ParamSpec ),
1224
+ _paramspec_tvars = True )
1212
1225
1213
1226
1214
1227
class Generic :
@@ -1244,7 +1257,7 @@ def __class_getitem__(cls, params):
1244
1257
params = tuple (_type_convert (p ) for p in params )
1245
1258
if cls in (Generic , Protocol ):
1246
1259
# Generic and Protocol can only be subscripted with unique type variables.
1247
- if not all (isinstance (p , _TypeVarLike ) for p in params ):
1260
+ if not all (isinstance (p , ( TypeVar , ParamSpec ) ) for p in params ):
1248
1261
raise TypeError (
1249
1262
f"Parameters to { cls .__name__ } [...] must all be type variables "
1250
1263
f"or parameter specification variables." )
@@ -1256,7 +1269,9 @@ def __class_getitem__(cls, params):
1256
1269
if any (isinstance (t , ParamSpec ) for t in cls .__parameters__ ):
1257
1270
params = _prepare_paramspec_params (cls , params )
1258
1271
_check_generic (cls , params , len (cls .__parameters__ ))
1259
- return _GenericAlias (cls , params )
1272
+ return _GenericAlias (cls , params ,
1273
+ _typevar_types = (TypeVar , ParamSpec ),
1274
+ _paramspec_tvars = True )
1260
1275
1261
1276
def __init_subclass__ (cls , * args , ** kwargs ):
1262
1277
super ().__init_subclass__ (* args , ** kwargs )
@@ -1268,7 +1283,7 @@ def __init_subclass__(cls, *args, **kwargs):
1268
1283
if error :
1269
1284
raise TypeError ("Cannot inherit from plain Generic" )
1270
1285
if '__orig_bases__' in cls .__dict__ :
1271
- tvars = _collect_type_vars (cls .__orig_bases__ )
1286
+ tvars = _collect_type_vars (cls .__orig_bases__ , ( TypeVar , ParamSpec ) )
1272
1287
# Look for Generic[T1, ..., Tn].
1273
1288
# If found, tvars must be a subset of it.
1274
1289
# If not found, tvars is it.
0 commit comments