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
@@ -1106,7 +1107,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1106
1107
(possibly multiple pieces of it, as ``Annotated `` is variadic).
1107
1108
Specifically, a type ``T `` can be annotated with metadata ``x `` via the
1108
1109
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
1110
1112
``Annotated[T, x] `` and has no special logic for metadata ``x ``, it
1111
1113
should ignore it and simply treat the type as ``T ``. Unlike the
1112
1114
``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
1133
1135
the same (or different) type(s) on any node, the tools or libraries
1134
1136
consuming those annotations are in charge of dealing with potential
1135
1137
duplicates. For example, if you are doing value range analysis you might
1136
- allow this::
1138
+ allow this:
1137
1139
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)]
1140
1149
1141
1150
Passing ``include_extras=True `` to :func: `get_type_hints ` lets one
1142
1151
access the extra annotations at runtime.
@@ -1148,38 +1157,63 @@ These can be used as types in annotations using ``[]``, each having a unique syn
1148
1157
* Multiple type annotations are supported (``Annotated `` supports variadic
1149
1158
arguments)::
1150
1159
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")]
1152
1165
1153
1166
* ``Annotated `` must be called with at least two arguments (
1154
1167
``Annotated[int] `` is not valid)
1155
1168
1156
1169
* The order of the annotations is preserved and matters for equality
1157
1170
checks::
1158
1171
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
+ ]
1162
1175
1163
1176
* Nested ``Annotated `` types are flattened, with metadata ordered
1164
1177
starting with the innermost annotation::
1165
1178
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
+ ]
1169
1182
1170
1183
* Duplicated annotations are not removed::
1171
1184
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 ::
1175
1192
1176
- * ``Annotated `` can be used with nested and generic aliases::
1193
+ @dataclass
1194
+ class MaxLen:
1195
+ value: int
1177
1196
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 ::
1181
1210
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')
1183
1217
1184
1218
.. versionadded :: 3.9
1185
1219
0 commit comments