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 code below and the comments.
import typing # some function with singnature typing def fn1_as_arg_with_kwargs(a: int, b: float) -> float: return a + b # some function with singnature typing def fn2_as_arg_with_kwargs(a: int, b: float) -> float: return a * b # function that get callables as arg # this works with typing def function_executor( a: int, b: float, fn: typing.Callable[[int, float], float]): return fn(a, b) # But what if I want to name my kwargs # (something like below which does not work) # ... this will help me more complex scenarios # ... or am I expecting a lot from python3 ;) def function_executor( a: int, b: float, fn: typing.Callable[["a": int, "b": float], float]): return fn(a=a, b=b)
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With