|
17 | 17 |
|
18 | 18 | --------------
|
19 | 19 |
|
20 |
| -This module supports type hints as specified by :pep:`484` and :pep:`526`. |
| 20 | +This module provides runtime support for type hints as specified by |
| 21 | +:pep:`484`, :pep:`526`, :pep:`544`, :pep:`586`, :pep:`589`, and :pep:`591`. |
21 | 22 | The most fundamental support consists of the types :data:`Any`, :data:`Union`,
|
22 | 23 | :data:`Tuple`, :data:`Callable`, :class:`TypeVar`, and
|
23 | 24 | :class:`Generic`. For full specification please see :pep:`484`. For
|
@@ -392,6 +393,48 @@ it as a return value) of a more specialized type is a type error. For example::
|
392 | 393 | Use :class:`object` to indicate that a value could be any type in a typesafe
|
393 | 394 | manner. Use :data:`Any` to indicate that a value is dynamically typed.
|
394 | 395 |
|
| 396 | + |
| 397 | +Nominal vs structural subtyping |
| 398 | +------------------------------- |
| 399 | + |
| 400 | +Initially :pep:`484` defined Python static type system as using |
| 401 | +*nominal subtyping*. This means that a class ``A`` is allowed where |
| 402 | +a class ``B`` is expected if and only if ``A`` is a subclass of ``B``. |
| 403 | + |
| 404 | +This requirement previously also applied to abstract base classes, such as |
| 405 | +:class:`Iterable`. The problem with this approach is that a class had |
| 406 | +to be explicitly marked to support them, which is unpythonic and unlike |
| 407 | +what one would normally do in idiomatic dynamically typed Python code. |
| 408 | +For example, this conforms to the :pep:`484`:: |
| 409 | + |
| 410 | + from typing import Sized, Iterable, Iterator |
| 411 | + |
| 412 | + class Bucket(Sized, Iterable[int]): |
| 413 | + ... |
| 414 | + def __len__(self) -> int: ... |
| 415 | + def __iter__(self) -> Iterator[int]: ... |
| 416 | + |
| 417 | +:pep:`544` allows to solve this problem by allowing users to write |
| 418 | +the above code without explicit base classes in the class definition, |
| 419 | +allowing ``Bucket`` to be implicitly considered a subtype of both ``Sized`` |
| 420 | +and ``Iterable[int]`` by static type checkers. This is known as |
| 421 | +*structural subtyping* (or static duck-typing):: |
| 422 | + |
| 423 | + from typing import Iterator, Iterable |
| 424 | + |
| 425 | + class Bucket: # Note: no base classes |
| 426 | + ... |
| 427 | + def __len__(self) -> int: ... |
| 428 | + def __iter__(self) -> Iterator[int]: ... |
| 429 | + |
| 430 | + def collect(items: Iterable[int]) -> int: ... |
| 431 | + result = collect(Bucket()) # Passes type check |
| 432 | + |
| 433 | +Moreover, by subclassing a special class :class:`Protocol`, a user |
| 434 | +can define new custom protocols to fully enjoy structural subtyping |
| 435 | +(see examples below). |
| 436 | + |
| 437 | + |
395 | 438 | Classes, functions, and decorators
|
396 | 439 | ----------------------------------
|
397 | 440 |
|
@@ -459,6 +502,39 @@ The module defines the following classes, functions and decorators:
|
459 | 502 | except KeyError:
|
460 | 503 | return default
|
461 | 504 |
|
| 505 | +.. class:: Protocol(Generic) |
| 506 | + |
| 507 | + Base class for protocol classes. Protocol classes are defined like this:: |
| 508 | + |
| 509 | + class Proto(Protocol): |
| 510 | + def meth(self) -> int: |
| 511 | + ... |
| 512 | + |
| 513 | + Such classes are primarily used with static type checkers that recognize |
| 514 | + structural subtyping (static duck-typing), for example:: |
| 515 | + |
| 516 | + class C: |
| 517 | + def meth(self) -> int: |
| 518 | + return 0 |
| 519 | + |
| 520 | + def func(x: Proto) -> int: |
| 521 | + return x.meth() |
| 522 | + |
| 523 | + func(C()) # Passes static type check |
| 524 | + |
| 525 | + See :pep:`544` for details. Protocol classes decorated with |
| 526 | + :func:`runtime_checkable` (described later) act as simple-minded runtime |
| 527 | + protocols that check only the presence of given attributes, ignoring their |
| 528 | + type signatures. |
| 529 | + |
| 530 | + Protocol classes can be generic, for example:: |
| 531 | + |
| 532 | + class GenProto(Protocol[T]): |
| 533 | + def meth(self) -> T: |
| 534 | + ... |
| 535 | + |
| 536 | + .. versionadded:: 3.8 |
| 537 | + |
462 | 538 | .. class:: Type(Generic[CT_co])
|
463 | 539 |
|
464 | 540 | A variable annotated with ``C`` may accept a value of type ``C``. In
|
@@ -1033,6 +1109,26 @@ The module defines the following classes, functions and decorators:
|
1033 | 1109 | Note that returning instances of private classes is not recommended.
|
1034 | 1110 | It is usually preferable to make such classes public.
|
1035 | 1111 |
|
| 1112 | +.. decorator:: runtime_checkable |
| 1113 | + |
| 1114 | + Mark a protocol class as a runtime protocol. |
| 1115 | + |
| 1116 | + Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. |
| 1117 | + This raises :exc:`TypeError` when applied to a non-protocol class. This |
| 1118 | + allows a simple-minded structural check, very similar to "one trick ponies" |
| 1119 | + in :mod:`collections.abc` such as :class:`Iterable`. For example:: |
| 1120 | + |
| 1121 | + @runtime_checkable |
| 1122 | + class Closable(Protocol): |
| 1123 | + def close(self): ... |
| 1124 | + |
| 1125 | + assert isinstance(open('/some/file'), Closable) |
| 1126 | + |
| 1127 | + **Warning:** this will check only the presence of the required methods, |
| 1128 | + not their type signatures! |
| 1129 | + |
| 1130 | + .. versionadded:: 3.8 |
| 1131 | + |
1036 | 1132 | .. data:: Any
|
1037 | 1133 |
|
1038 | 1134 | Special type indicating an unconstrained type.
|
|
0 commit comments