@@ -2,7 +2,7 @@ More types
2
2
==========
3
3
4
4
This section introduces a few additional kinds of types, including :py:data: `~typing.NoReturn `,
5
- :py:func: `NewType <typing.NewType> `, `` TypedDict ``, and types for async code. It also discusses
5
+ :py:func: `NewType <typing.NewType> `, and types for async code. It also discusses
6
6
how to give functions more precise types using overloads. All of these are only
7
7
situationally useful, so feel free to skip this section and come back when you
8
8
have a need for some of them.
@@ -20,9 +20,6 @@ Here's a quick summary of what's covered here:
20
20
signatures. This is useful if you need to encode a relationship between the
21
21
arguments and the return type that would be difficult to express normally.
22
22
23
- * ``TypedDict `` lets you give precise types for dictionaries that represent
24
- objects with a fixed schema, such as ``{'id': 1, 'items': ['x']} ``.
25
-
26
23
* Async types let you type check programs using ``async `` and ``await ``.
27
24
28
25
.. _noreturn :
@@ -949,252 +946,3 @@ generator type as the return type:
949
946
loop = asyncio.get_event_loop()
950
947
loop.run_until_complete(countdown_2(" USS Enterprise" , 5 ))
951
948
loop.close()
952
-
953
-
954
- .. _typeddict :
955
-
956
- TypedDict
957
- *********
958
-
959
- Python programs often use dictionaries with string keys to represent objects.
960
- Here is a typical example:
961
-
962
- .. code-block :: python
963
-
964
- movie = {' name' : ' Blade Runner' , ' year' : 1982 }
965
-
966
- Only a fixed set of string keys is expected (``'name' `` and
967
- ``'year' `` above), and each key has an independent value type (``str ``
968
- for ``'name' `` and ``int `` for ``'year' `` above). We've previously
969
- seen the ``dict[K, V] `` type, which lets you declare uniform
970
- dictionary types, where every value has the same type, and arbitrary keys
971
- are supported. This is clearly not a good fit for
972
- ``movie `` above. Instead, you can use a ``TypedDict `` to give a precise
973
- type for objects like ``movie ``, where the type of each
974
- dictionary value depends on the key:
975
-
976
- .. code-block :: python
977
-
978
- from typing_extensions import TypedDict
979
-
980
- Movie = TypedDict(' Movie' , {' name' : str , ' year' : int })
981
-
982
- movie: Movie = {' name' : ' Blade Runner' , ' year' : 1982 }
983
-
984
- ``Movie `` is a ``TypedDict `` type with two items: ``'name' `` (with type ``str ``)
985
- and ``'year' `` (with type ``int ``). Note that we used an explicit type
986
- annotation for the ``movie `` variable. This type annotation is
987
- important -- without it, mypy will try to infer a regular, uniform
988
- :py:class: `dict ` type for ``movie ``, which is not what we want here.
989
-
990
- .. note ::
991
-
992
- If you pass a ``TypedDict `` object as an argument to a function, no
993
- type annotation is usually necessary since mypy can infer the
994
- desired type based on the declared argument type. Also, if an
995
- assignment target has been previously defined, and it has a
996
- ``TypedDict `` type, mypy will treat the assigned value as a ``TypedDict ``,
997
- not :py:class: `dict `.
998
-
999
- Now mypy will recognize these as valid:
1000
-
1001
- .. code-block :: python
1002
-
1003
- name = movie[' name' ] # Okay; type of name is str
1004
- year = movie[' year' ] # Okay; type of year is int
1005
-
1006
- Mypy will detect an invalid key as an error:
1007
-
1008
- .. code-block :: python
1009
-
1010
- director = movie[' director' ] # Error: 'director' is not a valid key
1011
-
1012
- Mypy will also reject a runtime-computed expression as a key, as
1013
- it can't verify that it's a valid key. You can only use string
1014
- literals as ``TypedDict `` keys.
1015
-
1016
- The ``TypedDict `` type object can also act as a constructor. It
1017
- returns a normal :py:class: `dict ` object at runtime -- a ``TypedDict `` does
1018
- not define a new runtime type:
1019
-
1020
- .. code-block :: python
1021
-
1022
- toy_story = Movie(name = ' Toy Story' , year = 1995 )
1023
-
1024
- This is equivalent to just constructing a dictionary directly using
1025
- ``{ ... } `` or ``dict(key=value, ...) ``. The constructor form is
1026
- sometimes convenient, since it can be used without a type annotation,
1027
- and it also makes the type of the object explicit.
1028
-
1029
- Like all types, ``TypedDict ``\s can be used as components to build
1030
- arbitrarily complex types. For example, you can define nested
1031
- ``TypedDict ``\s and containers with ``TypedDict `` items.
1032
- Unlike most other types, mypy uses structural compatibility checking
1033
- (or structural subtyping) with ``TypedDict ``\s . A ``TypedDict `` object with
1034
- extra items is compatible with (a subtype of) a narrower
1035
- ``TypedDict ``, assuming item types are compatible (*totality * also affects
1036
- subtyping, as discussed below).
1037
-
1038
- A ``TypedDict `` object is not a subtype of the regular ``dict[...] ``
1039
- type (and vice versa), since :py:class: `dict ` allows arbitrary keys to be
1040
- added and removed, unlike ``TypedDict ``. However, any ``TypedDict `` object is
1041
- a subtype of (that is, compatible with) ``Mapping[str, object] ``, since
1042
- :py:class: `~typing.Mapping ` only provides read-only access to the dictionary items:
1043
-
1044
- .. code-block :: python
1045
-
1046
- def print_typed_dict (obj : Mapping[str , object ]) -> None :
1047
- for key, value in obj.items():
1048
- print (f ' { key} : { value} ' )
1049
-
1050
- print_typed_dict(Movie(name = ' Toy Story' , year = 1995 )) # OK
1051
-
1052
- .. note ::
1053
-
1054
- Unless you are on Python 3.8 or newer (where ``TypedDict `` is available in
1055
- standard library :py:mod: `typing ` module) you need to install ``typing_extensions ``
1056
- using pip to use ``TypedDict ``:
1057
-
1058
- .. code-block :: text
1059
-
1060
- python3 -m pip install --upgrade typing-extensions
1061
-
1062
- Totality
1063
- --------
1064
-
1065
- By default mypy ensures that a ``TypedDict `` object has all the specified
1066
- keys. This will be flagged as an error:
1067
-
1068
- .. code-block :: python
1069
-
1070
- # Error: 'year' missing
1071
- toy_story: Movie = {' name' : ' Toy Story' }
1072
-
1073
- Sometimes you want to allow keys to be left out when creating a
1074
- ``TypedDict `` object. You can provide the ``total=False `` argument to
1075
- ``TypedDict(...) `` to achieve this:
1076
-
1077
- .. code-block :: python
1078
-
1079
- GuiOptions = TypedDict(
1080
- ' GuiOptions' , {' language' : str , ' color' : str }, total = False )
1081
- options: GuiOptions = {} # Okay
1082
- options[' language' ] = ' en'
1083
-
1084
- You may need to use :py:meth: `~dict.get ` to access items of a partial (non-total)
1085
- ``TypedDict ``, since indexing using ``[] `` could fail at runtime.
1086
- However, mypy still lets use ``[] `` with a partial ``TypedDict `` -- you
1087
- just need to be careful with it, as it could result in a :py:exc: `KeyError `.
1088
- Requiring :py:meth: `~dict.get ` everywhere would be too cumbersome. (Note that you
1089
- are free to use :py:meth: `~dict.get ` with total ``TypedDict ``\s as well.)
1090
-
1091
- Keys that aren't required are shown with a ``? `` in error messages:
1092
-
1093
- .. code-block :: python
1094
-
1095
- # Revealed type is "TypedDict('GuiOptions', {'language'?: builtins.str,
1096
- # 'color'?: builtins.str})"
1097
- reveal_type(options)
1098
-
1099
- Totality also affects structural compatibility. You can't use a partial
1100
- ``TypedDict `` when a total one is expected. Also, a total ``TypedDict `` is not
1101
- valid when a partial one is expected.
1102
-
1103
- Supported operations
1104
- --------------------
1105
-
1106
- ``TypedDict `` objects support a subset of dictionary operations and methods.
1107
- You must use string literals as keys when calling most of the methods,
1108
- as otherwise mypy won't be able to check that the key is valid. List
1109
- of supported operations:
1110
-
1111
- * Anything included in :py:class: `~typing.Mapping `:
1112
-
1113
- * ``d[key] ``
1114
- * ``key in d ``
1115
- * ``len(d) ``
1116
- * ``for key in d `` (iteration)
1117
- * :py:meth: `d.get(key[, default]) <dict.get> `
1118
- * :py:meth: `d.keys() <dict.keys> `
1119
- * :py:meth: `d.values() <dict.values> `
1120
- * :py:meth: `d.items() <dict.items> `
1121
-
1122
- * :py:meth: `d.copy() <dict.copy> `
1123
- * :py:meth: `d.setdefault(key, default) <dict.setdefault> `
1124
- * :py:meth: `d1.update(d2) <dict.update> `
1125
- * :py:meth: `d.pop(key[, default]) <dict.pop> ` (partial ``TypedDict ``\s only)
1126
- * ``del d[key] `` (partial ``TypedDict ``\s only)
1127
-
1128
- .. note ::
1129
-
1130
- :py:meth: `~dict.clear ` and :py:meth: `~dict.popitem ` are not supported since they are unsafe
1131
- -- they could delete required ``TypedDict `` items that are not visible to
1132
- mypy because of structural subtyping.
1133
-
1134
- Class-based syntax
1135
- ------------------
1136
-
1137
- An alternative, class-based syntax to define a ``TypedDict `` is supported
1138
- in Python 3.6 and later:
1139
-
1140
- .. code-block :: python
1141
-
1142
- from typing_extensions import TypedDict
1143
-
1144
- class Movie (TypedDict ):
1145
- name: str
1146
- year: int
1147
-
1148
- The above definition is equivalent to the original ``Movie ``
1149
- definition. It doesn't actually define a real class. This syntax also
1150
- supports a form of inheritance -- subclasses can define additional
1151
- items. However, this is primarily a notational shortcut. Since mypy
1152
- uses structural compatibility with ``TypedDict ``\s , inheritance is not
1153
- required for compatibility. Here is an example of inheritance:
1154
-
1155
- .. code-block :: python
1156
-
1157
- class Movie (TypedDict ):
1158
- name: str
1159
- year: int
1160
-
1161
- class BookBasedMovie (Movie ):
1162
- based_on: str
1163
-
1164
- Now ``BookBasedMovie `` has keys ``name ``, ``year `` and ``based_on ``.
1165
-
1166
- Mixing required and non-required items
1167
- --------------------------------------
1168
-
1169
- In addition to allowing reuse across ``TypedDict `` types, inheritance also allows
1170
- you to mix required and non-required (using ``total=False ``) items
1171
- in a single ``TypedDict ``. Example:
1172
-
1173
- .. code-block :: python
1174
-
1175
- class MovieBase (TypedDict ):
1176
- name: str
1177
- year: int
1178
-
1179
- class Movie (MovieBase , total = False ):
1180
- based_on: str
1181
-
1182
- Now ``Movie `` has required keys ``name `` and ``year ``, while ``based_on ``
1183
- can be left out when constructing an object. A ``TypedDict `` with a mix of required
1184
- and non-required keys, such as ``Movie `` above, will only be compatible with
1185
- another ``TypedDict `` if all required keys in the other ``TypedDict `` are required keys in the
1186
- first ``TypedDict ``, and all non-required keys of the other ``TypedDict `` are also non-required keys
1187
- in the first ``TypedDict ``.
1188
-
1189
- Unions of TypedDicts
1190
- --------------------
1191
-
1192
- Since TypedDicts are really just regular dicts at runtime, it is not possible to
1193
- use ``isinstance `` checks to distinguish between different variants of a Union of
1194
- TypedDict in the same way you can with regular objects.
1195
-
1196
- Instead, you can use the :ref: `tagged union pattern <tagged_unions >`. The referenced
1197
- section of the docs has a full description with an example, but in short, you will
1198
- need to give each TypedDict the same key where each value has a unique
1199
- :ref: `Literal type <literal_types >`. Then, check that key to distinguish
1200
- between your TypedDicts.
0 commit comments