How can I specify the type hint of a variable as a function type? There is no typing.Function
, and I could not find anything in the relevant PEP, PEP 483.

- 62,466
- 11
- 102
- 153

- 11,356
- 5
- 40
- 74
-
73A function is [`Callable`](https://www.python.org/dev/peps/pep-0483/#fundamental-building-blocks) – jonrsharpe Jun 15 '16 at 12:17
-
5https://www.python.org/dev/peps/pep-0483/#fundamental-building-blocks, last bullet point before "we might add". – Jun 15 '16 at 12:18
4 Answers
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]

- 6,013
- 5
- 30
- 38

- 150,925
- 31
- 268
- 253
-
3@javadba - oh, yes, but I'm still not sure on which dial... By the way - what about `Callable[[Arg, Types, Here], ...]` for `*args`, `**kwargs`, keyword-only args and positional only args? Have they not thought about calling convention in the type signatures for callables? ;) – Tomasz Gandor May 28 '20 at 21:05
-
2[According to the docs](https://docs.python.org/3/library/typing.html#typing.Callable), `typing.Callable` seems to be in favor of `collections.abc.Callable`: – Nick Crews Feb 20 '21 at 00:03
-
more info at https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html – the1gofer Apr 08 '22 at 15:40
-
1Note that this is not quite the same thing. A function is a Callable but the programmer might be interested in specific attributes of functions, such as their unique dunder methods. – Christopher Barber Jul 21 '22 at 13:17
-
since all methods take `self` as a parameter, is the answer any different for methods? – Harvs Sep 26 '22 at 12:22
-
nit: the parameters aren't subscripted, that's just a list literal... – somebody Nov 13 '22 at 13:00
-
Is it possible to give variable names along with datatypes in type hints? – Avneesh Mishra Nov 26 '22 at 11:38
Another interesting point to note is that you can use the built in function type()
to get the type of a built in function and use that.
So you could have
def f(my_function: type(abs)) -> int:
return my_function(100)
Or something of that form

- 487
- 3
- 7
-
3A type hint can be whatever you wish, but they haven't always been lazy evaluated. Also, does your function really only take `builtin_function_or_method` as `my_function`? Wouldn't a `lambda` work? A user defined function or bound method? – Tomasz Gandor May 28 '20 at 21:10
-
9No you cannot, when running `mypy`, this gives the error: `error: Invalid type comment or annotation` `note: Suggestion: use type[...] instead of type(...)`. – ruohola Feb 28 '21 at 13:52
-
1note that `type(abs)` is just `builtin_function_or_method`... which i doubt very many things understand (ignoring the fact that it doesn't specify args, and ignoring the fact it's not even correct for this case) – somebody Nov 13 '22 at 13:23
My specific use case for wanting this functionality was to enable rich code completion in PyCharm. Using Callable
didn't cause PyCharm to suggest that the object had a .__code__
attribute, which is what I wanted, in this case.
I stumbled across the types
module and..
from types import FunctionType
allowed me to annotate an object with FunctionType
and, voilà, PyCharm now suggests my object has a .__code__
attribute.
The OP wasn't clear on why this type hint was useful to them. Callable certainly works for anything that implements .__call__()
but for further interface clarification, I submit the types
module.
Bummer that Python needed two very similar modules.

- 6,405
- 6
- 28
- 69

- 1,662
- 3
- 21
- 31
-
3Conversely Pylance in vscode accept only `Callable` and not `FunctionType` as valid. – Karol Zlot Feb 02 '22 at 10:37
In python3 it works without import typing
:
def my_function(other_function: callable):
pass

- 338
- 3
- 6
-
3https://docs.python.org/3/library/typing.html#callable typing.Callable is NOT deprecated – Vladimir Aug 19 '22 at 06:36
-
12this is actually a bit misleading because lowercase callable is actually a built-in function, not a class (or protocol) itself. If you want to allow any class that implements the __call__ method, use Callable from the typing module. If you want to be more specific and allow only functions, use FunctionType from types module. – Nicolas Fonteyne Nov 23 '22 at 19:51
-
2This also raises a TypeError when used as part of a union type: `def my_function(other_function: callable | None):`, at least on Python 3.10 – mcsoini Apr 21 '23 at 09:41