Considere the following code:
from typing import Callable, Any
TFunc = Callable[..., Any]
def get_authenticated_user(): return \"John\"
def require_auth()
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
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.