Skip to main content
🔒 Preview mode. The first 15 Foundations lessons are free; this one is Pro. Start a 7-day trial to unlock the editor, AI hints and the rest of the curriculum. Card required, cancel any time in Dashboard.Start 7-day trial →
← CoursesSenior Deep-DivesModule 11 · Decorator patterns at scaletyping.ParamSpec — decorators that preserve the wrapped signaturepredict156 / 161
+150 XP
Task
📝 **Task:** Predict the 7-line output. A `trace` decorator wraps two functions: `add(a, b)` and `greet(name, *, prefix='Hi')`. At runtime the wrapper prints 'calling ...' on entry and 'returned ...' on exit. The final line uses `inspect.signature(add)` to verify that `@wraps` preserved the ORIGINAL signature — proving that the typing-side `ParamSpec` declaration mirrors what runtime introspection already sees. 📋 Implement the function above. Tests run automatically. 💡 **Hint:** Re-read the theory if you get stuck.
Predict the output

Read the code carefully

from typing import Callable, ParamSpec, TypeVar
from functools import wraps
import inspect


P = ParamSpec("P")
R = TypeVar("R")


def trace(fn: Callable[P, R]) -> Callable[P, R]:
    @wraps(fn)
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
        print(f"calling {fn.__name__}")
        result = fn(*args, **kwargs)
        print(f"returned {result!r}")
        return result
    return wrapper


@trace
def add(a: int, b: int) -> int:
    return a + b


@trace
def greet(name: str, *, prefix: str = "Hi") -> str:
    return f"{prefix}, {name}"


result = add(2, 3)
print(f"=> {result}")

result = greet("Ada", prefix="Hello")
print(f"=> {result}")

sig = inspect.signature(add)
print(f"add sig: {sig}")

What will the program print? Write here:

💬 Discussion

Be the first to ask a question or share a tip.
Sign in to join the discussion. Reading is free.
Loading discussion…