Skip to content

Commit 70795f7

Browse files
committed
Adds typing to the decorators
1 parent 63fb637 commit 70795f7

File tree

4 files changed

+195
-4
lines changed

4 files changed

+195
-4
lines changed

aiocache/decorators.py

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class cached:
6060
def __init__(
6161
self,
6262
ttl=SENTINEL,
63+
*,
6364
namespace="",
6465
key_builder=None,
6566
skip_cache_func=lambda x: False,
@@ -303,6 +304,7 @@ class multi_cached:
303304
def __init__(
304305
self,
305306
keys_from_attr,
307+
*,
306308
namespace="",
307309
key_builder=None,
308310
skip_cache_func=lambda k, v: False,

aiocache/decorators.pyi

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
from typing import (
2+
Any,
3+
Callable,
4+
Concatenate,
5+
Mapping,
6+
ParamSpec,
7+
Protocol,
8+
Sequence,
9+
Type,
10+
TypeVar,
11+
overload,
12+
)
13+
14+
from aiocache import BaseCache, Cache
15+
from aiocache.plugins import BasePlugin
16+
from aiocache.serializers import BaseSerializer
17+
18+
Params = ParamSpec("Params")
19+
ReturnType = TypeVar("ReturnType")
20+
DecoratorKWArgs = TypeVar("DecoratorKWArgs")
21+
SerializerType = TypeVar("SerializerType", bound=BaseSerializer)
22+
CacheType = TypeVar("CacheType", bound=BaseCache)
23+
MCReturnType = TypeVar("MCReturnType", bound=Mapping)
24+
MCKey = TypeVar("MCKey")
25+
MCVal = TypeVar("MCVal")
26+
27+
class CachedDecorator(Protocol[Params, ReturnType]):
28+
def __call__(
29+
self,
30+
*args: Params.args,
31+
cache_read: bool = True,
32+
cache_write: bool = True,
33+
aiocache_wait_for_write: bool = True,
34+
**kwargs: Params.kwargs,
35+
) -> ReturnType: ...
36+
37+
class CachedDecorated(CachedDecorator[CacheType, Params, ReturnType]):
38+
cache: CacheType
39+
40+
class cached:
41+
ttl: int | None
42+
key_builder: Callable[Params, str] | None
43+
skip_cache_func: Callable[[ReturnType], bool] | None
44+
noself: bool
45+
alias: str | None
46+
cache: None
47+
48+
decorator: CachedDecorator[Params, ReturnType]
49+
50+
_cache: CacheType
51+
_serializer: SerializerType
52+
_namespace: str | None
53+
_plugins: Sequence[BasePlugin] | None
54+
_kwargs: dict[str, DecoratorKWArgs]
55+
56+
@overload
57+
def __init__(
58+
self,
59+
ttl: int | None = None,
60+
*,
61+
key_builder: Callable[Params, str] | None = None,
62+
skip_cache_func: Callable[[ReturnType], bool] | None = None,
63+
cache: Type[CacheType] = Cache.MEMORY,
64+
noself: bool = False,
65+
alias: str,
66+
**kwargs: DecoratorKWArgs,
67+
): ...
68+
@overload
69+
def __init__(
70+
self,
71+
ttl: int | None = None,
72+
*,
73+
key_builder: Callable[Params, str] | None = None,
74+
skip_cache_func: Callable[[ReturnType], bool] | None = None,
75+
cache: Type[CacheType] = Cache.MEMORY,
76+
noself: bool = False,
77+
namespace: str | None = None,
78+
serializer: SerializerType | None = None,
79+
plugins: Sequence[BasePlugin] | None = None,
80+
alias: None = None,
81+
**kwargs: DecoratorKWArgs,
82+
): ...
83+
def __call__(
84+
self, fn: Callable[Params, ReturnType]
85+
) -> CachedDecorated[CacheType, Params, ReturnType]: ...
86+
def get_cache_key(self, *args: Params.args, **kwargs: Params.kwargs) -> str: ...
87+
async def get_from_cache(self, key: str) -> ReturnType | None: ...
88+
async def set_in_cache(self, key: str, value: ReturnType) -> None: ...
89+
90+
class cached_stampede(cached):
91+
lease: int
92+
93+
@overload
94+
def __init__(
95+
self,
96+
lease: int = 2,
97+
ttl: int | None = None,
98+
*,
99+
key_builder: Callable[Params, str] | None = None,
100+
skip_cache_func: Callable[[ReturnType], bool] | None = None,
101+
cache: Type[CacheType] = Cache.MEMORY,
102+
noself: bool = False,
103+
alias: str,
104+
**kwargs: DecoratorKWArgs,
105+
) -> CachedDecorated[CacheType, Params, ReturnType]: ...
106+
@overload
107+
def __init__(
108+
self,
109+
lease: int = 2,
110+
ttl: int | None = None,
111+
*,
112+
key_builder: Callable[Params, str] | None = None,
113+
skip_cache_func: Callable[[ReturnType], bool] | None = None,
114+
cache: Type[CacheType] = Cache.MEMORY,
115+
noself: bool = False,
116+
namespace: str | None = None,
117+
serializer: SerializerType | None = None,
118+
plugins: Sequence[BasePlugin] | None = None,
119+
alias: None = None,
120+
**kwargs: DecoratorKWArgs,
121+
) -> CachedDecorated[CacheType, Params, ReturnType]: ...
122+
123+
class multi_cached:
124+
keys_from_attr: str
125+
key_builder: Callable[Concatenate[MCKey, Callable[Params, MCReturnType], Params], str] | None
126+
skip_cache_func: Callable[[MCKey, MCVal], bool] | None
127+
ttl: int | None
128+
alias: str | None
129+
cache: None
130+
131+
decorator: CachedDecorator[Params, MCReturnType]
132+
133+
_cache: CacheType
134+
_serializer: SerializerType
135+
_namespace: str | None
136+
_plugins: Sequence[BasePlugin] | None
137+
_kwargs: dict[str, DecoratorKWArgs]
138+
139+
@overload
140+
def __init__(
141+
self,
142+
keys_from_attr: str,
143+
*,
144+
key_builder: (
145+
Callable[Concatenate[MCKey, Callable[Params, ReturnType], Params], str] | None
146+
) = None,
147+
skip_cache_func: Callable[[MCKey, MCVal], bool] | None = None,
148+
ttl: int | None = None,
149+
cache: Type[CacheType] = Cache.MEMORY,
150+
alias: str,
151+
**kwargs: DecoratorKWArgs,
152+
): ...
153+
@overload
154+
def __init__(
155+
self,
156+
keys_from_attr: str,
157+
*,
158+
namespace: str | None = None,
159+
key_builder: (
160+
Callable[Concatenate[MCKey, Callable[Params, ReturnType], Params], str] | None
161+
) = None,
162+
skip_cache_func: Callable[[MCKey, MCVal], bool] | None = None,
163+
ttl: int | None = None,
164+
cache: Type[CacheType] = Cache.MEMORY,
165+
serializer: SerializerType | None = None,
166+
plugins: Sequence[BasePlugin] | None = None,
167+
alias: None = None,
168+
**kwargs: DecoratorKWArgs,
169+
): ...
170+
def __call__(
171+
self, fn: Callable[Params, ReturnType]
172+
) -> CachedDecorated[CacheType, Params, MCReturnType]: ...
173+
def get_cache_keys(
174+
self, f: Callable[Params, ReturnType], *args: Params.args, **kwargs: Params.kwargs
175+
) -> str: ...
176+
async def get_from_cache(self, *keys: MCKey) -> list[MCVal | None]: ...
177+
async def set_in_cache(
178+
self,
179+
result: MCReturnType[MCKey, MCVal],
180+
fn: Callable[Params, ReturnType],
181+
fn_args: Params.args,
182+
fn_kwargs: Params.kwargs,
183+
) -> None: ...
184+
185+
def __getattr__(name: str) -> Any: ...

setup.cfg

+3
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ source = aiocache
2525
[coverage:report]
2626
show_missing = true
2727
skip_covered = true
28+
29+
[options.package_data]
30+
{name} = py.typed, *.pyi

tests/ut/test_decorators.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def test_init(self):
6060
def test_fails_at_instantiation(self):
6161
with pytest.raises(TypeError):
6262

63-
@cached(wrong_param=1)
63+
@cached(wrong_param=1) # type: ignore[misc]
6464
async def fn() -> None:
6565
"""Dummy function."""
6666

@@ -373,7 +373,7 @@ def f():
373373
def test_fails_at_instantiation(self):
374374
with pytest.raises(TypeError):
375375

376-
@multi_cached(wrong_param=1)
376+
@multi_cached(wrong_param=1) # type: ignore[misc]
377377
async def fn() -> None:
378378
"""Dummy function."""
379379

@@ -476,8 +476,9 @@ async def test_cache_write_doesnt_wait_for_future(self, mocker, decorator, decor
476476
mocker.spy(decorator, "set_in_cache")
477477
with patch.object(decorator, "get_from_cache", autospec=True, return_value=[None, None]):
478478
with patch("aiocache.decorators.asyncio.ensure_future", autospec=True):
479-
await decorator_call(1, keys=["a", "b"], value="value",
480-
aiocache_wait_for_write=False)
479+
await decorator_call(
480+
1, keys=["a", "b"], value="value", aiocache_wait_for_write=False
481+
)
481482

482483
decorator.set_in_cache.assert_not_awaited()
483484
decorator.set_in_cache.assert_called_once_with({"a": ANY, "b": ANY}, stub_dict, ANY, ANY)

0 commit comments

Comments
 (0)