5
5
.. testsetup :: *
6
6
7
7
import typing
8
+ from dataclasses import dataclass
8
9
from typing import *
9
10
10
11
.. module :: typing
@@ -1184,7 +1185,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1184
1185
(possibly multiple pieces of it, as ``Annotated `` is variadic).
1185
1186
Specifically, a type ``T `` can be annotated with metadata ``x `` via the
1186
1187
typehint ``Annotated[T, x] ``. This metadata can be used for either static
1187
- analysis or at runtime. If a library (or tool) encounters a typehint
1188
+ analysis or at runtime: at runtime, it is stored in a :attr: `__metadata__ `
1189
+ attribute. If a library (or tool) encounters a typehint
1188
1190
``Annotated[T, x] `` and has no special logic for metadata ``x ``, it
1189
1191
should ignore it and simply treat the type as ``T ``. Unlike the
1190
1192
``no_type_check `` functionality that currently exists in the ``typing ``
@@ -1211,10 +1213,17 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1211
1213
the same (or different) type(s) on any node, the tools or libraries
1212
1214
consuming those annotations are in charge of dealing with potential
1213
1215
duplicates. For example, if you are doing value range analysis you might
1214
- allow this::
1216
+ allow this:
1215
1217
1216
- T1 = Annotated[int, ValueRange(-10, 5)]
1217
- T2 = Annotated[T1, ValueRange(-20, 3)]
1218
+ .. testcode ::
1219
+
1220
+ @dataclass
1221
+ class ValueRange:
1222
+ lo: int
1223
+ hi: int
1224
+
1225
+ T1 = Annotated[int, ValueRange(-10, 5)]
1226
+ T2 = Annotated[T1, ValueRange(-20, 3)]
1218
1227
1219
1228
Passing ``include_extras=True `` to :func: `get_type_hints ` lets one
1220
1229
access the extra annotations at runtime.
@@ -1226,38 +1235,64 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1226
1235
* Multiple type annotations are supported (``Annotated `` supports variadic
1227
1236
arguments)::
1228
1237
1229
- Annotated[int, ValueRange(3, 10), ctype("char")]
1238
+ @dataclass
1239
+ class ctype:
1240
+ kind: str
1241
+
1242
+ Annotated[int, ValueRange(3, 10), ctype("char")]
1230
1243
1231
1244
* ``Annotated `` must be called with at least two arguments (
1232
1245
``Annotated[int] `` is not valid)
1233
1246
1234
1247
* The order of the annotations is preserved and matters for equality
1235
1248
checks::
1236
1249
1237
- Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
1238
- int, ctype("char"), ValueRange(3, 10)
1239
- ]
1250
+ assert Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
1251
+ int, ctype("char"), ValueRange(3, 10)
1252
+ ]
1240
1253
1241
1254
* Nested ``Annotated `` types are flattened, with metadata ordered
1242
1255
starting with the innermost annotation::
1243
1256
1244
- Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
1245
- int, ValueRange(3, 10), ctype("char")
1246
- ]
1257
+ assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
1258
+ int, ValueRange(3, 10), ctype("char")
1259
+ ]
1247
1260
1248
1261
* Duplicated annotations are not removed::
1249
1262
1250
- Annotated[int, ValueRange(3, 10)] != Annotated[
1251
- int, ValueRange(3, 10), ValueRange(3, 10)
1252
- ]
1263
+ assert Annotated[int, ValueRange(3, 10)] != Annotated[
1264
+ int, ValueRange(3, 10), ValueRange(3, 10)
1265
+ ]
1266
+
1267
+ * ``Annotated `` can be used with nested and generic aliases:
1268
+
1269
+ .. testcode ::
1253
1270
1254
- * ``Annotated `` can be used with nested and generic aliases::
1271
+ @dataclass
1272
+ class MaxLen:
1273
+ value: int
1255
1274
1256
- T = TypeVar('T')
1257
- Vec = Annotated[list[tuple[T, T]], MaxLen(10)]
1258
- V = Vec[int]
1275
+ type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)]
1276
+
1277
+ # When used in a type annotation, a type checker will treat "V" the same as
1278
+ # ``Annotated[list[tuple[int, int]], MaxLen(10)] ``:
1279
+ type V = Vec[int]
1280
+
1281
+ .. attribute :: __metadata__
1282
+
1283
+ At runtime, the metadata associated with an ``Annotated `` type can be
1284
+ retrieved via the ``__metadata__ `` attribute.
1285
+
1286
+ For example:
1287
+
1288
+ .. doctest ::
1259
1289
1260
- V == Annotated[list[tuple[int, int]], MaxLen(10)]
1290
+ >>> from typing import Annotated
1291
+ >>> X = Annotated[int , " very" , " important" , " metadata" ]
1292
+ >>> X
1293
+ typing.Annotated[int, 'very', 'important', 'metadata']
1294
+ >>> X.__metadata__
1295
+ ('very', 'important', 'metadata')
1261
1296
1262
1297
.. versionadded :: 3.9
1263
1298
0 commit comments