@@ -1469,9 +1469,6 @@ These are not used in annotations. They are building blocks for declaring types.
14691469
14701470 assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
14711471
1472- The type info for introspection can be accessed via ``Point2D.__annotations__ ``,
1473- ``Point2D.__total__ ``, ``Point2D.__required_keys__ ``, and
1474- ``Point2D.__optional_keys__ ``.
14751472 To allow using this feature with older versions of Python that do not
14761473 support :pep: `526 `, ``TypedDict `` supports two additional equivalent
14771474 syntactic forms:
@@ -1488,6 +1485,18 @@ These are not used in annotations. They are building blocks for declaring types.
14881485 The keyword-argument syntax is deprecated in 3.11 and will be removed
14891486 in 3.13. It may also be unsupported by static type checkers.
14901487
1488+ The functional syntax should also be used when any of the keys are not valid
1489+ :ref: `identifiers `, for example because they are keywords or contain hyphens.
1490+ Example::
1491+
1492+ # raises SyntaxError
1493+ class Point2D(TypedDict):
1494+ in: int # 'in' is a keyword
1495+ x-y: int # name with hyphens
1496+
1497+ # OK, functional syntax
1498+ Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
1499+
14911500 By default, all keys must be present in a ``TypedDict ``. It is possible to
14921501 override this by specifying totality.
14931502 Usage::
@@ -1504,6 +1513,82 @@ These are not used in annotations. They are building blocks for declaring types.
15041513 ``True `` as the value of the ``total `` argument. ``True `` is the default,
15051514 and makes all items defined in the class body required.
15061515
1516+ It is possible for a ``TypedDict `` type to inherit from one or more other ``TypedDict `` types
1517+ using the class-based syntax.
1518+ Usage::
1519+
1520+ class Point3D(Point2D):
1521+ z: int
1522+
1523+ ``Point3D `` has three items: ``x ``, ``y `` and ``z ``. It is equivalent to this
1524+ definition::
1525+
1526+ class Point3D(TypedDict):
1527+ x: int
1528+ y: int
1529+ z: int
1530+
1531+ A ``TypedDict `` cannot inherit from a non-TypedDict class,
1532+ notably including :class: `Generic `. For example::
1533+
1534+ class X(TypedDict):
1535+ x: int
1536+
1537+ class Y(TypedDict):
1538+ y: int
1539+
1540+ class Z(object): pass # A non-TypedDict class
1541+
1542+ class XY(X, Y): pass # OK
1543+
1544+ class XZ(X, Z): pass # raises TypeError
1545+
1546+ T = TypeVar('T')
1547+ class XT(X, Generic[T]): pass # raises TypeError
1548+
1549+ A ``TypedDict `` can be introspected via annotations dicts
1550+ (see :ref: `annotations-howto ` for more information on annotations best practices),
1551+ :attr: `__total__ `, :attr: `__required_keys__ `, and :attr: `__optional_keys__ `.
1552+
1553+ .. attribute :: __total__
1554+
1555+ ``Point2D.__total__ `` gives the value of the ``total `` argument.
1556+ Example::
1557+
1558+ >>> from typing import TypedDict
1559+ >>> class Point2D(TypedDict): pass
1560+ >>> Point2D.__total__
1561+ True
1562+ >>> class Point2D(TypedDict, total=False): pass
1563+ >>> Point2D.__total__
1564+ False
1565+ >>> class Point3D(Point2D): pass
1566+ >>> Point3D.__total__
1567+ True
1568+
1569+ .. attribute :: __required_keys__
1570+ .. attribute :: __optional_keys__
1571+
1572+ ``Point2D.__required_keys__ `` and ``Point2D.__optional_keys__ `` return
1573+ :class: `frozenset ` objects containing required and non-required keys, respectively.
1574+ Currently the only way to declare both required and non-required keys in the
1575+ same ``TypedDict `` is mixed inheritance, declaring a ``TypedDict `` with one value
1576+ for the ``total `` argument and then inheriting it from another ``TypedDict `` with
1577+ a different value for ``total ``.
1578+ Usage::
1579+
1580+ >>> class Point2D(TypedDict, total=False):
1581+ ... x: int
1582+ ... y: int
1583+ ...
1584+ >>> class Point3D(Point2D):
1585+ ... z: int
1586+ ...
1587+ >>> Point3D.__required_keys__ == frozenset({'z'})
1588+ True
1589+ >>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
1590+ True
1591+
15071592 See :pep: `589 ` for more examples and detailed rules of using ``TypedDict ``.
15081593
15091594 .. versionadded :: 3.8
0 commit comments