1
1
Additional features
2
2
-------------------
3
3
4
- This section discusses various features outside core mypy features.
4
+ This section discusses various features that did not fit in naturally in one
5
+ of the previous sections.
6
+
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>`.
5
122
6
123
.. _attrs_package :
7
124
@@ -17,6 +134,7 @@ Type annotations can be added as follows:
17
134
.. code-block :: python
18
135
19
136
import attr
137
+
20
138
@attr.s
21
139
class A :
22
140
one: int = attr.ib() # Variable annotation (Python 3.6+)
@@ -28,6 +146,7 @@ If you're using ``auto_attribs=True`` you must use variable annotations.
28
146
.. code-block :: python
29
147
30
148
import attr
149
+
31
150
@attr.s (auto_attribs = True )
32
151
class A :
33
152
one: int
@@ -43,6 +162,7 @@ That enables this to work:
43
162
44
163
import attr
45
164
from typing import Dict
165
+
46
166
@attr.s (auto_attribs = True )
47
167
class A :
48
168
one: int = attr.ib(8 )
@@ -175,7 +295,7 @@ Caching with mypy daemon
175
295
========================
176
296
177
297
You can also use remote caching with the :ref: `mypy daemon <mypy_daemon >`.
178
- The remote cache will significantly speed up the the first ``dmypy check ``
298
+ The remote cache will significantly speed up the first ``dmypy check ``
179
299
run after starting or restarting the daemon.
180
300
181
301
The mypy daemon requires extra fine-grained dependency data in
@@ -231,3 +351,129 @@ at least if your codebase is hundreds of thousands of lines or more:
231
351
mypy build to create the cache data, as repeatedly updating cache
232
352
data incrementally could result in drift over a long time period (due
233
353
to a mypy caching issue, perhaps).
354
+
355
+ .. _extended_callable :
356
+
357
+ Extended Callable types
358
+ ***********************
359
+
360
+ As an experimental mypy extension, you can specify ``Callable `` types
361
+ that support keyword arguments, optional arguments, and more. When
362
+ you specify the arguments of a Callable, you can choose to supply just
363
+ the type of a nameless positional argument, or an "argument specifier"
364
+ representing a more complicated form of argument. This allows one to
365
+ more closely emulate the full range of possibilities given by the
366
+ ``def `` statement in Python.
367
+
368
+ As an example, here's a complicated function definition and the
369
+ corresponding ``Callable ``:
370
+
371
+ .. code-block :: python
372
+
373
+ from typing import Callable
374
+ from mypy_extensions import (Arg, DefaultArg, NamedArg,
375
+ DefaultNamedArg, VarArg, KwArg)
376
+
377
+ def func (__a : int , # This convention is for nameless arguments
378
+ b : int ,
379
+ c : int = 0 ,
380
+ * args : int ,
381
+ d : int ,
382
+ e : int = 0 ,
383
+ ** kwargs : int ) -> int :
384
+ ...
385
+
386
+ F = Callable[[int , # Or Arg(int)
387
+ Arg(int , ' b' ),
388
+ DefaultArg(int , ' c' ),
389
+ VarArg(int ),
390
+ NamedArg(int , ' d' ),
391
+ DefaultNamedArg(int , ' e' ),
392
+ KwArg(int )],
393
+ int ]
394
+
395
+ f: F = func
396
+
397
+ Argument specifiers are special function calls that can specify the
398
+ following aspects of an argument:
399
+
400
+ - its type (the only thing that the basic format supports)
401
+
402
+ - its name (if it has one)
403
+
404
+ - whether it may be omitted
405
+
406
+ - whether it may or must be passed using a keyword
407
+
408
+ - whether it is a ``*args `` argument (representing the remaining
409
+ positional arguments)
410
+
411
+ - whether it is a ``**kwargs `` argument (representing the remaining
412
+ keyword arguments)
413
+
414
+ The following functions are available in ``mypy_extensions `` for this
415
+ purpose:
416
+
417
+ .. code-block :: python
418
+
419
+ def Arg (type = Any, name = None ):
420
+ # A normal, mandatory, positional argument.
421
+ # If the name is specified it may be passed as a keyword.
422
+
423
+ def DefaultArg (type = Any, name = None ):
424
+ # An optional positional argument (i.e. with a default value).
425
+ # If the name is specified it may be passed as a keyword.
426
+
427
+ def NamedArg (type = Any, name = None ):
428
+ # A mandatory keyword-only argument.
429
+
430
+ def DefaultNamedArg (type = Any, name = None ):
431
+ # An optional keyword-only argument (i.e. with a default value).
432
+
433
+ def VarArg (type = Any):
434
+ # A *args-style variadic positional argument.
435
+ # A single VarArg() specifier represents all remaining
436
+ # positional arguments.
437
+
438
+ def KwArg (type = Any):
439
+ # A **kwargs-style variadic keyword argument.
440
+ # A single KwArg() specifier represents all remaining
441
+ # keyword arguments.
442
+
443
+ In all cases, the ``type `` argument defaults to ``Any ``, and if the
444
+ ``name `` argument is omitted the argument has no name (the name is
445
+ required for ``NamedArg `` and ``DefaultNamedArg ``). A basic
446
+ ``Callable `` such as
447
+
448
+ .. code-block :: python
449
+
450
+ MyFunc = Callable[[int , str , int ], float ]
451
+
452
+ is equivalent to the following:
453
+
454
+ .. code-block :: python
455
+
456
+ MyFunc = Callable[[Arg(int ), Arg(str ), Arg(int )], float ]
457
+
458
+ A ``Callable `` with unspecified argument types, such as
459
+
460
+ .. code-block :: python
461
+
462
+ MyOtherFunc = Callable[... , int ]
463
+
464
+ is (roughly) equivalent to
465
+
466
+ .. code-block :: python
467
+
468
+ MyOtherFunc = Callable[[VarArg(), KwArg()], int ]
469
+
470
+ .. note ::
471
+
472
+ This feature is experimental. Details of the implementation may
473
+ change and there may be unknown limitations. **IMPORTANT: **
474
+ Each of the functions above currently just returns its ``type ``
475
+ argument, so the information contained in the argument specifiers
476
+ is not available at runtime. This limitation is necessary for
477
+ backwards compatibility with the existing ``typing.py `` module as
478
+ present in the Python 3.5+ standard library and distributed via
479
+ PyPI.
0 commit comments