Python glossary entry

ParamSpec

typing.ParamSpec
Namespace
Standard library
Module
typing
Available since
Python 3.10

Captures a callable parameter list so decorators and adapters can preserve the original call signature.

Definition

A ParamSpec represents a callable's positional and keyword parameters as one relationship. It is designed for higher-order functions that forward calls without changing their accepted arguments.

Preserve a decorator signature

Pyodide / WebAssembly
from collections.abc import Callable
from functools import wraps
from typing import ParamSpec, TypeVar

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

def traced(function: Callable[P, R]) -> Callable[P, R]:
    @wraps(function)
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
        print("[event] forwarding call to:", function.__name__)
        return function(*args, **kwargs)
    return wrapper

@traced
def repeat(text: str, count: int = 2) -> str:
    return text * count

print("[result] decorated call:", repeat("py", count=3))

P.args and P.kwargs annotate the forwarding implementation. The checker exposes the original repeat parameters to callers instead of reducing the decorator result to an uninformative Callable[..., str].

Use it when

Use ParamSpec when arguments pass through a decorator, callback adapter, or dependency wrapper. If the wrapper intentionally changes the signature, Concatenate or an explicit callback protocol may communicate the transformation more clearly.

Primary sourceOfficial Python documentation ↗