How to Specify the Function Type in My Type Hints

How can I specify the function type in my type hints?

As @jonrsharpe noted in a comment, this can be done with typing.Callable:

from typing import Callable

def my_function(func: Callable):

Note: Callable on its own is equivalent to Callable[..., Any].
Such a Callable takes any number and type of arguments (...) and returns a value of any type (Any). If this is too unconstrained, one may also specify the types of the input argument list and return type.

For example, given:

def sum(a: int, b: int) -> int: return a+b

The corresponding annotation is:

Callable[[int, int], int]

That is, the parameters are sub-scripted in the outer subscription with the return type as the second element in the outer subscription. In general:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]

How to type hint an instance-level function (i.e. not a method)?

This is currently broken in mypy as it assumes you are creating a method, here is the relevant issue https://github.com/python/mypy/issues/708.

Typing the function in the init works fine as it won't think it's a method on the class, the following code passes type checking properly and func's type is inferred from the parameter. The attribute assignment can also be typed directly if the parameter is not viable.

from collections.abc import Callable

class Foo:
def __init__(self, func: Callable[[], int]):
self.func = func

reveal_type(Foo(lambda: 0).func)
###OUTPUT###
file.py:7: note: Revealed type is "def () -> builtins.int"

An another workaround that can be found in the issue and avoids assigning in the init is to use a callback Protocol like so:

from typing import Protocol

class FuncCallback(Protocol):
def __call__(self, /) -> int:
...

class Foo:
func: FuncCallback

def __init__(self, func):
self.func = func

This makes func a FuncCallback protocol which expects no arguments when called and returns an int like your Callable.

What is the type hint for a function

Yes, typing.Callable is the right hint for a callback.

Also see the Callable section of PEP 484:

Frameworks expecting callback functions of specific signatures might be type hinted using Callable[[Arg1Type, Arg2Type], ReturnType].

How to write type hints for a function returning itself?

I think @chepner's answer is great. If you really do want to express this as a recursive Callable type, then you could restructure the function as a callable class and do something like this:

from __future__ import annotations

class F:
def __call__(self) -> F:
return self

f = F()

You can test this with mypy to see that it maintains its type on future calls:

g = f()
h = g(1) # Too many arguments for "__call__" of "F"
i = h()
j = i(2) # Too many arguments for "__call__" of "F"
k = j()

How to type hint function with a callable argument and default value

You could use the @overload for correctly type hinting of function with default argument for your case:

from typing import Callable, List, TypeVar, overload, Set

T = TypeVar("T")

@overload
def transform(data: List[int]) -> Set[int]: ...

@overload
def transform(data: List[int], ret_type: Callable[[List[int]], T]) -> T: ...

# untyped implementation
def transform(data, ret_type = set):
return ret_type(data)

a = [1, 2, 3]
my_set: Set = transform(a)

type hinting a function that takes the return type as parameter

Have a look at Generics, especially TypeVar. You can do something like this:

from typing import TypeVar, Callable

R = TypeVar("R")
D = TypeVar("D")

def mycoerce(data: D, ret_type: Callable[[D], R]) -> R:
return ret_type(data)

a = mycoerce("123", int) # desired: a type hinted to int
b = mycoerce("123", float) # desired: b type hinted to float

print(a, b)


Related Topics



Leave a reply



Submit