Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 60 additions & 5 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2786,6 +2786,37 @@ types.
y: int
z: int

By default, a ``TypedDict`` is open, meaning that it may contain additional keys
at runtime beyond those defined in the class body. The *closed* class argument can
be used to control this; if ``closed=True``, the ``TypedDict`` cannot contain additional keys.

::

class ClosedPoint(TypedDict, closed=True):
x: int
y: int

class ClosedPoint3D(ClosedPoint): # type checker error: cannot add keys to a closed TypedDict
z: int

Setting ``closed=False`` explicitly requests the default open behavior. If the argument is not
passed, this state is inherited from the parent class.

In addition to being open or closed, a ``TypedDict`` can also be configured to have extra items.
If the *extra_items* class argument is set to a type, the ``TypedDict`` can contain arbitrary
additional keys, but the values of those keys must be of the specified type.

::

class ExtraItemsPoint(TypedDict, extra_items=int):
x: int
y: int

point: ExtraItemsPoint = {'x': 1, 'y': 2, 'anything': 3} # OK

The *extra_items* argument is also inherited through subclassing. It is unset
by default, and it may not be used together with the *closed* argument.

A ``TypedDict`` cannot inherit from a non-\ ``TypedDict`` class,
except for :class:`Generic`. For example::

Expand Down Expand Up @@ -2819,8 +2850,8 @@ types.
group: list[T]

A ``TypedDict`` can be introspected via annotations dicts
(see :ref:`annotations-howto` for more information on annotations best practices),
:attr:`__total__`, :attr:`__required_keys__`, and :attr:`__optional_keys__`.
(see :ref:`annotations-howto` for more information on annotations best practices)
and the following attributes:

.. attribute:: __total__

Expand Down Expand Up @@ -2890,8 +2921,6 @@ types.
``__required_keys__`` and ``__optional_keys__`` rely on may not work
properly, and the values of the attributes may be incorrect.

Support for :data:`ReadOnly` is reflected in the following attributes:

.. attribute:: __readonly_keys__

A :class:`frozenset` containing the names of all read-only keys. Keys
Expand All @@ -2906,6 +2935,14 @@ types.

.. versionadded:: 3.13

.. attribute:: __closed__

The value of the *closed* class argument. It can be ``True``, ``False``, or :data:`None`.

.. attribute:: __extra_items__

The value of the *extra_items* class argument. It can be a valid type or :data:`NoExtraItems`.

See the `TypedDict <https://typing.python.org/en/latest/spec/typeddict.html#typeddict>`_ section in the typing documentation for more examples and detailed rules.

.. versionadded:: 3.8
Expand All @@ -2925,7 +2962,10 @@ types.
Removed support for the keyword-argument method of creating ``TypedDict``\ s.

.. versionchanged:: 3.13
Support for the :data:`ReadOnly` qualifier was added.
Support for the :data:`ReadOnly` qualifier was added. See :pep:`705`.

.. versionchanged:: 3.15
Support for the *closed* and *extra_items* class arguments was added. See :pep:`728`.


Protocols
Expand Down Expand Up @@ -3673,6 +3713,21 @@ Introspection helpers

.. versionadded:: 3.13

.. data:: NoExtraItems

A :class:`sentinel` object used to indicate that a :class:`TypedDict`
does not have the *extra_items* class argument.

.. doctest::

>>> from typing import TypedDict, NoExtraItems
>>> class Point(TypedDict):
... x: int
... y: int
...
>>> Point.__extra_items__ is NoExtraItems
True

Constant
--------

Expand Down
11 changes: 10 additions & 1 deletion Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Summary -- Release highlights
<whatsnew315-unpacking-in-comprehensions>`
* :pep:`686`: :ref:`Python now uses UTF-8 as the default encoding
<whatsnew315-utf8-default>`
* :pep:`728`: ``TypedDict`` with typed extra items
* :pep:`728`: :ref:`TypedDict with typed extra items <whatsnew315-pep728>`
* :pep:`747`: :ref:`Annotating type forms with TypeForm
<whatsnew315-typeform>`
* :pep:`800`: Disjoint bases in the type system
Expand Down Expand Up @@ -1399,6 +1399,15 @@ typing

(Contributed by Jelle Zijlstra in :gh:`145033`.)

.. _whatsnew315-pep728:

* :pep:`728`: Add support in :class:`~typing.TypedDict` for the *closed*
and *extra_items* class arguments. A closed :class:`~typing.TypedDict`
does not allow extra keys beyond those specified in the class body, while
a :class:`~typing.TypedDict` with ``extra_items`` allows arbitrary extra
items where the values are of the specified type. (Contributed by Angela
Liss in :gh:`137840`.)

* Code like ``class ExtraTypeVars(P1[S], Protocol[T, T2]): ...`` now raises
a :exc:`TypeError`, because ``S`` is not listed in ``Protocol`` parameters.
(Contributed by Nikita Sobolev in :gh:`137191`.)
Expand Down
Loading