@@ -70,6 +70,8 @@ annotations. These include:
70
70
*Introducing * :class: `ParamSpec ` and :data: `Concatenate `
71
71
* :pep: `613 `: Explicit Type Aliases
72
72
*Introducing * :data: `TypeAlias `
73
+ * :pep: `646 `: Variadic Generics
74
+ *Introducing * :data: `TypeVarTuple `
73
75
* :pep: `647 `: User-Defined Type Guards
74
76
*Introducing * :data: `TypeGuard `
75
77
* :pep: `673 `: Self type
@@ -1230,6 +1232,123 @@ These are not used in annotations. They are building blocks for creating generic
1230
1232
``covariant=True `` or ``contravariant=True ``. See :pep: `484 ` for more
1231
1233
details. By default, type variables are invariant.
1232
1234
1235
+ .. class :: TypeVarTuple
1236
+
1237
+ Type variable tuple. A specialized form of :class: `Type variable <TypeVar> `
1238
+ that enables *variadic * generics.
1239
+
1240
+ A normal type variable enables parameterization with a single type. A type
1241
+ variable tuple, in contrast, allows parameterization with an
1242
+ *arbitrary * number of types by acting like an *arbitrary * number of type
1243
+ variables wrapped in a tuple. For example::
1244
+
1245
+ T = TypeVar('T')
1246
+ Ts = TypeVarTuple('Ts')
1247
+
1248
+ def remove_first_element(tup: tuple[T, *Ts]) -> tuple[*Ts]:
1249
+ return tup[1:]
1250
+
1251
+ # T is bound to int, Ts is bound to ()
1252
+ # Return value is (), which has type tuple[()]
1253
+ remove_first_element(tup=(1,))
1254
+
1255
+ # T is bound to int, Ts is bound to (str,)
1256
+ # Return value is ('spam',), which has type tuple[str]
1257
+ remove_first_element(tup=(1, 'spam'))
1258
+
1259
+ # T is bound to int, Ts is bound to (str, float)
1260
+ # Return value is ('spam', 3.0), which has type tuple[str, float]
1261
+ remove_first_element(tup=(1, 'spam', 3.0))
1262
+
1263
+ Note the use of the unpacking operator ``* `` in ``tuple[T, *Ts] ``.
1264
+ Conceptually, you can think of ``Ts `` as a tuple of type variables
1265
+ ``(T1, T2, ...) ``. ``tuple[T, *Ts] `` would then become
1266
+ ``tuple[T, *(T1, T2, ...)] ``, which is equivalent to
1267
+ ``tuple[T, T1, T2, ...] ``. (Note that in older versions of Python, you might
1268
+ see this written using :data: `Unpack <Unpack> ` instead, as
1269
+ ``Unpack[Ts] ``.)
1270
+
1271
+ Type variable tuples must *always * be unpacked. This helps distinguish type
1272
+ variable types from normal type variables::
1273
+
1274
+ x: Ts # Not valid
1275
+ x: tuple[Ts] # Not valid
1276
+ x: tuple[*Ts] # The correct way to to do it
1277
+
1278
+ Type variable tuples can be used in the same contexts as normal type
1279
+ variables. For example, in class definitions, arguments, and return types::
1280
+
1281
+ Shape = TypeVarTuple('Shape')
1282
+ class Array(Generic[*Shape]):
1283
+ def __getitem__(self, key: tuple[*Shape]) -> float: ...
1284
+ def __abs__(self) -> Array[*Shape]: ...
1285
+ def get_shape(self) -> tuple[*Shape]: ...
1286
+
1287
+ Type variable tuples can be happily combined with normal type variables::
1288
+
1289
+ DType = TypeVar('DType')
1290
+
1291
+ class Array(Generic[DType, *Shape]): # This is fine
1292
+ pass
1293
+
1294
+ class Array2(Generic[*Shape, DType]): # This would also be fine
1295
+ pass
1296
+
1297
+ float_array_1d: Array[float, Height] = Array() # Totally fine
1298
+ int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too
1299
+
1300
+ However, note that at most one type variable tuple may appear in a single
1301
+ list of type arguments or type parameters::
1302
+
1303
+ x: tuple[*Ts, *Ts] # Not valid
1304
+ class Array(Generic[*Shape, *Shape]): # Not valid
1305
+ pass
1306
+
1307
+ Finally, an unpacked type variable tuple can be used as the type annotation
1308
+ of ``*args ``::
1309
+
1310
+ def call_soon(
1311
+ callback: Callable[[*Ts], None],
1312
+ *args: *Ts
1313
+ ) -> None:
1314
+ ...
1315
+ callback(*args)
1316
+
1317
+ In contrast to non-unpacked annotations of ``*args `` - e.g. ``*args: int ``,
1318
+ which would specify that *all * arguments are ``int `` - ``*args: *Ts ``
1319
+ enables reference to the types of the *individual * arguments in ``*args ``.
1320
+ Here, this allows us to ensure the types of the ``*args `` passed
1321
+ to ``call_soon `` match the types of the (positional) arguments of
1322
+ ``callback ``.
1323
+
1324
+ For more details on type variable tuples, see :pep: `646 `.
1325
+
1326
+ .. versionadded :: 3.11
1327
+
1328
+ .. data :: Unpack
1329
+
1330
+ A typing operator that conceptually marks an object as having been
1331
+ unpacked. For example, using the unpack operator ``* `` on a
1332
+ :class: `type variable tuple <TypeVarTuple> ` is equivalent to using ``Unpack ``
1333
+ to mark the type variable tuple as having been unpacked::
1334
+
1335
+ Ts = TypeVarTuple('Ts')
1336
+ tup: tuple[*Ts]
1337
+ # Effectively does:
1338
+ tup: tuple[Unpack[Ts]]
1339
+
1340
+ In fact, ``Unpack `` can be used interchangeably with ``* `` in the context
1341
+ of types. You might see ``Unpack `` being used explicitly in older versions
1342
+ of Python, where ``* `` couldn't be used in certain places::
1343
+
1344
+ # In older versions of Python, TypeVarTuple and Unpack
1345
+ # are located in the `typing_extensions` backports package.
1346
+ from typing_extensions import TypeVarTuple, Unpack
1347
+
1348
+ Ts = TypeVarTuple('Ts')
1349
+ tup: tuple[*Ts] # Syntax error on Python <= 3.10!
1350
+ tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible
1351
+
1233
1352
.. class :: ParamSpec(name, *, bound=None, covariant=False, contravariant=False)
1234
1353
1235
1354
Parameter specification variable. A specialized version of
0 commit comments