Skip to content

Commit f5058bc

Browse files
authored
Update overload docs (#5229)
This pull request overhauls the overloads documentation to reflect the new change in semantics. Specific changes made: 1. Moves documentation about overloads into the "Type System Reference" section -- specifically, in the "More types" page. 2. Modifies the docs to start with a non-dunder example (resolves #4579) and simplifies the `__dunder__` example. 3. Adds documentation about specific checks mypy will perform: in particular, the "no-shadowing" and "no unsafe variant" definition checks. 4. Documents the new "pick the first match" rule. 5. Removes the now out-of-date note about erasure.
1 parent 0ca6bf9 commit f5058bc

File tree

3 files changed

+387
-117
lines changed

3 files changed

+387
-117
lines changed

docs/source/additional_features.rst

-116
Original file line numberDiff line numberDiff line change
@@ -4,122 +4,6 @@ Additional features
44
This section discusses various features that did not fit in naturally in one
55
of the previous sections.
66

7-
.. _function-overloading:
8-
9-
Function overloading
10-
********************
11-
12-
Sometimes the types in a function depend on each other in ways that
13-
can't be captured with a ``Union``. For example, the ``__getitem__``
14-
(``[]`` bracket indexing) method can take an integer and return a
15-
single item, or take a ``slice`` and return a ``Sequence`` of items.
16-
You might be tempted to annotate it like so:
17-
18-
.. code-block:: python
19-
20-
from typing import Sequence, TypeVar, Union
21-
T = TypeVar('T')
22-
23-
class MyList(Sequence[T]):
24-
def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]:
25-
if isinstance(index, int):
26-
... # Return a T here
27-
elif isinstance(index, slice):
28-
... # Return a sequence of Ts here
29-
else:
30-
raise TypeError(...)
31-
32-
But this is too loose, as it implies that when you pass in an ``int``
33-
you might sometimes get out a single item and sometimes a sequence.
34-
The return type depends on the parameter type in a way that can't be
35-
expressed using a type variable. Instead, we can use `overloading
36-
<https://www.python.org/dev/peps/pep-0484/#function-method-overloading>`_
37-
to give the same function multiple type annotations (signatures) and
38-
accurately describe the function's behavior.
39-
40-
.. code-block:: python
41-
42-
from typing import overload, Sequence, TypeVar, Union
43-
T = TypeVar('T')
44-
45-
class MyList(Sequence[T]):
46-
47-
# The @overload definitions are just for the type checker,
48-
# and overwritten by the real implementation below.
49-
@overload
50-
def __getitem__(self, index: int) -> T:
51-
pass # Don't put code here
52-
53-
# All overloads and the implementation must be adjacent
54-
# in the source file, and overload order may matter:
55-
# when two overloads may overlap, the more specific one
56-
# should come first.
57-
@overload
58-
def __getitem__(self, index: slice) -> Sequence[T]:
59-
pass # Don't put code here
60-
61-
# The implementation goes last, without @overload.
62-
# It may or may not have type hints; if it does,
63-
# these are checked against the overload definitions
64-
# as well as against the implementation body.
65-
def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]:
66-
# This is exactly the same as before.
67-
if isinstance(index, int):
68-
... # Return a T here
69-
elif isinstance(index, slice):
70-
... # Return a sequence of Ts here
71-
else:
72-
raise TypeError(...)
73-
74-
Calls to overloaded functions are type checked against the variants,
75-
not against the implementation. A call like ``my_list[5]`` would have
76-
type ``T``, not ``Union[T, Sequence[T]]`` because it matches the
77-
first overloaded definition, and ignores the type annotations on the
78-
implementation of ``__getitem__``. The code in the body of the
79-
definition of ``__getitem__`` is checked against the annotations on
80-
the corresponding declaration. In this case the body is checked
81-
with ``index: Union[int, slice]`` and a return type
82-
``Union[T, Sequence[T]]``. If there are no annotations on the
83-
corresponding definition, then code in the function body is not type
84-
checked.
85-
86-
The annotations on the function body must be compatible with the
87-
types given for the overloaded variants listed above it. The type
88-
checker will verify that all the types for the overloaded variants
89-
are compatible with the types given for the implementation. In this
90-
case it checks that the parameter type ``int`` and the return type
91-
``T`` are compatible with ``Union[int, slice]`` and
92-
``Union[T, Sequence[T]]`` for the first variant. For the second
93-
variant it verifies that the parameter type ``slice`` and the return
94-
type ``Sequence[T]`` are compatible with ``Union[int, slice]`` and
95-
``Union[T, Sequence[T]]``.
96-
97-
Overloaded function variants are still ordinary Python functions and
98-
they still define a single runtime object. There is no automatic
99-
dispatch happening, and you must manually handle the different types
100-
in the implementation (usually with :func:`isinstance` checks, as
101-
shown in the example).
102-
103-
The overload variants must be adjacent in the code. This makes code
104-
clearer, as you don't have to hunt for overload variants across the
105-
file.
106-
107-
Overloads in stub files are exactly the same, except there is no
108-
implementation.
109-
110-
.. note::
111-
112-
As generic type variables are erased at runtime when constructing
113-
instances of generic types, an overloaded function cannot have
114-
variants that only differ in a generic type argument,
115-
e.g. ``List[int]`` and ``List[str]``.
116-
117-
.. note::
118-
119-
If you just need to constrain a type variable to certain types or
120-
subtypes, you can use a :ref:`value restriction
121-
<type-variable-value-restriction>`.
122-
1237
.. _attrs_package:
1248

1259
The attrs package

docs/source/command_line.rst

+2
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ The following options are available:
290290
module (such as ``List[int]`` and ``Dict[str, str]``).
291291

292292

293+
.. _additional-command-line-flags:
294+
293295
Additional command line flags
294296
*****************************
295297

0 commit comments

Comments
 (0)