Hi, Instead of using the type parameter approach, have you considered using a type operator approach? I'm sure this approach has problems, but thought I'd bring it up anyway. I mean is something like this: ``` from typing import Awaitable, Callable, TypeVar, Parameters TReturn = TypeVar("TReturn") def add_logging( f: Callable[..., TReturn] ) -> Callable[Parameters[f], Awaitable[TReturn]]: async def inner(*args: Parameters[f].args, **kwargs: Parameters[f].kwargs) -> TReturn: await log_to_database() return f(*args, **kwargs) return inner ``` or even, extending Callable a bit to eliminate the TypeVar as well, ``` from typing import Awaitable, Callable, Parameters, ReturnType def add_logging( f: Callable[..., ...] ) -> Callable[Parameters[f], Awaitable[ReturnType[f]]]: async def inner(*args: Parameters[f].args, **kwargs: Parameters[f].kwargs) -> ReturnType[f]: await log_to_database() return f(*args, **kwargs) return inner ``` This is the approach used by TypeScript, at least. They are defined like this[0]: ``` type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never; type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any; ``` [0] https://github.com/microsoft/TypeScript/blob/v3.7.4/src/lib/es5.d.ts#L1473-L... In Python, `Parameters` would return something like a `ParameterSpecification` instance, with the same restrictions described in the PEP. In TypeScript, these type operators appear to use some complex machinery, namely conditional types and the `infer` declaration, which no Python type checker supports AFAIK. But maybe they can be implemented directly. They might also be useful for other cases. For example, I often have a function with a complex set of arguments, and another functions which wraps it and just forwards the arguments. In these cases, I would have loved to be able to write this: ``` def function( with: int, lots: bool, of: string, complex: bytes, *, arguments: float, ): None:... def function_wrapper( *args: Parameters[function].args, **kwargs: Parameters[function].kwargs, ) -> ReturnType[function]: ... ``` Ran