Skip to content

Commit 53b6afb

Browse files
committed
Use ParamSpec to properly annotate decorators
Signed-off-by: Iurii Pliner <[email protected]>
1 parent d9aae14 commit 53b6afb

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

prometheus_client/context_managers.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import functools
2+
import sys
23
from timeit import default_timer
34
from types import TracebackType
45
from typing import (
5-
Any, Callable, Literal, Optional, Tuple, Type, TYPE_CHECKING, TypeVar,
6+
Callable, Literal, Optional, Tuple, Type, TYPE_CHECKING, TypeVar,
67
Union,
78
)
9+
if sys.version_info >= (3, 10):
10+
from typing import ParamSpec
11+
else:
12+
from typing_extensions import ParamSpec
813

914
if TYPE_CHECKING:
1015
from . import Counter
11-
F = TypeVar("F", bound=Callable[..., Any])
16+
17+
TParam = ParamSpec("TParam")
18+
TResult = TypeVar("TResult")
1219

1320

1421
class ExceptionCounter:
@@ -24,9 +31,9 @@ def __exit__(self, typ: Optional[Type[BaseException]], value: Optional[BaseExcep
2431
self._counter.inc()
2532
return False
2633

27-
def __call__(self, f: "F") -> "F":
34+
def __call__(self, f: Callable[TParam, TResult]) -> Callable[TParam, TResult]:
2835
@functools.wraps(f)
29-
def wrapped(*args: Any, **kwargs: Any) -> Any:
36+
def wrapped(*args: TParam.args, **kwargs: TParam.kwargs) -> TResult:
3037
with self:
3138
return f(*args, **kwargs)
3239
return wrapped # type: ignore
@@ -42,9 +49,9 @@ def __enter__(self):
4249
def __exit__(self, typ, value, traceback):
4350
self._gauge.dec()
4451

45-
def __call__(self, f: "F") -> "F":
52+
def __call__(self, f: Callable[TParam, TResult]) -> Callable[TParam, TResult]:
4653
@functools.wraps(f)
47-
def wrapped(*args: Any, **kwargs: Any) -> Any:
54+
def wrapped(*args: TParam.args, **kwargs: TParam.kwargs) -> TResult:
4855
with self:
4956
return f(*args, **kwargs)
5057
return wrapped # type: ignore
@@ -71,9 +78,9 @@ def __exit__(self, typ, value, traceback):
7178
def labels(self, *args, **kw):
7279
self._metric = self._metric.labels(*args, **kw)
7380

74-
def __call__(self, f: "F") -> "F":
81+
def __call__(self, f: Callable[TParam, TResult]) -> Callable[TParam, TResult]:
7582
@functools.wraps(f)
76-
def wrapped(*args: Any, **kwargs: Any) -> Any:
83+
def wrapped(*args: TParam.args, **kwargs: TParam.kwargs) -> TResult:
7784
# Obtaining new instance of timer every time
7885
# ensures thread safety and reentrancy.
7986
with self._new_timer():

prometheus_client/metrics.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
)
2020

2121
T = TypeVar('T', bound='MetricWrapperBase')
22-
F = TypeVar("F", bound=Callable[..., Any])
2322

2423

2524
def _build_full_name(metric_type, name, namespace, subsystem, unit):

setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
extras_require={
3030
'twisted': ['twisted'],
3131
},
32+
install_requires=[
33+
'typing-extensions>=4; python_version<"3.10"',
34+
],
3235
test_suite="tests",
3336
python_requires=">=3.9",
3437
classifiers=[

0 commit comments

Comments
 (0)