11Additional features
22-------------------
33
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>`.
5122
6123.. _attrs_package :
7124
@@ -17,6 +134,7 @@ Type annotations can be added as follows:
17134.. code-block :: python
18135
19136 import attr
137+
20138 @attr.s
21139 class A :
22140 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.
28146.. code-block :: python
29147
30148 import attr
149+
31150 @attr.s (auto_attribs = True )
32151 class A :
33152 one: int
@@ -43,6 +162,7 @@ That enables this to work:
43162
44163 import attr
45164 from typing import Dict
165+
46166 @attr.s (auto_attribs = True )
47167 class A :
48168 one: int = attr.ib(8 )
@@ -175,7 +295,7 @@ Caching with mypy daemon
175295========================
176296
177297You 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 ``
179299run after starting or restarting the daemon.
180300
181301The 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:
231351 mypy build to create the cache data, as repeatedly updating cache
232352 data incrementally could result in drift over a long time period (due
233353 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