Typehinting function with two possible call signatures

Question:

I have a class which takes a function as a parameter, and I want that function to either have signature int -> int or list[int] -> int. I’ve type hinted it using a Union as follows.

from typing import Callable, Union

class Foo:
    def __init__(self, func: Callable[[Union[int, list[int]]], int]) -> None:
        self.func = func

def identity(num: int) -> int:
    return num

Foo(identity)

Unfortunately mypy is not happy with the final line (Foo(identity)), saying

 error: Argument 1 to "Foo" has incompatible type "Callable[[int], int]"; expected "Callable[[Union[int, List[int]]], int]"

I understand now that the identity function signature does not match exactly the typehint for func, but I’m stuck as to how to move forward here. What is the proper way to handle this scenario?

Asked By: natty

||

Answers:

You should annotate the parameter with a Union of the two different Callable signatures

class Foo:
    def __init__(self, func: Union[Callable[[int], int], Callable[[list[int]], int]]) -> None:
        self.func = func
Answered By: Iain Shelvington
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.