typing.Callable is the type you use to indicate a callable. Most python types that support the () operator are of the type collections.abc.Callable. Examples include functions, classmethods, staticmethods, bound methods and lambdas.

In summary, anything with a __call__ method (which is how () is implemented), is a callable.

PEP 677 attempted to introduce implicit tuple-with-arrow syntax, so that something like Callable[[int, str], list[float]] could be expressed much more intuitively as (int, str) -> list[float]. The PEP was rejected because the benefits of the new syntax were not deemed sufficient given the added maintenance burden and possible room for confusion.

Answer from Mad Physicist on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › library › typing.html
typing — Support for type hints
1 week ago - Note that these checks are enforced only by the static type checker. At runtime, the statement Derived = NewType('Derived', Base) will make Derived a callable that immediately returns whatever parameter you pass it.
🌐
Python.org
discuss.python.org › typing
The structural type of typing.Callable - Typing - Discussions on Python.org
June 14, 2024 - I originally asked this question in python/typing, but I thought it would be useful to revisit it here. The structure of typing.Callable seems a bit of a gray area at the moment. It is defined as a special-form in typeshed, so I assume that all type checkers have their own internal definition somewhere.
Discussions

PEP 677 – Callable Type Syntax
I'm so happy that python is taking typing seriously. More on reddit.com
🌐 r/Python
76
133
December 14, 2021
python typing signature (typing.Callable) for function with kwargs - Stack Overflow
I heavily use python typing support from python 3. Recently I was trying to pass a function as an argument and I do not find any help for using kwargs in typing.Callable signature. Please check the... More on stackoverflow.com
🌐 stackoverflow.com
Subtyping rules for `...` in callable types - Typing - Discussions on Python.org
I’m planning to write a new chapter for the typing spec that focuses on subtyping rules for callable types. This is an area that has always been underspecified in the spec and the typing PEPs. One topic that I’d like to get feedback on before writing the chapter has to do with the subtyping ... More on discuss.python.org
🌐 discuss.python.org
1
April 2, 2024
Proposal: Generalize `Callable` to be able to specify argument names and kinds
These don't cleanly match the actual types of callable objects in Python. Argument names, whether arguments are optional, and whether arguments are *args or **kwargs do affect the type of a callable. We should be able to spell these things in the type language. More on github.com
🌐 github.com
48
August 19, 2016
Top answer
1 of 4
66

typing.Callable is the type you use to indicate a callable. Most python types that support the () operator are of the type collections.abc.Callable. Examples include functions, classmethods, staticmethods, bound methods and lambdas.

In summary, anything with a __call__ method (which is how () is implemented), is a callable.

PEP 677 attempted to introduce implicit tuple-with-arrow syntax, so that something like Callable[[int, str], list[float]] could be expressed much more intuitively as (int, str) -> list[float]. The PEP was rejected because the benefits of the new syntax were not deemed sufficient given the added maintenance burden and possible room for confusion.

2 of 4
33

The typing module is used for type hints:

This module provides runtime support for type hints.

What are type hints?

The documentation provides this example:

def greeting(name: str) -> str:
    return 'Hello ' + name

In the function greeting, the argument name is expected to be of type str and the return type str. Subtypes are accepted as arguments.

How to use typing.Callable

Assume you want to define a function that takes two integers and performs some kind of operation on them that returns another integer:

def apply_func(a: int, b: int, func) -> int:
    return func(a, b)

So the expected type of the func argument in apply_func is "something that can be called (e.g. a function) that takes two integer arguments and returns an integer":

typing.Callable[[int, int], int]

Why bother with type hints in the first place?

Using type hints enables you to perform type checking. If you use an IDE like PyCharm or Visual Studio Code, you'll get visual feedback if you're using unexpected types:

🌐
Python
typing.python.org › en › latest › spec › callables.html
Callables — typing documentation
Variadic positional parameter types can be defined with an unpacked tuple of the form *tuple[int, ...] in the parameter list. The first argument specifies the type of the variadic parameters. For example, the following defines a callable that accepts any number of integer arguments: type VarCallback = Callable[[*tuple[int, ...]], None]
🌐
Reddit
reddit.com › r/python › pep 677 – callable type syntax
r/Python on Reddit: PEP 677 – Callable Type Syntax
December 14, 2021 - ContainerType = Callable[[int], datetime] Or ContainerType = (int) -> datetime · I wouldn't want to have to add a dataclass into the mix just for clean typehints. ... Oh man, now I hate -> in Python.
Top answer
1 of 2
147

You are probably looking for Callback protocols.

In short, when you want to express a callable with a complex signature, what you'll want to do is to create a custom Protocol that defines a __call__ method with the precise signature you want.

For example, in your case:

from typing import Protocol

# Or, if you want to support Python 3.7 and below, install the typing_extensions
# module via pip and do the below:
from typing_extensions import Protocol

class MyCallable(Protocol):
    def __call__(self, a: int, b: float) -> float: ...

def good(a: int, b: float) -> float: ...

def bad(x: int, y: float) -> float: ...


def function_executor(a: int, b: float, fn: MyCallable) -> float:
    return fn(a=a, b=b)

function_executor(1, 2.3, good)  # Ok!
function_executor(1, 2.3, bad)   # Errors

If you try type-checking this program using mypy, you'll get the following (admittedly cryptic) error on the last line:

Argument 3 to "function_executor" has incompatible type "Callable[[int, float], float]"; expected "MyCallable"

(Callback protocols are somewhat new, so hopefully the quality of the error messages will improve over time.)

2 of 2
19

I found the example with the typing callback a bit complicated. For anyone looking for a simple example of typing a function with kwargs:

from typing import Protocol

class MyCallable(Protocol):
    # Define types here, as if __call__ were a function (ignore self).
    def __call__(self, a: int, b: int) -> int:
        ...

# Generic function- types correspond to MyCallable.__call__ args.
def func_add(a: int, b: int) -> int:
    return a + b

# Assign the function to a variable called my_function, and add the type.
my_function: MyCallable = func_add

my_function(a=1, b=2)   # This is OK.
my_function(a=1, b="x") # This is NOK.

Find elsewhere
🌐
Python.org
discuss.python.org › typing
Subtyping rules for `...` in callable types - Typing - Discussions on Python.org
April 2, 2024 - I’m planning to write a new chapter for the typing spec that focuses on subtyping rules for callable types. This is an area that has always been underspecified in the spec and the typing PEPs. One topic that I’d like to…
🌐
Python
peps.python.org › pep-0677
PEP 677 – Callable Type Syntax | peps.python.org
December 13, 2021 - This PEP introduces a concise and friendly syntax for callable types, supporting the same functionality as typing.Callable but with an arrow syntax inspired by the syntax for typed function signatures.
🌐
LinkedIn
linkedin.com › pulse › deep-dive-python-understanding-callable-edinson-requena-tz49e
Deep Dive into Python: Understanding callable and typing.Callable
January 4, 2024 - This type annotation is part of ... of runtime. ... typing.Callable is a class in Python's typing module that provides a way to specify types for callable functions or objects....
🌐
GitHub
github.com › python › typing › discussions › 1385
The structural type of typing.Callable · python/typing · Discussion #1385
Also, PEP 544 has "Callback protocols and Callable[...] types can be used interchangeably." One simple and direct way to explain what this means when substituting a Callable type where a callback protocol type is expected is to say what the signature of __call__ is for the Callable.
Author   python
🌐
Biopragmatics
cthoyt.com › 2025 › 04 › 23 › python-wish-unpacking-callable.html
I wish I could unpack Callables in Python type annotations | Biopragmatics
April 23, 2025 - from typing import Callable, Generic, Unpack, ParamSpec, TypeVar P = ParamSpec("P") T = TypeVar("T") class Box(Generic[P, T]): def __init__(self, func: Callable[P, T]) -> None: self.func = func def f(x: int) -> str: return str(x) # This works!
🌐
Medium
medium.com › data-science › python-type-hinting-introduction-to-the-callable-syntax-a978d2be43a1
Python Type Hinting: Introduction to The Callable Syntax | by Marcin Kozak | TDS Archive | Medium
May 16, 2024 - Prominent examples are of course functions, but in addition to functions, Python offers other callable objects, that is, classes and instances of classes that define the __call__() method.
🌐
GitHub
github.com › python › typing › issues › 264
Proposal: Generalize `Callable` to be able to specify argument names and kinds · Issue #264 · python/typing
August 19, 2016 - Right now you can specify callables with two patterns of arguments (shown here by example): Callable[..., int] takes in any arguments, any number. Callable[[int, str, bool], int] takes in a predetermined number of required positional arg...
Published   Aug 19, 2016
🌐
Verve AI
vervecopilot.com › interview-questions › what-no-one-tells-you-about-python-typing-callable-and-interview-performance
What No One Tells You About Python Typing Callable And Interview Performance
August 14, 2025 - At its core, python typing callable refers to any object that can be "called" like a function. This includes standard functions, methods, and even objects that implement the call method [3]. Understanding what qualifies as a callable is fundamental.
🌐
GitHub
github.com › python › typing › issues › 1301
Callable with variadic fixed arguments that doesn't mean *args · Issue #1301 · python/typing
October 14, 2022 - Concatenate is currently only valid when used as the first argument to a Callable. The last parameter to Concatenate must be a ParamSpec or ellipsis (...). ... C= TypeVar("C", bound=Command) class CommandHandler(Protocol): def __call__(self, __command: C, *__args: Any) -> None: ...
Published   Dec 02, 2022
🌐
CodeCut
codecut.ai › home › daily tips › code quality › python helpers › typing.callable: specify an input is of type function
typing.Callable: Specify an Input is of Type Function | CodeCut
October 4, 2024 - Khuyen Tran typing is a Python ... is of type function, use typing.Callable. Callable can be used static type checker such as mypy to check if the input is indeed a function....
🌐
Python.org
discuss.python.org › python help
Typing generic callback protocol with *args and **kwargs - Python Help - Discussions on Python.org
December 1, 2023 - I’m trying to do some possibly weird stuff with decorators and I’m struggling to get the typing right. I have created a decorator to which you provide some metadata, and when it’s called on a function it will put that f…
🌐
YouTube
youtube.com › watch
"Callable" Explained in Only 12 Minutes - YouTube
In today's video we're going to learn about the Callable type in Python, and why it's so important.▶ Become job-ready with Python:https://www.indently.io▶ Fo...
Published   December 9, 2024
🌐
GeeksforGeeks
geeksforgeeks.org › python › callable-in-python
callable() in Python - GeeksforGeeks
November 29, 2023 - In this example, we are using callable() function to check if an object is callable in Python. In the first case when an object is passed in the callable() method, it returns True. It is so because let is an object to the callable function Geek (which may not be in all cases).
🌐
Mypy
mypy.readthedocs.io › en › stable › kinds_of_types.html
Kinds of types - mypy 1.19.1 documentation
In earlier Python versions you can sometimes work around this limitation by using a named tuple as a base class (see section Named tuples). You can pass around function objects and bound methods in statically typed code. The type of a function that accepts arguments A1, …, An and returns Rt is Callable[[A1, ..., An], Rt]. Example: