Skip to content

gh-91243: Document Required and NotRequired #93173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
May 27, 2022
65 changes: 58 additions & 7 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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::
Expand Down Expand Up @@ -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
Expand All @@ -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.

Expand Down