|
2 | 2 | import functools
|
3 | 3 | import inspect
|
4 | 4 | import logging
|
| 5 | +from typing import Callable, TypeVar |
| 6 | +try: |
| 7 | + from typing import ParamSpec # Python 3.10+ |
| 8 | +except ImportError: |
| 9 | + from typing_extensions import ParamSpec |
| 10 | + |
| 11 | +P = ParamSpec("P") |
| 12 | +R = TypeVar("R") |
5 | 13 |
|
6 | 14 | from aiocache.base import SENTINEL
|
7 | 15 | from aiocache.lock import RedLock
|
@@ -43,9 +51,10 @@ def __init__(
|
43 | 51 | self.noself = noself
|
44 | 52 | self.cache = cache
|
45 | 53 |
|
46 |
| - def __call__(self, f): |
| 54 | + # Use ParamSpec and TypeVar to preserve the decorated function's type signature for static type checkers. |
| 55 | + def __call__(self, f: Callable[P, R]) -> Callable[P, R]: |
47 | 56 | @functools.wraps(f)
|
48 |
| - async def wrapper(*args, **kwargs): |
| 57 | + async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: |
49 | 58 | return await self.decorator(f, *args, **kwargs)
|
50 | 59 |
|
51 | 60 | wrapper.cache = self.cache
|
@@ -228,9 +237,10 @@ def __init__(
|
228 | 237 | self.skip_cache_func = skip_cache_func
|
229 | 238 | self.ttl = ttl
|
230 | 239 |
|
231 |
| - def __call__(self, f): |
| 240 | + # Use ParamSpec and TypeVar to preserve the decorated function's type signature for static type checkers. |
| 241 | + def __call__(self, f: Callable[P, R]) -> Callable[P, R]: |
232 | 242 | @functools.wraps(f)
|
233 |
| - async def wrapper(*args, **kwargs): |
| 243 | + async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: |
234 | 244 | return await self.decorator(f, *args, **kwargs)
|
235 | 245 |
|
236 | 246 | wrapper.cache = self.cache
|
|
0 commit comments