Python etc / 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

def handle_request(
  user: User,
  request: Request,
) -> Response:

request = Request()
response = handle_request(request)