Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to type hint a Callable of a function with default arguments?

I'm trying to Type Hint the function bar, but I got the Too few arguments error when I run mypy.

from typing import Callable, Optional

def foo(arg: int = 123) -> float:
    return arg+0.1

def bar(foo: Callable[[int], float], arg: Optional[int] = None) -> float:
    if arg:
        return foo(arg)
    return foo()

print(bar(foo))
print(bar(foo, 90))

I have also tried:

  • Callable[[], float] (got Too many arguments error)
  • Callable[[Optional[int]], float] (got another error)

So, how should I do the Type Hinting of the bar function?

like image 859
DonLarry Avatar asked Jul 14 '21 23:07

DonLarry


People also ask

What is callable in Python typing?

Short version, Callable is a type hint that indicates a function or other object which can be called. Consider a simple example below. The bar parameter is a callable object that takes two ints as parameters and returns an int.

How do you use type hints in Python?

Here's how you can add type hints to our function: Add a colon and a data type after each function parameter. Add an arrow ( -> ) and a data type after the function to specify the return data type.

What is default arguments in function give example?

Default arguments are overwritten when the calling function provides values for them. For example, calling the function sum(10, 15, 25, 30) overwrites the values of z and w to 25 and 30 respectively.

What is the syntax to indicate optional arguments in a callable?

There is no syntax to indicate optional or keyword arguments; such function types are rarely used as callback types. Callable[..., ReturnType] (literal ellipsis) can be used to type hint a callable taking any number of arguments and returning ReturnType. A plain Callable is equivalent to Callable[..., Any], and in turn to collections.abc.Callable.

What is a callable function in C++?

Callable¶ Callable type; Callable[[int], str] is a function of (int) -> str. The subscription syntax must always be used with exactly two values: the argument list and the return type. The argument list must be a list of types or an ellipsis; the return type must be a single type.

What is a callable in JavaScript?

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. That is, the parameters are sub-scripted in the outer subscription with the return type as the second element in the outer subscription.

How to specify the default value of the input parameters?

Here, we use colon: to specify the type of input arguments, and arrow -> to specify the type of the return variable of a function. We can use equal = to specify the default value of the input parameters.


1 Answers

Define this:

class Foo(Protocol):
    def __call__(self, x: int = ..., /) -> float:
        ...

then type hint foo as Foo instead of Callable[[int], float]. Callback protocols allow you to:

define flexible callback types that are hard (or even impossible) to express using the Callable[...] syntax

and optional arguments are one of those impossible things to express with a normal Callable. The / at the end of __call__'s signature makes x a positional-only parameter, which allows any passed function to bar to have a parameter name that is not x (your specific example of foo calls it arg instead). If you removed /, then not only would the types have to line up as expected, but the names would have to line up too because you would be implying that Foo could be called with a keyword argument. Because bar doesn't call foo with keyword arguments, opting into that behavior by omitting the / imposes inflexibility on the user of bar (and would make your current example still fail because "arg" != "x").

like image 167
Mario Ishac Avatar answered Nov 14 '22 23:11

Mario Ishac