Skip to content

Commit 241c36e

Browse files
[3.12] gh-97797: Improve documentation for typing.Annotated (GH-105365) (#105448)
gh-97797: Improve documentation for typing.Annotated (GH-105365) (cherry picked from commit e26d296) Co-authored-by: Alex Waygood <[email protected]>
1 parent 92ab560 commit 241c36e

File tree

1 file changed

+54
-19
lines changed

1 file changed

+54
-19
lines changed

Doc/library/typing.rst

+54-19
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
@@ -1184,7 +1185,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn
11841185
(possibly multiple pieces of it, as ``Annotated`` is variadic).
11851186
Specifically, a type ``T`` can be annotated with metadata ``x`` via the
11861187
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
11881190
``Annotated[T, x]`` and has no special logic for metadata ``x``, it
11891191
should ignore it and simply treat the type as ``T``. Unlike the
11901192
``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
12111213
the same (or different) type(s) on any node, the tools or libraries
12121214
consuming those annotations are in charge of dealing with potential
12131215
duplicates. For example, if you are doing value range analysis you might
1214-
allow this::
1216+
allow this:
12151217

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)]
12181227

12191228
Passing ``include_extras=True`` to :func:`get_type_hints` lets one
12201229
access the extra annotations at runtime.
@@ -1226,38 +1235,64 @@ These can be used as types in annotations using ``[]``, each having a unique syn
12261235
* Multiple type annotations are supported (``Annotated`` supports variadic
12271236
arguments)::
12281237

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")]
12301243

12311244
* ``Annotated`` must be called with at least two arguments (
12321245
``Annotated[int]`` is not valid)
12331246

12341247
* The order of the annotations is preserved and matters for equality
12351248
checks::
12361249

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+
]
12401253

12411254
* Nested ``Annotated`` types are flattened, with metadata ordered
12421255
starting with the innermost annotation::
12431256

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+
]
12471260

12481261
* Duplicated annotations are not removed::
12491262

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::
12531270

1254-
* ``Annotated`` can be used with nested and generic aliases::
1271+
@dataclass
1272+
class MaxLen:
1273+
value: int
12551274

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::
12591289

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')
12611296

12621297
.. versionadded:: 3.9
12631298

0 commit comments

Comments
 (0)