Skip to content

Commit d0af527

Browse files
[3.11] gh-97797: Improve documentation for typing.Annotated (GH-105365). (#105449)
(cherry picked from commit e26d296) Co-authored-by: Alex Waygood <[email protected]>
1 parent 0d2ed56 commit d0af527

File tree

1 file changed

+53
-19
lines changed

1 file changed

+53
-19
lines changed

Doc/library/typing.rst

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
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

Comments
 (0)