Unwrapping functools.wraps: How to Remove Decorators from a Python Function
,Sometimes, you need to call a Python function without its decorators. I encountered this need while implementing custom exception handling for the ACS (Assertion Consumer Service) view in django-saml2-auth
. This view was decorated with an exception_handler
that rendered responses, which interfered with my custom handling. Fortunately, functools.wraps
comes to the rescue, storing the original function in a __wrapped__
attribute.
Here’s an example to demonstrate:
from functools import wraps
def heading(f):
@wraps(f)
def wrapper(*args, **kwds):
to_decorate = f()
return f"<h1>{to_decorate}</h1>"
return wrapper
@heading
def decorated_hello():
return "Hello World!"
# Using the decorated function
print(decorated_hello())
# Output: '<h1>Hello World!</h1>'
# Accessing the original, undecorated function
print(decorated_hello.__wrapped__())
# Output: 'Hello World!'