Extended Callable types

Note

This feature is deprecated. You can usecallback protocols as a replacement.

As an experimental mypy extension, you can specify Callable typesthat support keyword arguments, optional arguments, and more. Whenyou specify the arguments of a Callable, you can choose to supply justthe type of a nameless positional argument, or an “argument specifier”representing a more complicated form of argument. This allows one tomore closely emulate the full range of possibilities given by thedef statement in Python.

As an example, here’s a complicated function definition and thecorresponding Callable:

  1. from typing import Callable
  2. from mypy_extensions import (Arg, DefaultArg, NamedArg,
  3. DefaultNamedArg, VarArg, KwArg)
  4.  
  5. def func(__a: int, # This convention is for nameless arguments
  6. b: int,
  7. c: int = 0,
  8. *args: int,
  9. d: int,
  10. e: int = 0,
  11. **kwargs: int) -> int:
  12. ...
  13.  
  14. F = Callable[[int, # Or Arg(int)
  15. Arg(int, 'b'),
  16. DefaultArg(int, 'c'),
  17. VarArg(int),
  18. NamedArg(int, 'd'),
  19. DefaultNamedArg(int, 'e'),
  20. KwArg(int)],
  21. int]
  22.  
  23. f: F = func

Argument specifiers are special function calls that can specify thefollowing aspects of an argument:

  • its type (the only thing that the basic format supports)
  • its name (if it has one)
  • whether it may be omitted
  • whether it may or must be passed using a keyword
  • whether it is a *args argument (representing the remainingpositional arguments)
  • whether it is a **kwargs argument (representing the remainingkeyword arguments)

The following functions are available in mypy_extensions for thispurpose:

  1. def Arg(type=Any, name=None):
  2. # A normal, mandatory, positional argument.
  3. # If the name is specified it may be passed as a keyword.
  4.  
  5. def DefaultArg(type=Any, name=None):
  6. # An optional positional argument (i.e. with a default value).
  7. # If the name is specified it may be passed as a keyword.
  8.  
  9. def NamedArg(type=Any, name=None):
  10. # A mandatory keyword-only argument.
  11.  
  12. def DefaultNamedArg(type=Any, name=None):
  13. # An optional keyword-only argument (i.e. with a default value).
  14.  
  15. def VarArg(type=Any):
  16. # A *args-style variadic positional argument.
  17. # A single VarArg() specifier represents all remaining
  18. # positional arguments.
  19.  
  20. def KwArg(type=Any):
  21. # A **kwargs-style variadic keyword argument.
  22. # A single KwArg() specifier represents all remaining
  23. # keyword arguments.

In all cases, the type argument defaults to Any, and if thename argument is omitted the argument has no name (the name isrequired for NamedArg and DefaultNamedArg). A basicCallable such as

  1. MyFunc = Callable[[int, str, int], float]

is equivalent to the following:

  1. MyFunc = Callable[[Arg(int), Arg(str), Arg(int)], float]

A Callable with unspecified argument types, such as

  1. MyOtherFunc = Callable[..., int]

is (roughly) equivalent to

  1. MyOtherFunc = Callable[[VarArg(), KwArg()], int]

Note

Each of the functions above currently just returns its typeargument at runtime, so the information contained in the argumentspecifiers is not available at runtime. This limitation isnecessary for backwards compatibility with the existingtyping.py module as present in the Python 3.5+ standard libraryand distributed via PyPI.