I have a decorator that "wraps" a function in a new one that has one extra positional argument in the beginning:
import functools
def my_decorator(f):
@functools.wraps(f)
def wrapped(message: str, *args, **kwargs):
print('Decorated:', message)
return f(*args, **kwargs)
return wrapped
Here is an example on how my decorator is used:
@my_decorator
def foo(a: int, b: str) -> None:
print('Hello world', [a, b])
foo('test', 2, '3')
# Decorated: test
# Hello world [2, '3']
So far so good. However, I'd like my decorator to create a new function with the correct signature. But since I used @functools.wraps, I am getting the same signature as the original function:
import inspect
print('Signature:', inspect.signature(foo))
# Signature: (a: int, b: str) -> None
But I want to get (message: str, a: int, b: str) -> None instead. How to do this?
I need the correct signature to get correct type checks and also because I am using a framework that relies on function signatures for its behavior.