Let's say I have the following:
def with_connection(f):
def decorated(*args, **kwargs):
f(get_connection(...), *args, **kwargs)
return decorated
@with_connection
def spam(connection):
# Do something
I want to test the spam
function without going through the hassle of setting up a connection (or whatever the decorator is doing).
Given spam
, how do I strip the decorator from it and get the underlying "undecorated" function?
There's been a bit of an update for this question. If you're using Python 3, you can use __wrapped__
property for decorators from stdlib.
Here's an example from Python Cookbook, 3rd edition, section 9.3 Unwrapping decorators
>>> @somedecorator
>>> def add(x, y):
... return x + y
...
>>> orig_add = add.__wrapped__
>>> orig_add(3, 4)
7
>>>
If you are trying to unwrap a function from custom decorator, the decorator function needs to use wraps
function from functools
See discussion in Python Cookbook, 3rd edition, section 9.2 Preserving function metadata when writing decorators
>>> from functools import wraps
>>> def somedecoarator(func):
... @wraps(func)
... def wrapper(*args, **kwargs):
... # decorator implementation here
... # ...
... return func(*args, kwargs)
...
... return wrapper