@@ -117,16 +117,15 @@ annotations have no effect at runtime:
117
117
Abstract base classes and multiple inheritance
118
118
**********************************************
119
119
120
- Mypy uses Python abstract base classes for protocol types. There are
121
- several built-in abstract base classes types (for example,
122
- `` Sequence ``, `` Iterable `` and `` Iterator ``) . You can define abstract
123
- base classes using the ``abc.ABCMeta `` metaclass and the
124
- ``abc.abstractmethod `` function decorator.
120
+ Mypy supports Python abstract base classes (ABCs). Abstract classes
121
+ have at least one abstract method or property that must be implemented
122
+ by a subclass . You can define abstract base classes using the
123
+ ``abc.ABCMeta `` metaclass, and the `` abc.abstractmethod `` and
124
+ ``abc.abstractproperty `` function decorators. Example:
125
125
126
126
.. code-block :: python
127
127
128
128
from abc import ABCMeta, abstractmethod
129
- import typing
130
129
131
130
class A (metaclass = ABCMeta ):
132
131
@abstractmethod
@@ -140,32 +139,31 @@ base classes using the ``abc.ABCMeta`` metaclass and the
140
139
def bar (self ) -> str :
141
140
return ' x'
142
141
143
- a = A() # Error: A is abstract
144
- b = B() # OK
142
+ a = A() # Error: A is abstract
143
+ b = B() # OK
145
144
146
- Unlike most Python code, abstract base classes are likely to play a
147
- significant role in many complex mypy programs.
145
+ Note that mypy performs checking for unimplemented abstract methods
146
+ even if you omit the ``ABCMeta `` metaclass. This can be useful if the
147
+ metaclass would cause runtime metaclass conflicts.
148
148
149
149
A class can inherit any number of classes, both abstract and
150
150
concrete. As with normal overrides, a dynamically typed method can
151
- implement a statically typed abstract method defined in an abstract
152
- base class.
151
+ implement a statically typed method defined in any base class,
152
+ including an abstract method defined in an abstract base class.
153
+
154
+ You can implement an abstract property using either a normal
155
+ property or an instance variable.
153
156
154
157
.. _protocol-types :
155
158
156
159
Protocols and structural subtyping
157
160
**********************************
158
161
159
- .. note ::
160
-
161
- Structural subtyping is experimental. Some things may not
162
- work as expected. Mypy may pass unsafe code or it can reject
163
- valid code.
164
-
165
162
Mypy supports two ways of deciding whether two classes are compatible
166
163
as types: nominal subtyping and structural subtyping. *Nominal *
167
164
subtyping is strictly based on the class hierarchy. If class ``D ``
168
- inherits class ``C ``, it's also a subtype of ``C ``. This form of
165
+ inherits class ``C ``, it's also a subtype of ``C ``, and instances of
166
+ ``D `` can be used when ``C `` instances are expected. This form of
169
167
subtyping is used by default in mypy, since it's easy to understand
170
168
and produces clear and concise error messages, and since it matches
171
169
how the native ``isinstance() `` check works -- based on class
@@ -174,16 +172,239 @@ a structural subtype of class ``C`` if the former has all attributes
174
172
and methods of the latter, and with compatible types.
175
173
176
174
Structural subtyping can be seen as a static equivalent of duck
177
- typing, which is well known to Python programmers. Mypy provides an
178
- opt-in support for structural subtyping via protocol classes described
175
+ typing, which is well known to Python programmers. Mypy provides
176
+ support for structural subtyping via protocol classes described
179
177
below. See `PEP 544 <https://www.python.org/dev/peps/pep-0544/ >`_ for
180
178
the detailed specification of protocols and structural subtyping in
181
179
Python.
182
180
181
+ .. _predefined_protocols :
182
+
183
+ Predefined protocols
184
+ ********************
185
+
186
+ The ``typing `` module defines various protocol classes that correspond
187
+ to common Python protocols, such as ``Iterable[T] ``. If a class
188
+ defines a suitable ``__iter__ `` method, mypy understands that it
189
+ implements the iterable protocol and is compatible with ``Iterable[T] ``.
190
+ For example, ``IntList `` below is iterable, over ``int `` values:
191
+
192
+ .. code-block :: python
193
+
194
+ from typing import Iterator, Iterable, Optional
195
+
196
+ class IntList :
197
+ def __init__ (self , value : int , next : Optional[IntList]) -> None :
198
+ self .value = value
199
+ self .next = next
200
+
201
+ def __iter__ (self ) -> Iterator[int ]:
202
+ current = self
203
+ while current:
204
+ yield current.value
205
+ current = current.next
206
+
207
+ def print_numbered (items : Iterable[int ]) -> None :
208
+ for n, x in enumerate (items):
209
+ print (n + 1 , x)
210
+
211
+ x = IntList(3 , IntList(5 , None ))
212
+ print_numbered(x) # OK
213
+ print_numbered([4 , 5 ]) # Also OK
214
+
215
+ The subsections below introduce all built-in protocols defined in
216
+ ``typing `` and the signatures of the corresponding methods you need to define
217
+ to implement each protocol (the signatures can be left out, as always, but mypy
218
+ won't type check unannotated methods).
219
+
220
+ Iteration protocols
221
+ ...................
222
+
223
+ The iteration protocols are useful in many contexts. For example, they allow
224
+ iteration of objects in for loops.
225
+
226
+ ``Iterable[T] ``
227
+ ---------------
228
+
229
+ The :ref: `example above <predefined_protocols >` has a simple implementation of an
230
+ ``__iter__ `` method.
231
+
232
+ .. code-block :: python
233
+
234
+ def __iter__ (self ) -> Iterator[T]
235
+
236
+ `` Iterator[T]``
237
+ -------------- -
238
+
239
+ .. code- block:: python
240
+
241
+ def __next__ (self ) -> T
242
+ def __iter__ (self ) -> Iterator[T]
243
+
244
+ Collection protocols
245
+ .................. ..
246
+
247
+ Many of these are implemented by built- in container types such as
248
+ `` list `` and `` dict `` , and these are also useful for user- defined
249
+ collection objects.
250
+
251
+ `` Sized``
252
+ -------- -
253
+
254
+ This is a type for objects that support `` len (x)`` .
255
+
256
+ .. code- block:: python
257
+
258
+ def __len__ (self ) -> int
259
+
260
+ `` Container[T]``
261
+ ----------------
262
+
263
+ This is a type for objects that support the `` in `` operator.
264
+
265
+ .. code- block:: python
266
+
267
+ def __contains__ (self , x: object ) -> bool
268
+
269
+ `` Collection[T]``
270
+ ---------------- -
271
+
272
+ .. code- block:: python
273
+
274
+ def __len__ (self ) -> int
275
+ def __iter__ (self ) -> Iterator[T]
276
+ def __contains__ (self , x: object ) -> bool
277
+
278
+ One- off protocols
279
+ ............... ..
280
+
281
+ These protocols are typically only useful with a single standard
282
+ library function or class .
283
+
284
+ `` Reversible[T]``
285
+ ---------------- -
286
+
287
+ This is a type for objects that support `` reversed (x)`` .
288
+
289
+ .. code- block:: python
290
+
291
+ def __reversed__ (self ) -> Iterator[T]
292
+
293
+ `` SupportsAbs[T]``
294
+ ------------------
295
+
296
+ This is a type for objects that support `` abs (x)`` . `` T`` is the type of
297
+ value returned by `` abs (x)`` .
298
+
299
+ .. code- block:: python
300
+
301
+ def __abs__ (self ) -> T
302
+
303
+ `` SupportsBytes``
304
+ ---------------- -
305
+
306
+ This is a type for objects that support `` bytes (x)`` .
307
+
308
+ .. code- block:: python
309
+
310
+ def __bytes__ (self ) -> bytes
311
+
312
+ `` SupportsComplex``
313
+ ------------------ -
314
+
315
+ This is a type for objects that support `` complex (x)`` .
316
+
317
+ .. code- block:: python
318
+
319
+ def __complex__ (self ) -> complex
320
+
321
+ `` SupportsFloat``
322
+ ---------------- -
323
+
324
+ This is a type for objects that support `` float (x)`` .
325
+
326
+ .. code- block:: python
327
+
328
+ def __float__ (self ) -> float
329
+
330
+ `` SupportsInt``
331
+ -------------- -
332
+
333
+ This is a type for objects that support `` int (x)`` .
334
+
335
+ .. code- block:: python
336
+
337
+ def __int__ (self ) -> int
338
+
339
+ `` SupportsRound[T]``
340
+ --------------------
341
+
342
+ This is a type for objects that support `` round (x)`` .
343
+
344
+ .. code- block:: python
345
+
346
+ def __round__ (self ) -> T
347
+
348
+ Async protocols
349
+ ...............
350
+
351
+ These protocols can be useful in async code.
352
+
353
+ `` Awaitable[T]``
354
+ ----------------
355
+
356
+ .. code- block:: python
357
+
358
+ def __await__ (self ) -> Generator[Any, None , T]
359
+
360
+ `` AsyncIterable[T]``
361
+ --------------------
362
+
363
+ .. code- block:: python
364
+
365
+ def __aiter__ (self ) -> AsyncIterator[T]
366
+
367
+ `` AsyncIterator[T]``
368
+ --------------------
369
+
370
+ .. code- block:: python
371
+
372
+ def __anext__ (self ) -> Awaitable[T]
373
+ def __aiter__ (self ) -> AsyncIterator[T]
374
+
375
+ Context manager protocols
376
+ ........................ .
377
+
378
+ There are two protocols for context managers -- one for regular context
379
+ managers and one for async ones. These allow defining objects that can
380
+ be used in `` with `` and `` async with `` statements.
381
+
382
+ `` ContextManager[T]``
383
+ -------------------- -
384
+
385
+ .. code- block:: python
386
+
387
+ def __enter__ (self ) -> T
388
+ def __exit__ (self ,
389
+ exc_type: Optional[Type[BaseException ]],
390
+ exc_value: Optional[BaseException ],
391
+ traceback: Optional[TracebackType]) -> Optional[bool ]
392
+
393
+ `` AsyncContextManager[T]``
394
+ --------------------------
395
+
396
+ .. code- block:: python
397
+
398
+ def __aenter__ (self ) -> Awaitable[T]
399
+ def __aexit__ (self ,
400
+ exc_type: Optional[Type[BaseException ]],
401
+ exc_value: Optional[BaseException ],
402
+ traceback: Optional[TracebackType]) -> Awaitable[Optional[bool ]]
403
+
183
404
Simple user- defined protocols
184
405
*****************************
185
406
186
- You can define a protocol class by inheriting the special
407
+ You can define your own protocol class by inheriting the special
187
408
`` typing_extensions.Protocol`` class :
188
409
189
410
.. code- block:: python
@@ -216,12 +437,10 @@ similarly compatible with the protocol, as they support ``close()``.
216
437
The `` Protocol`` base class is currently provided in the `` typing_extensions``
217
438
package. Once structural subtyping is mature and
218
439
`PEP 544 < https:// www.python.org/ dev/ peps/ pep- 0544 / > ` _ has been accepted,
219
- ``Protocol `` will be included in the ``typing `` module. Several library
220
- types such as ``typing.Sized `` and ``typing.Iterable `` will also be changed
221
- into protocols. They are currently treated as regular ABCs by mypy.
440
+ `` Protocol`` will be included in the `` typing`` module.
222
441
223
- Defining subprotocols
224
- *********************
442
+ Defining subprotocols and subclassing protocols
443
+ ***********************************************
225
444
226
445
You can also define subprotocols. Existing protocols can be extended
227
446
and merged using multiple inheritance. Example:
@@ -249,7 +468,7 @@ and merged using multiple inheritance. Example:
249
468
250
469
Note that inheriting from an existing protocol does not automatically
251
470
turn the subclass into a protocol -- it just creates a regular
252
- (non-protocol) ABC that implements the given protocol (or
471
+ (non- protocol) class or ABC that implements the given protocol (or
253
472
protocols). The `` typing_extensions.Protocol`` base class must always
254
473
be explicitly present if you are defining a protocol:
255
474
@@ -267,6 +486,13 @@ be explicitly present if you are defining a protocol:
267
486
# Error: nominal subtyping used by default
268
487
x: NewProtocol = Concrete() # Error!
269
488
489
+ You can also include default implementations of methods in
490
+ protocols. If you explicitly subclass these protocols you can inherit
491
+ these default implementations. Explicitly including a protocol as a
492
+ base class is also a way of documenting that your class implements a
493
+ particular protocol, and it forces mypy to verify that your class
494
+ implementation is actually compatible with the protocol.
495
+
270
496
.. note::
271
497
272
498
You can use Python 3.6 variable annotations (`PEP 526
@@ -326,6 +552,9 @@ adds support for basic runtime structural checks:
326
552
if isinstance (mug, Portable):
327
553
use(mug.handles) # Works statically and at runtime
328
554
555
+ `` isinstance ()`` also works with the :ref:`predefined protocols < predefined_protocols> `
556
+ in `` typing`` such as `` Iterable`` .
557
+
329
558
.. note::
330
559
`` isinstance ()`` with protocols is not completely safe at runtime.
331
560
For example, signatures of methods are not checked. The runtime
0 commit comments