@@ -34,39 +34,45 @@ Useful built-in types
34
34
35
35
.. code-block :: python
36
36
37
- from typing import List, Set, Dict, Tuple, Optional
38
-
39
37
# For most types, just use the name of the type
40
38
x: int = 1
41
39
x: float = 1.0
42
40
x: bool = True
43
41
x: str = " test"
44
42
x: bytes = b " test"
45
43
46
- # For collections, the type of the collection item is in brackets
47
- # (Python 3.9+)
44
+ # For collections on Python 3.9+, the type of the collection item is in brackets
48
45
x: list[int ] = [1 ]
49
46
x: set[int ] = {6 , 7 }
50
47
51
- # In Python 3.8 and earlier, the name of the collection type is
52
- # capitalized, and the type is imported from the 'typing' module
53
- x: List[int ] = [1 ]
54
- x: Set[int ] = {6 , 7 }
55
-
56
48
# For mappings, we need the types of both keys and values
57
49
x: dict[str , float ] = {" field" : 2.0 } # Python 3.9+
58
- x: Dict[str , float ] = {" field" : 2.0 }
59
50
60
51
# For tuples of fixed size, we specify the types of all the elements
61
52
x: tuple[int , str , float ] = (3 , " yes" , 7.5 ) # Python 3.9+
62
- x: Tuple[int , str , float ] = (3 , " yes" , 7.5 )
63
53
64
54
# For tuples of variable size, we use one type and ellipsis
65
55
x: tuple[int , ... ] = (1 , 2 , 3 ) # Python 3.9+
56
+
57
+ # On Python 3.8 and earlier, the name of the collection type is
58
+ # capitalized, and the type is imported from the 'typing' module
59
+ from typing import List, Set, Dict, Tuple
60
+ x: List[int ] = [1 ]
61
+ x: Set[int ] = {6 , 7 }
62
+ x: Dict[str , float ] = {" field" : 2.0 }
63
+ x: Tuple[int , str , float ] = (3 , " yes" , 7.5 )
66
64
x: Tuple[int , ... ] = (1 , 2 , 3 )
67
65
68
- # Use Optional[] for values that could be None
69
- x: Optional[str ] = some_function()
66
+ from typing import Union, Optional
67
+
68
+ # On Python 3.10+, use the | operator when something could be one of a few types
69
+ x: list[int | str ] = [3 , 5 , " test" , " fun" ] # Python 3.10+
70
+ # On earlier versions, use Union
71
+ x: list[Union[int , str ]] = [3 , 5 , " test" , " fun" ]
72
+
73
+ # Use Optional[X] for a value that could be None
74
+ # Optional[X] is the same as X | None or Union[X, None]
75
+ x: Optional[str ] = " something" if some_condition() else None
70
76
# Mypy understands a value can't be None in an if-statement
71
77
if x is not None :
72
78
print (x.upper())
@@ -89,9 +95,10 @@ Functions
89
95
def plus (num1 : int , num2 : int ) -> int :
90
96
return num1 + num2
91
97
92
- # Add default value for an argument after the type annotation
93
- def f (num1 : int , my_float : float = 3.5 ) -> float :
94
- return num1 + my_float
98
+ # If a function does not return a value, use None as the return type
99
+ # Default value for an argument goes after the type annotation
100
+ def show (value : str , excitement : int = 10 ) -> None :
101
+ print (value + " !" * excitement)
95
102
96
103
# This is how you annotate a callable (function) value
97
104
x: Callable[[int , float ], float ] = f
@@ -124,13 +131,61 @@ Functions
124
131
quux(3 , 5 ) # error: Too many positional arguments for "quux"
125
132
quux(x = 3 , y = 5 ) # error: Unexpected keyword argument "x" for "quux"
126
133
127
- # This makes each positional arg and each keyword arg a "str"
134
+ # This says each positional arg and each keyword arg is a "str"
128
135
def call (self , * args : str , ** kwargs : str ) -> str :
129
136
reveal_type(args) # Revealed type is "tuple[str, ...]"
130
137
reveal_type(kwargs) # Revealed type is "dict[str, str]"
131
138
request = make_request(* args, ** kwargs)
132
139
return self .do_api_query(request)
133
140
141
+ Classes
142
+ *******
143
+
144
+ .. code-block :: python
145
+
146
+ class MyClass :
147
+ # You can optionally declare instance variables in the class body
148
+ attr: int
149
+ # This is an instance variable with a default value
150
+ charge_percent: int = 100
151
+
152
+ # The "__init__" method doesn't return anything, so it gets return
153
+ # type "None" just like any other method that doesn't return anything
154
+ def __init__ (self ) -> None :
155
+ ...
156
+
157
+ # For instance methods, omit type for "self"
158
+ def my_method (self , num : int , str1 : str ) -> str :
159
+ return num * str1
160
+
161
+ # User-defined classes are valid as types in annotations
162
+ x: MyClass = MyClass()
163
+
164
+ # You can also declare the type of an attribute in "__init__"
165
+ class Box :
166
+ def __init__ (self ) -> None :
167
+ self .items: list[str ] = []
168
+
169
+ # You can use the ClassVar annotation to declare a class variable
170
+ class Car :
171
+ seats: ClassVar[int ] = 4
172
+ passengers: ClassVar[list[str ]]
173
+
174
+ # If you want dynamic attributes on your class, have it
175
+ # override "__setattr__" or "__getattr__":
176
+ # - "__getattr__" allows for dynamic access to names
177
+ # - "__setattr__" allows for dynamic assignment to names
178
+ class A :
179
+ # This will allow assignment to any A.x, if x is the same type as "value"
180
+ # (use "value: Any" to allow arbitrary types)
181
+ def __setattr__ (self , name : str , value : int ) -> None : ...
182
+
183
+ # This will allow access to any A.x, if x is compatible with the return type
184
+ def __getattr__ (self , name : str ) -> int : ...
185
+
186
+ a.foo = 42 # Works
187
+ a.bar = ' Ex-parrot' # Fails type checking
188
+
134
189
When you're puzzled or when things are complicated
135
190
**************************************************
136
191
@@ -143,9 +198,6 @@ When you're puzzled or when things are complicated
143
198
# message with the type; remove it again before running the code.
144
199
reveal_type(1 ) # Revealed type is "builtins.int"
145
200
146
- # Use Union when something could be one of a few types
147
- x: list[Union[int , str ]] = [3 , 5 , " test" , " fun" ]
148
-
149
201
# If you initialize a variable with an empty container or "None"
150
202
# you may have to help mypy a bit by providing an explicit type annotation
151
203
x: list[str ] = []
@@ -154,6 +206,8 @@ When you're puzzled or when things are complicated
154
206
# Use Any if you don't know the type of something or it's too
155
207
# dynamic to write a type for
156
208
x: Any = mystery_function()
209
+ # Mypy will let you do anything with x!
210
+ x.whatever() * x[" you" ] + x(" want" ) - any (x) and all (x) is super # no errors
157
211
158
212
# Use a "type: ignore" comment to suppress errors on a given line,
159
213
# when your code confuses mypy or runs into an outright bug in mypy.
@@ -216,56 +270,6 @@ that are common in idiomatic Python are standardized.
216
270
217
271
You can even make your own duck types using :ref: `protocol-types `.
218
272
219
- Classes
220
- *******
221
-
222
- .. code-block :: python
223
-
224
- class MyClass :
225
- # You can optionally declare instance variables in the class body
226
- attr: int
227
- # This is an instance variable with a default value
228
- charge_percent: int = 100
229
-
230
- # The "__init__" method doesn't return anything, so it gets return
231
- # type "None" just like any other method that doesn't return anything
232
- def __init__ (self ) -> None :
233
- ...
234
-
235
- # For instance methods, omit type for "self"
236
- def my_method (self , num : int , str1 : str ) -> str :
237
- return num * str1
238
-
239
- # User-defined classes are valid as types in annotations
240
- x: MyClass = MyClass()
241
-
242
- # You can use the ClassVar annotation to declare a class variable
243
- class Car :
244
- seats: ClassVar[int ] = 4
245
- passengers: ClassVar[list[str ]]
246
-
247
- # You can also declare the type of an attribute in "__init__"
248
- class Box :
249
- def __init__ (self ) -> None :
250
- self .items: list[str ] = []
251
-
252
- # If you want dynamic attributes on your class, have it override "__setattr__"
253
- # or "__getattr__" in a stub or in your source code.
254
- #
255
- # "__setattr__" allows for dynamic assignment to names
256
- # "__getattr__" allows for dynamic access to names
257
- class A :
258
- # This will allow assignment to any A.x, if x is the same type as "value"
259
- # (use "value: Any" to allow arbitrary types)
260
- def __setattr__ (self , name : str , value : int ) -> None : ...
261
-
262
- # This will allow access to any A.x, if x is compatible with the return type
263
- def __getattr__ (self , name : str ) -> int : ...
264
-
265
- a.foo = 42 # Works
266
- a.bar = ' Ex-parrot' # Fails type checking
267
-
268
-
269
273
Coroutines and asyncio
270
274
**********************
271
275
@@ -290,11 +294,7 @@ Miscellaneous
290
294
.. code-block :: python
291
295
292
296
import sys
293
- import re
294
- from typing import Match, IO
295
-
296
- # "typing.Match" describes regex matches from the re module
297
- x: Match[str ] = re.match(r ' [0-9 ]+ ' , " 15" )
297
+ from typing import IO
298
298
299
299
# Use IO[] for functions that should accept or return any
300
300
# object that comes from an open() call (IO[] does not
@@ -309,7 +309,7 @@ Miscellaneous
309
309
310
310
# Forward references are useful if you want to reference a class before
311
311
# it is defined
312
- def f (foo : A) -> int : # This will fail
312
+ def f (foo : A) -> int : # This will fail at runtime with 'A' is not defined
313
313
...
314
314
315
315
class A :
0 commit comments