pythongenericsmypytypingcallable

how to type a custom callable type in Python


I have a class called Foo:

class Foo:
    def __init__(self, callable):
        self.my_attr = "hi"
        self.callable = callable

    def __call__(self, *args, **kwargs):
         # call the wrapped in function
         return self.callable(*args, **kwargs)

I would like to type its instances (the __call__ method and the my_attr attribute).

Thank you for your help,


Solution

  • I used Generics to solve the problem:

    from typing import ParamSpec, TypeVar, Generic, Callable
    P = ParamSpec("P")
    RV = TypeVar("RV")
    
    class Foo(Generic[P, RV]):
        def __init__(self, callable: Callable[P, RV]):
            self.my_attr = "hi"
            self.callable = callable
    
        def __call__(self, *args: P.args, **kwargs: P.kwargs) -> RV:
             # call the wrapped in function
             return self.callable(*args, **kwargs)
    
    def my_decorator(func: Callable[P, RV]) ->  Foo[P, RV]:
        return Foo(func)
    

    Now these typing is valid:

    @my_decorator
    def func(a: int, b: str) -> str:
        raise NotImplementedError
    
    s: str = func(1, "2") # valid typing for object cal
    ss: str = func.my_attr # valid typing for attribute access