55.. testsetup :: *
66
77 import typing
8+ from dataclasses import dataclass
89 from typing import *
910
1011.. module :: typing
@@ -1106,7 +1107,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn
11061107 (possibly multiple pieces of it, as ``Annotated `` is variadic).
11071108 Specifically, a type ``T `` can be annotated with metadata ``x `` via the
11081109 typehint ``Annotated[T, x] ``. This metadata can be used for either static
1109- analysis or at runtime. If a library (or tool) encounters a typehint
1110+ analysis or at runtime: at runtime, it is stored in a :attr: `__metadata__ `
1111+ attribute. If a library (or tool) encounters a typehint
11101112 ``Annotated[T, x] `` and has no special logic for metadata ``x ``, it
11111113 should ignore it and simply treat the type as ``T ``. Unlike the
11121114 ``no_type_check `` functionality that currently exists in the ``typing ``
@@ -1133,10 +1135,17 @@ These can be used as types in annotations using ``[]``, each having a unique syn
11331135 the same (or different) type(s) on any node, the tools or libraries
11341136 consuming those annotations are in charge of dealing with potential
11351137 duplicates. For example, if you are doing value range analysis you might
1136- allow this::
1138+ allow this:
11371139
1138- T1 = Annotated[int, ValueRange(-10, 5)]
1139- T2 = Annotated[T1, ValueRange(-20, 3)]
1140+ .. testcode ::
1141+
1142+ @dataclass
1143+ class ValueRange:
1144+ lo: int
1145+ hi: int
1146+
1147+ T1 = Annotated[int, ValueRange(-10, 5)]
1148+ T2 = Annotated[T1, ValueRange(-20, 3)]
11401149
11411150 Passing ``include_extras=True `` to :func: `get_type_hints ` lets one
11421151 access the extra annotations at runtime.
@@ -1148,38 +1157,63 @@ These can be used as types in annotations using ``[]``, each having a unique syn
11481157 * Multiple type annotations are supported (``Annotated `` supports variadic
11491158 arguments)::
11501159
1151- Annotated[int, ValueRange(3, 10), ctype("char")]
1160+ @dataclass
1161+ class ctype:
1162+ kind: str
1163+
1164+ Annotated[int, ValueRange(3, 10), ctype("char")]
11521165
11531166 * ``Annotated `` must be called with at least two arguments (
11541167 ``Annotated[int] `` is not valid)
11551168
11561169 * The order of the annotations is preserved and matters for equality
11571170 checks::
11581171
1159- Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
1160- int, ctype("char"), ValueRange(3, 10)
1161- ]
1172+ assert Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
1173+ int, ctype("char"), ValueRange(3, 10)
1174+ ]
11621175
11631176 * Nested ``Annotated `` types are flattened, with metadata ordered
11641177 starting with the innermost annotation::
11651178
1166- Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
1167- int, ValueRange(3, 10), ctype("char")
1168- ]
1179+ assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
1180+ int, ValueRange(3, 10), ctype("char")
1181+ ]
11691182
11701183 * Duplicated annotations are not removed::
11711184
1172- Annotated[int, ValueRange(3, 10)] != Annotated[
1173- int, ValueRange(3, 10), ValueRange(3, 10)
1174- ]
1185+ assert Annotated[int, ValueRange(3, 10)] != Annotated[
1186+ int, ValueRange(3, 10), ValueRange(3, 10)
1187+ ]
1188+
1189+ * ``Annotated `` can be used with nested and generic aliases:
1190+
1191+ .. testcode ::
11751192
1176- * ``Annotated `` can be used with nested and generic aliases::
1193+ @dataclass
1194+ class MaxLen:
1195+ value: int
11771196
1178- T = TypeVar('T')
1179- Vec = Annotated[list[tuple[T, T]], MaxLen(10)]
1180- V = Vec[int]
1197+ T = TypeVar("T")
1198+ Vec: TypeAlias = Annotated[list[tuple[T, T]], MaxLen(10)]
1199+
1200+ assert Vec[int] == Annotated[list[tuple[int, int]], MaxLen(10)]
1201+
1202+ .. attribute :: __metadata__
1203+
1204+ At runtime, the metadata associated with an ``Annotated `` type can be
1205+ retrieved via the ``__metadata__ `` attribute.
1206+
1207+ For example:
1208+
1209+ .. doctest ::
11811210
1182- V == Annotated[list[tuple[int, int]], MaxLen(10)]
1211+ >>> from typing import Annotated
1212+ >>> X = Annotated[int , " very" , " important" , " metadata" ]
1213+ >>> X
1214+ typing.Annotated[int, 'very', 'important', 'metadata']
1215+ >>> X.__metadata__
1216+ ('very', 'important', 'metadata')
11831217
11841218 .. versionadded :: 3.9
11851219
0 commit comments