Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python typing signature (typing.Callable) for function with kwargs

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) 
like image 319
Praveen Kulkarni Avatar asked Sep 07 '19 21:09

Praveen Kulkarni


1 Answers

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.)

like image 178
Michael0x2a Avatar answered Sep 23 '22 23:09

Michael0x2a