Callable types (and lambdas)

You can pass around function objects and bound methods in staticallytyped code. The type of a function that accepts arguments A1, …, Anand returns Rt is Callable[[A1, …, An], Rt]. Example:

  1. from typing import Callable
  2.  
  3. def twice(i: int, next: Callable[[int], int]) -> int:
  4. return next(next(i))
  5.  
  6. def add(i: int) -> int:
  7. return i + 1
  8.  
  9. print(twice(3, add)) # 5

You can only have positional arguments, and only ones without defaultvalues, in callable types. These cover the vast majority of uses ofcallable types, but sometimes this isn’t quite enough. Mypy recognizesa special form Callable[…, T] (with a literal ) which canbe used in less typical cases. It is compatible with arbitrarycallable objects that return a type compatible with T, independentof the number, types or kinds of arguments. Mypy lets you call suchcallable values with arbitrary arguments, without any checking – inthis respect they are treated similar to a (args: Any, *kwargs: Any) function signature. Example:

  1. from typing import Callable
  2.  
  3. def arbitrary_call(f: Callable[..., int]) -> int:
  4. return f('x') + f(y=2) # OK
  5.  
  6. arbitrary_call(ord) # No static error, but fails at runtime
  7. arbitrary_call(open) # Error: does not return an int
  8. arbitrary_call(1) # Error: 'int' is not callable

In situations where more precise or complex types of callbacks arenecessary one can use flexible callback protocols.Lambdas are also supported. The lambda argument and return value typescannot be given explicitly; they are always inferred based on contextusing bidirectional type inference:

  1. l = map(lambda x: x + 1, [1, 2, 3]) # Infer x as int and l as List[int]

If you want to give the argument or return value types explicitly, usean ordinary, perhaps nested function definition.