Search code examples
pythonpython-decorators

python wrapping function with signature


How can I create decorators that wrap a function with a signature, from an inspect.Signature object itself instead of a function.

Consider the following:

>>> import functools
>>> import inspect
>>>
>>> def foo(a, b: int, c=0, d:float=1.0) -> float:
...     return a + (c * b) ** d
>>> @functools.wraps(foo)
... def bar(*args, **kwargs):
...     return sum(kwargs.values())
>>> print(inspect.signature(foo))
(a, b: int, c=0, d: float = 1.0) -> float
>>> print(inspect.signature(bar))
(a, b: int, c=0, d: float = 1.0) -> float

I'd like to have function wrap_with_signature whose input is an inspect.Signature object and returns a decorator such that:

foo_signature = inspect.signature(foo)
@wrap_with_signature(foo_signature)  # parametrize with signature instead of function
def bar(*args, **kwargs):
    return sum(kwargs.values())

Why? Because it would allow me to edit the Signature object to get exactly the signature I want.


Solution

  • All you need to do is assign the signature to the function's __signature__ attribute:

    def wrap_with_signature(signature):
        def wrapper(func):
            func.__signature__ = signature
            return func
        return wrapper