typing.Concatenate
In addition to typing.ParamSpec, PEP 612 introduced typing.Concatenate that allows describing decorators that accept fewer or more arguments that the wrapped function:
from typing import Callable, Concatenate, ParamSpec, TypeVar
P = ParamSpec('P')
R = TypeVar('R')
class User: ...
class Request: ...
class Response: ...
def with_user(
f: Callable[Concatenate[User, P], R],
) -> Callable[P, R]:
def inner(*args: P.args, **kwargs: P.kwargs) -> R:
user = User()
return f(user, *args, **kwargs)
return inner
@with_user
def handle_request(
user: User,
request: Request,
) -> Response:
...
request = Request()
response = handle_request(request)