11import asyncio
22import functools
3+ from collections .abc import Callable , Generator
34from contextlib import contextmanager
4- from typing import Any , Callable , Dict , Generator
5+ from typing import Any , ParamSpec , TypeVar
56
67from opentelemetry import context , propagate , trace
78from opentelemetry .trace import SpanKind , Status , StatusCode
89
10+ P = ParamSpec ("P" )
11+ R = TypeVar ("R" )
12+
913
1014def get_tracer () -> trace .Tracer :
1115 """Get a tracer for the current module."""
@@ -16,7 +20,7 @@ def get_tracer() -> trace.Tracer:
1620def trace_span (
1721 name : str ,
1822 kind : SpanKind = SpanKind .INTERNAL ,
19- attributes : Dict [str , Any ] | None = None ,
23+ attributes : dict [str , Any ] | None = None ,
2024 set_status_on_exception : bool = True ,
2125 tracer : trace .Tracer | None = None
2226) -> Generator [trace .Span , None , None ]:
@@ -53,38 +57,40 @@ def trace_span(
5357def trace_method (
5458 name : str | None = None ,
5559 kind : SpanKind = SpanKind .INTERNAL ,
56- attributes : Dict [str , Any ] | None = None
57- ) -> Callable :
60+ attributes : dict [str , Any ] | None = None
61+ ) -> Callable [[ Callable [ P , R ]], Callable [ P , R ]] :
5862 """
5963 Decorator for tracing method calls.
60-
64+
6165 Args:
6266 name: Custom span name, defaults to module.method_name
6367 kind: Kind of span (INTERNAL, CLIENT, SERVER, etc.)
6468 attributes: Additional attributes to set on the span
65-
69+
6670 Returns:
6771 Decorated function with tracing
6872 """
69- def decorator (func : Callable ) -> Callable :
73+ def decorator (func : Callable [ P , R ] ) -> Callable [ P , R ] :
7074 span_name = name or f"{ func .__module__ } .{ func .__name__ } "
7175
7276 @functools .wraps (func )
73- async def async_wrapper (* args : Any , ** kwargs : Any ) -> Any :
77+ async def async_wrapper (* args : P . args , ** kwargs : P . kwargs ) -> R :
7478 with trace_span (span_name , kind = kind , attributes = attributes ):
75- return await func (* args , ** kwargs )
79+ return await func (* args , ** kwargs ) # type: ignore[misc, no-any-return]
7680
7781 @functools .wraps (func )
78- def sync_wrapper (* args : Any , ** kwargs : Any ) -> Any :
82+ def sync_wrapper (* args : P . args , ** kwargs : P . kwargs ) -> R :
7983 with trace_span (span_name , kind = kind , attributes = attributes ):
8084 return func (* args , ** kwargs )
8185
82- return async_wrapper if asyncio .iscoroutinefunction (func ) else sync_wrapper
86+ if asyncio .iscoroutinefunction (func ):
87+ return async_wrapper # type: ignore[return-value]
88+ return sync_wrapper
8389
8490 return decorator
8591
8692
87- def inject_trace_context (headers : Dict [str , str ]) -> Dict [str , str ]:
93+ def inject_trace_context (headers : dict [str , str ]) -> dict [str , str ]:
8894 """
8995 Inject current trace context into headers for propagation.
9096
@@ -99,7 +105,7 @@ def inject_trace_context(headers: Dict[str, str]) -> Dict[str, str]:
99105 return propagation_headers
100106
101107
102- def extract_trace_context (headers : Dict [str , str ]) -> context .Context :
108+ def extract_trace_context (headers : dict [str , str ]) -> context .Context :
103109 """
104110 Extract trace context from headers.
105111
@@ -126,7 +132,7 @@ def add_span_attributes(**attributes: Any) -> None:
126132 span .set_attribute (key , value )
127133
128134
129- def add_span_event (name : str , attributes : Dict [str , Any ] | None = None ) -> None :
135+ def add_span_event (name : str , attributes : dict [str , Any ] | None = None ) -> None :
130136 """
131137 Add an event to the current span.
132138
0 commit comments