@@ -1388,16 +1388,25 @@ These are not used in annotations. They are building blocks for declaring types.
1388
1388
1389
1389
assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
1390
1390
1391
- The type info for introspection can be accessed via ``Point2D.__annotations__ ``,
1392
- ``Point2D.__total__ ``, ``Point2D.__required_keys__ ``, and
1393
- ``Point2D.__optional_keys__ ``.
1394
1391
To allow using this feature with older versions of Python that do not
1395
1392
support :pep: `526 `, ``TypedDict `` supports two additional equivalent
1396
1393
syntactic forms::
1397
1394
1398
1395
Point2D = TypedDict('Point2D', x=int, y=int, label=str)
1399
1396
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
1400
1397
1398
+ The functional syntax should also be used when any of the keys are not valid
1399
+ :ref: `identifiers `, for example because they are keywords or contain hyphens.
1400
+ Example::
1401
+
1402
+ # raises SyntaxError
1403
+ class Point2D(TypedDict):
1404
+ in: int # 'in' is a keyword
1405
+ x-y: int # name with hyphens
1406
+
1407
+ # OK, functional syntax
1408
+ Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
1409
+
1401
1410
By default, all keys must be present in a ``TypedDict ``. It is possible to
1402
1411
override this by specifying totality.
1403
1412
Usage::
@@ -1411,6 +1420,82 @@ These are not used in annotations. They are building blocks for declaring types.
1411
1420
``True `` as the value of the ``total `` argument. ``True `` is the default,
1412
1421
and makes all items defined in the class body required.
1413
1422
1423
+ It is possible for a ``TypedDict `` type to inherit from one or more other ``TypedDict `` types
1424
+ using the class-based syntax.
1425
+ Usage::
1426
+
1427
+ class Point3D(Point2D):
1428
+ z: int
1429
+
1430
+ ``Point3D `` has three items: ``x ``, ``y `` and ``z ``. It is equivalent to this
1431
+ definition::
1432
+
1433
+ class Point3D(TypedDict):
1434
+ x: int
1435
+ y: int
1436
+ z: int
1437
+
1438
+ A ``TypedDict `` cannot inherit from a non-TypedDict class,
1439
+ notably including :class: `Generic `. For example::
1440
+
1441
+ class X(TypedDict):
1442
+ x: int
1443
+
1444
+ class Y(TypedDict):
1445
+ y: int
1446
+
1447
+ class Z(object): pass # A non-TypedDict class
1448
+
1449
+ class XY(X, Y): pass # OK
1450
+
1451
+ class XZ(X, Z): pass # raises TypeError
1452
+
1453
+ T = TypeVar('T')
1454
+ class XT(X, Generic[T]): pass # raises TypeError
1455
+
1456
+ A ``TypedDict `` can be introspected via annotations dicts
1457
+ (see :ref: `annotations-howto ` for more information on annotations best practices),
1458
+ :attr: `__total__ `, :attr: `__required_keys__ `, and :attr: `__optional_keys__ `.
1459
+
1460
+ .. attribute :: __total__
1461
+
1462
+ ``Point2D.__total__ `` gives the value of the ``total `` argument.
1463
+ Example::
1464
+
1465
+ >>> from typing import TypedDict
1466
+ >>> class Point2D(TypedDict): pass
1467
+ >>> Point2D.__total__
1468
+ True
1469
+ >>> class Point2D(TypedDict, total=False): pass
1470
+ >>> Point2D.__total__
1471
+ False
1472
+ >>> class Point3D(Point2D): pass
1473
+ >>> Point3D.__total__
1474
+ True
1475
+
1476
+ .. attribute :: __required_keys__
1477
+ .. attribute :: __optional_keys__
1478
+
1479
+ ``Point2D.__required_keys__ `` and ``Point2D.__optional_keys__ `` return
1480
+ :class: `frozenset ` objects containing required and non-required keys, respectively.
1481
+ Currently the only way to declare both required and non-required keys in the
1482
+ same ``TypedDict `` is mixed inheritance, declaring a ``TypedDict `` with one value
1483
+ for the ``total `` argument and then inheriting it from another ``TypedDict `` with
1484
+ a different value for ``total ``.
1485
+ Usage::
1486
+
1487
+ >>> class Point2D(TypedDict, total=False):
1488
+ ... x: int
1489
+ ... y: int
1490
+ ...
1491
+ >>> class Point3D(Point2D):
1492
+ ... z: int
1493
+ ...
1494
+ >>> Point3D.__required_keys__ == frozenset({'z'})
1495
+ True
1496
+ >>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
1497
+ True
1498
+
1414
1499
See :pep: `589 ` for more examples and detailed rules of using ``TypedDict ``.
1415
1500
1416
1501
.. versionadded :: 3.8
0 commit comments