@@ -1194,40 +1194,36 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1194
1194
1195
1195
.. data :: Annotated
1196
1196
1197
- A type, introduced in :pep: `593 ` (``Flexible function and variable
1198
- annotations ``), to decorate existing types with context-specific metadata
1199
- (possibly multiple pieces of it, as ``Annotated `` is variadic).
1200
- Specifically, a type ``T `` can be annotated with metadata ``x `` via the
1201
- typehint ``Annotated[T, x] ``. This metadata can be used for either static
1202
- analysis or at runtime: at runtime, it is stored in a :attr: `__metadata__ `
1203
- attribute. If a library (or tool) encounters a typehint
1204
- ``Annotated[T, x] `` and has no special logic for metadata ``x ``, it
1205
- should ignore it and simply treat the type as ``T ``. Unlike the
1206
- ``no_type_check `` functionality that currently exists in the ``typing ``
1207
- module which completely disables typechecking annotations on a function
1208
- or a class, the ``Annotated `` type allows for both static typechecking
1209
- of ``T `` (which can safely ignore ``x ``)
1210
- together with runtime access to ``x `` within a specific application.
1211
-
1212
- Ultimately, the responsibility of how to interpret the annotations (if
1213
- at all) is the responsibility of the tool or library encountering the
1214
- ``Annotated `` type. A tool or library encountering an ``Annotated `` type
1215
- can scan through the annotations to determine if they are of interest
1216
- (e.g., using ``isinstance() ``).
1217
-
1218
- When a tool or a library does not support annotations or encounters an
1219
- unknown annotation it should just ignore it and treat annotated type as
1220
- the underlying type.
1221
-
1222
- It's up to the tool consuming the annotations to decide whether the
1223
- client is allowed to have several annotations on one type and how to
1224
- merge those annotations.
1225
-
1226
- Since the ``Annotated `` type allows you to put several annotations of
1227
- the same (or different) type(s) on any node, the tools or libraries
1228
- consuming those annotations are in charge of dealing with potential
1229
- duplicates. For example, if you are doing value range analysis you might
1230
- allow this:
1197
+ Special typing form to add context-specific metadata to an annotation.
1198
+
1199
+ Add metadata ``x `` to a given type ``T `` by using the annotation
1200
+ ``Annotated[T, x] ``. Metadata added using ``Annotated `` can be used by
1201
+ static analysis tools or at runtime. At runtime, the metadata is stored
1202
+ in a :attr: `!__metadata__ ` attribute.
1203
+
1204
+ If a library or tool encounters an annotation ``Annotated[T, x] `` and has
1205
+ no special logic for the metadata, it should ignore the metadata and simply
1206
+ treat the annotation as ``T ``. As such, ``Annotated `` can be useful for code
1207
+ that wants to use annotations for purposes outside Python's static typing
1208
+ system.
1209
+
1210
+ Using ``Annotated[T, x] `` as an annotation still allows for static
1211
+ typechecking of ``T ``, as type checkers will simply ignore the metadata ``x ``.
1212
+ In this way, ``Annotated `` differs from the
1213
+ :func: `@no_type_check <no_type_check> ` decorator, which can also be used for
1214
+ adding annotations outside the scope of the typing system, but
1215
+ completely disables typechecking for a function or class.
1216
+
1217
+ The responsibility of how to interpret the metadata
1218
+ lies with the the tool or library encountering an
1219
+ ``Annotated `` annotation. A tool or library encountering an ``Annotated `` type
1220
+ can scan through the metadata elements to determine if they are of interest
1221
+ (e.g., using :func: `isinstance `).
1222
+
1223
+ .. describe :: Annotated[<type>, <metadata>]
1224
+
1225
+ Here is an example of how you might use ``Annotated `` to add metadata to
1226
+ type annotations if you were doing range analysis:
1231
1227
1232
1228
.. testcode ::
1233
1229
@@ -1239,14 +1235,11 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1239
1235
T1 = Annotated[int, ValueRange(-10, 5)]
1240
1236
T2 = Annotated[T1, ValueRange(-20, 3)]
1241
1237
1242
- Passing ``include_extras=True `` to :func: `get_type_hints ` lets one
1243
- access the extra annotations at runtime.
1244
-
1245
- The details of the syntax:
1238
+ Details of the syntax:
1246
1239
1247
1240
* The first argument to ``Annotated `` must be a valid type
1248
1241
1249
- * Multiple type annotations are supported (``Annotated `` supports variadic
1242
+ * Multiple metadata elements can be supplied (``Annotated `` supports variadic
1250
1243
arguments)::
1251
1244
1252
1245
@dataclass
@@ -1255,24 +1248,28 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1255
1248
1256
1249
Annotated[int, ValueRange(3, 10), ctype("char")]
1257
1250
1258
- * ``Annotated `` must be called with at least two arguments (
1251
+ It is up to the tool consuming the annotations to decide whether the
1252
+ client is allowed to add multiple metadata elements to one annotation and how to
1253
+ merge those annotations.
1254
+
1255
+ * ``Annotated `` must be subscripted with at least two arguments (
1259
1256
``Annotated[int] `` is not valid)
1260
1257
1261
- * The order of the annotations is preserved and matters for equality
1258
+ * The order of the metadata elements is preserved and matters for equality
1262
1259
checks::
1263
1260
1264
1261
assert Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
1265
1262
int, ctype("char"), ValueRange(3, 10)
1266
1263
]
1267
1264
1268
- * Nested ``Annotated `` types are flattened, with metadata ordered
1269
- starting with the innermost annotation::
1265
+ * Nested ``Annotated `` types are flattened. The order of the metadata elements
1266
+ starts with the innermost annotation::
1270
1267
1271
1268
assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
1272
1269
int, ValueRange(3, 10), ctype("char")
1273
1270
]
1274
1271
1275
- * Duplicated annotations are not removed::
1272
+ * Duplicated metadata elements are not removed::
1276
1273
1277
1274
assert Annotated[int, ValueRange(3, 10)] != Annotated[
1278
1275
int, ValueRange(3, 10), ValueRange(3, 10)
@@ -1292,12 +1289,32 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1292
1289
# ``Annotated[list[tuple[int, int]], MaxLen(10)] ``:
1293
1290
type V = Vec[int]
1294
1291
1295
- .. attribute :: __metadata__
1292
+ * ``Annotated `` cannot be used with an unpacked :class: `TypeVarTuple `::
1293
+
1294
+ type Variadic[*Ts] = Annotated[*Ts, Ann1] # NOT valid
1295
+
1296
+ This would be equivalent to::
1296
1297
1297
- At runtime, the metadata associated with an ``Annotated `` type can be
1298
- retrieved via the ``__metadata__ `` attribute.
1298
+ Annotated[T1, T2, T3, ..., Ann1]
1299
1299
1300
- For example:
1300
+ where ``T1``, ``T2``, etc. are :class:`TypeVars <TypeVar>`. This would be
1301
+ invalid: only one type should be passed to Annotated.
1302
+
1303
+ * By default, :func: `get_type_hints ` strips the metadata from annotations.
1304
+ Pass ``include_extras=True `` to have the metadata preserved:
1305
+
1306
+ .. doctest ::
1307
+
1308
+ >>> from typing import Annotated, get_type_hints
1309
+ >>> def func (x : Annotated[int , " metadata" ]) -> None : pass
1310
+ ...
1311
+ >>> get_type_hints(func)
1312
+ {'x': <class 'int'>, 'return': <class 'NoneType'>}
1313
+ >>> get_type_hints(func, include_extras = True )
1314
+ {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>}
1315
+
1316
+ * At runtime, the metadata associated with an ``Annotated `` type can be
1317
+ retrieved via the :attr: `!__metadata__ ` attribute:
1301
1318
1302
1319
.. doctest ::
1303
1320
@@ -1308,6 +1325,11 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1308
1325
>>> X.__metadata__
1309
1326
('very', 'important', 'metadata')
1310
1327
1328
+ .. seealso ::
1329
+
1330
+ :pep: `593 ` - Flexible function and variable annotations
1331
+ The PEP introducing ``Annotated `` to the standard library.
1332
+
1311
1333
.. versionadded :: 3.9
1312
1334
1313
1335
0 commit comments