diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 7ddc84ac5e4..c7c5536a64f 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -78,6 +78,8 @@ annotations. These include: *Introducing* :data:`TypeVarTuple` * :pep:`647`: User-Defined Type Guards *Introducing* :data:`TypeGuard` +* :pep:`655`: Marking individual TypedDict items as required or potentially-missing + *Introducing* :data:`Required` and :data:`NotRequired` * :pep:`673`: Self type *Introducing* :data:`Self` * :pep:`675`: Arbitrary Literal String Type @@ -1022,6 +1024,18 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. versionadded:: 3.8 +.. data:: Required + +.. data:: NotRequired + + Special typing constructs that mark individual keys of a :class:`TypedDict` + as either required or non-required respectively. + + For more information, see :class:`TypedDict` and + :pep:`655` ("Marking individual TypedDict items as required or potentially-missing"). + + .. versionadded:: 3.11 + .. data:: Annotated A type, introduced in :pep:`593` (``Flexible function and variable @@ -1706,8 +1720,21 @@ These are not used in annotations. They are building blocks for declaring types. Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) By default, all keys must be present in a ``TypedDict``. It is possible to - override this by specifying totality. - Usage:: + mark individual keys as non-required using :data:`NotRequired`:: + + class Point2D(TypedDict): + x: int + y: int + label: NotRequired[str] + + # Alternative syntax + Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]}) + + This means that a ``Point2D`` ``TypedDict`` can have the ``label`` + key omitted. + + It is also possible to mark all keys as non-required by default + by specifying a totality of ``False``:: class Point2D(TypedDict, total=False): x: int @@ -1721,6 +1748,21 @@ These are not used in annotations. They are building blocks for declaring types. ``True`` as the value of the ``total`` argument. ``True`` is the default, and makes all items defined in the class body required. + Individual keys of a ``total=False`` ``TypedDict`` can be marked as + required using :data:`Required`:: + + class Point2D(TypedDict, total=False): + x: Required[int] + y: Required[int] + label: str + + # Alternative syntax + Point2D = TypedDict('Point2D', { + 'x': Required[int], + 'y': Required[int], + 'label': str + }, total=False) + It is possible for a ``TypedDict`` type to inherit from one or more other ``TypedDict`` types using the class-based syntax. Usage:: @@ -1785,11 +1827,16 @@ These are not used in annotations. They are building blocks for declaring types. ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return :class:`frozenset` objects containing required and non-required keys, respectively. - Currently the only way to declare both required and non-required keys in the - same ``TypedDict`` is mixed inheritance, declaring a ``TypedDict`` with one value - for the ``total`` argument and then inheriting it from another ``TypedDict`` with - a different value for ``total``. - Usage:: + + Keys marked with :data:`Required` will always appear in ``__required_keys__`` + and keys marked with :data:`NotRequired` will always appear in ``__optional_keys__``. + + For backwards compatibility with Python 3.10 and below, + it is also possible to use inheritance to declare both required and + non-required keys in the same ``TypedDict`` . This is done by declaring a + ``TypedDict`` with one value for the ``total`` argument and then + inheriting from it in another ``TypedDict`` with a different value for + ``total``:: >>> class Point2D(TypedDict, total=False): ... x: int @@ -1807,6 +1854,10 @@ These are not used in annotations. They are building blocks for declaring types. .. versionadded:: 3.8 + .. versionchanged:: 3.11 + Added support for marking individual keys as :data:`Required` or :data:`NotRequired`. + See :pep:`655`. + .. versionchanged:: 3.11 Added support for generic ``TypedDict``\ s.