Lesson guide
What this Python exercise practices
Preserve Function Metadata with functools.wraps is a beginner practice lesson that focuses on functions, parameters, return values. It is designed to be solved in about 8 minutes with examples, starter code, and test feedback.
Prerequisites
- Python variables
- Function parameters
- Return values
Difficulty and time
- Level
- Beginner
- Estimated time
- 8 minutes
Related public exercises
Summary
Learn to write decorators that preserve a function's metadata using functools.wraps.
Problem statement
When you write decorators in Python, a common pitfall is that the wrapper function hides metadata from the original function (like __name__ and __doc__). The functools.wraps helper copies metadata from the original function to the wrapper so tools like documentation generators, debugging, and introspection still work. Your task: write a decorator called preserve_metadata that: - Uses functools.wraps to ensure the wrapper preserves the original function's __name__, __doc__, and __wrapped__ (i.e., the original function must still be accessible via __wrapped__). - Calls the original function with the same arguments and returns its result. - Attaches an attribute named metadata to the wrapper function. This attribute should be a dict containing the key 'decorated' with the boolean value True. Provide a usable decorator so functions decorated with @preserve_metadata behave identically to the original function, except they have the additional metadata attribute.
Task
Implement a decorator that wraps another function while preserving its __name__, __doc__, and __wrapped__ metadata, and attaches a small metadata attribute to the wrapper.
Examples
Basic usage
Input
@preserve_metadata def greet(name): "Return greeting." return f"Hi, {name}" greet.__name__, greet.__doc__, greet("Joe")
Output
('greet', 'Return greeting.', 'Hi, Joe')
Explanation
The decorator preserves the original name and docstring and returns the original function's output. The wrapper also has a metadata attribute.
Input format
A decorated function is defined in the provided code. Tests will call the decorated function or inspect its attributes.
Output format
Expressions should evaluate to values (strings, booleans, etc.). The test harness compares the stringified return value to the expected output.
Constraints
Use functools.wraps to preserve metadata. Attach the metadata attribute as a dict: {'decorated': True}. Do not modify the original function's behavior.
Samples
Sample input 0
@preserve_metadata def greet(name): "Return greeting." return f"Hi, {name}" greet("Sam")
Sample output 0
Hi, Sam
Explanation 0
Calling the decorated function returns the same result as the original function.
AI assistant
Ask me anything!
Need help? I can explain the core idea behind this problem, review your current code, and give targeted hints. Use “Teach Theory” for the concept, “Get AI hint” for a quick scaffold nudge, or ask a specific question below.
Chat history is temporary and will not be saved.
Free preview includes 1 Teach Theory response and 1 AI hint on each of the first 3 lessons in this module.