decorator: Strengthen decorator types using ParamSpec.

Signed-off-by: Zixuan James Li <359101898@qq.com>
This commit is contained in:
Zixuan James Li 2022-04-13 10:43:23 -04:00 committed by Tim Abbott
parent b1fbba0577
commit e632a4ced2
1 changed files with 9 additions and 5 deletions

View File

@ -24,6 +24,7 @@ from django.utils.translation import gettext as _
from django.views.decorators.csrf import csrf_exempt
from django_otp import user_has_device
from two_factor.utils import default_device
from typing_extensions import ParamSpec
from zerver.lib.cache import cache_with_key
from zerver.lib.exceptions import (
@ -67,7 +68,8 @@ webhook_logger = logging.getLogger("zulip.zerver.webhooks")
webhook_unsupported_events_logger = logging.getLogger("zulip.zerver.webhooks.unsupported")
webhook_anomalous_payloads_logger = logging.getLogger("zulip.zerver.webhooks.anomalous")
FuncT = TypeVar("FuncT", bound=Callable[..., object])
ParamT = ParamSpec("ParamT")
ReturnT = TypeVar("ReturnT")
def update_user_activity(
@ -847,20 +849,22 @@ def to_utc_datetime(var_name: str, timestamp: str) -> datetime.datetime:
return timestamp_to_datetime(float(timestamp))
def statsd_increment(counter: str, val: int = 1) -> Callable[[FuncT], FuncT]:
def statsd_increment(
counter: str, val: int = 1
) -> Callable[[Callable[ParamT, ReturnT]], Callable[ParamT, ReturnT]]:
"""Increments a statsd counter on completion of the
decorated function.
Pass the name of the counter to this decorator-returning function."""
def wrapper(func: FuncT) -> FuncT:
def wrapper(func: Callable[ParamT, ReturnT]) -> Callable[ParamT, ReturnT]:
@wraps(func)
def wrapped_func(*args: object, **kwargs: object) -> object:
def wrapped_func(*args: ParamT.args, **kwargs: ParamT.kwargs) -> ReturnT:
ret = func(*args, **kwargs)
statsd.incr(counter, val)
return ret
return cast(FuncT, wrapped_func) # https://github.com/python/mypy/issues/1927
return wrapped_func
return wrapper