Skip to content

Instantly share code, notes, and snippets.

@chtenb
Created December 14, 2015 07:33
Show Gist options
  • Save chtenb/1343468b3f6dd108b591 to your computer and use it in GitHub Desktop.
Save chtenb/1343468b3f6dd108b591 to your computer and use it in GitHub Desktop.
from inspect import signature
from functools import wraps
def dec(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
def dec2(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
def foo(a: int, b):
pass
print(signature(dec(foo)))
print(signature(dec2(foo)))
@chtenb
Copy link
Author

chtenb commented Dec 14, 2015

prints:

(*args, **kwargs)
(a:int, b)

@smarie
Copy link

smarie commented Mar 26, 2019

As per python 3.7: functools.wraps preserves signature but only in appearance because help and signature follow the __wrapped__ attribute ; it does not raise correct errors in case of misuse. See this answer, you can use makefun.wraps to get a fully signature-preserving behaviour like in decorator. A very interesting side effect is that all arguments are redirected into the kwargs variable when possible (when not varpositional), which is really helpful for the wrapper implementation.

from inspect import signature
from functools import wraps

def dec2(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("success!")
        return func(*args, **kwargs)
    return wrapper

from makefun import wraps

def dec3(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("success!")
        return func(*args, **kwargs)
    return wrapper

def foo(a: int, b):
    pass

f2 = dec2(foo)
print(signature(f2))
f2(1)  # raises TypeError but... prints "success!"

f3 = dec3(foo)
print(signature(f3))
f3(1)  # raises TypeError and *does not* print success

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment