Python 3 type hinting for decorator

You can’t use Callable to say anything about additional arguments; they are not generic. Your only option is to say that your decorator takes a Callable and that a different Callable is returned.

In your case you can nail down the return type with a typevar:

RT = TypeVar('RT')  # return type

def inject_user() -> Callable[[Callable[..., RT]], Callable[..., RT]]:
    def decorator(func: Callable[..., RT]) -> Callable[..., RT]:
        def wrapper(*args, **kwargs) -> RT:
            # ...

Even then the resulting decorated foo() function has a typing signature of def (*Any, **Any) -> builtins.bool* when you use reveal_type().

Various proposals are currently being discussed to make Callable more flexible but those have not yet come to fruition. See

  • Allow variadic generics
  • Proposal: Generalize Callable to be able to specify argument names and kinds
  • TypeVar to represent a Callable’s arguments
  • Support function decorators excellently

for some examples. The last one in that list is an umbrella ticket that includes your specific usecase, the decorator that alters the callable signature:

Mess with the return type or with arguments

For an arbitrary function you can’t do this at all yet — there isn’t even a syntax. Here’s me making up some syntax for it.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)