datarekha
Python Medium Asked at StripeAsked at AirbnbAsked at Uber

Why is functools.wraps necessary when writing decorators?

The short answer

Without functools.wraps, the wrapper function replaces the original's __name__, __doc__, __module__, __qualname__, and __annotations__, breaking introspection, logging, and documentation tools. functools.wraps copies all of these attributes from the wrapped function to the wrapper and stores a reference in __wrapped__ for unwrapping.

How to think about it

What this question is really testing

Decorators are everywhere in Python frameworks. The interviewer wants to see that you don’t just know how to write a decorator — you know the production pitfall that trips up most people: without @functools.wraps, the wrapper silently stomps on the original function’s identity, breaking logging, routing frameworks, test fixtures, and documentation tools.

The problem: identity theft

A naive wrapper replaces the original function’s metadata:

def timer(func):
    def wrapper(*args, **kwargs):          # no @wraps
        return func(*args, **kwargs)
    return wrapper

@timer
def train(epochs):
    """Train the model for a given number of epochs."""
    ...

print(train.__name__)   # 'wrapper'  — wrong
print(train.__doc__)    # None       — documentation gone

This breaks Flask/FastAPI route naming, pytest fixture discovery, Sphinx docs, and any logging that uses func.__name__.

The fix: @functools.wraps

What functools.wraps copies

@functools.wraps(func) is a shorthand for calling functools.update_wrapper(wrapper, func), which copies:

AttributeWhy it matters
__name__Flask/FastAPI routes, logging, pytest fixtures
__doc__Sphinx, help(), IDE hover docs
__module__Correct module attribution
__qualname__Accurate stack traces
__annotations__Type checkers, FastAPI request parsing
__wrapped__Allows inspect.unwrap to peel back layers

The key insight

The __wrapped__ attribute is especially valuable: it lets inspect.unwrap traverse an entire decorator stack to reach the original function. This is how testing tools can access the undecorated function signature, and how debuggers show you meaningful stack traces instead of a tower of wrapper frames.

Learn it properly Decorators

Keep practising

All Python questions

Explore further

Skip to content