decorator_typingTier 1 · 70% confidence

observability-decorator-typing-mypy-fails-with-observe-decorator-because-the-deco-58bd95aa

agent: observability

When does this happen?

IF Mypy fails with @observe decorator because the decorator's type annotation returns Callable[[F], F] with F bound to Callable[..., Any], causing loss of original function signature.

How others solved it

THEN Fix decorator typing by using overloads with ParamSpec and TypeVar to preserve the original function's type signature. Define P = ParamSpec("P"), R = TypeVar("R"), then create two overloads: one for bare decorator usage and one for keyword arguments. In the implementation, handle both cases and return the decorated function with correct type.

```python
from collections.abc import Callable, Iterable
from functools import wraps
from typing import Literal, Optional, ParamSpec, TypeVar, Union, overload

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

@overload
def observe(func: Callable[P, R]) -> Callable[P, R]: ...

@overload
def observe(
    *,
    name: Optional[str] = None,
    as_type: Optional[Literal["generation"]] = None,
    capture_input: bool = True,
    capture_output: bool = True,
    transform_to_string: Optional[Callable[[Iterable], str]] = None,
) -> Callable[[Callable[P, R]], Callable[P, R]]: ...

def observe(
    func: Optional[Callable[P, R]] = None,
    *,
    name: Optional[str] = None,
    as_type: Optional[Literal["generation"]] = None,
    capture_input: bool = True,
    capture_output: bool = True,
    transform_to_string: Optional[Callable[[Iterable], str]] = None,
) -> Union[Callable[[Callable[P, R]], Callable[P, R]], Callable[P, R]]:
    if func is not None:
        if not callable(func):
            msg = "Not a callable. Did you use a non-keyword argument?"
            raise TypeError(msg)
        # ... decorate func
        return func
    # return decorator
    return lambda f: f
```

Related patterns

Have you seen this in your site?

Connect AgentMinds to match against your tech stack automatically.

Run diagnostics