cachetools 7.2.2__tar.gz → 7.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cachetools-7.2.2 → cachetools-7.2.3}/CHANGELOG.rst +8 -0
- {cachetools-7.2.2/src/cachetools.egg-info → cachetools-7.2.3}/PKG-INFO +1 -1
- {cachetools-7.2.2 → cachetools-7.2.3}/pyproject.toml +1 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/__init__.py +1 -1
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/__init__.pyi +35 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/_cached.py +13 -2
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/func.pyi +28 -2
- {cachetools-7.2.2 → cachetools-7.2.3/src/cachetools.egg-info}/PKG-INFO +1 -1
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_cached.py +44 -7
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_cachedmethod.py +4 -4
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_func.py +44 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/LICENSE +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/MANIFEST.in +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/README.rst +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/docs/conf.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/docs/index.rst +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/setup.cfg +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/_cachedmethod.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/_descriptor.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/func.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/keys.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/keys.pyi +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools/py.typed +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools.egg-info/SOURCES.txt +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools.egg-info/dependency_links.txt +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/src/cachetools.egg-info/top_level.txt +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/__init__.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_cache.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_classmethod.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_fifo.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_keys.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_lfu.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_lru.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_rr.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_threading.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_tlru.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tests/test_ttl.py +0 -0
- {cachetools-7.2.2 → cachetools-7.2.3}/tox.ini +0 -0
|
@@ -29,7 +29,9 @@ __all__: Final = (
|
|
|
29
29
|
__version__: str
|
|
30
30
|
|
|
31
31
|
_P = ParamSpec("_P")
|
|
32
|
+
_Q = ParamSpec("_Q")
|
|
32
33
|
_R = TypeVar("_R")
|
|
34
|
+
_S = TypeVar("_S")
|
|
33
35
|
_T = TypeVar("_T")
|
|
34
36
|
_KT = TypeVar("_KT")
|
|
35
37
|
_VT = TypeVar("_VT")
|
|
@@ -153,16 +155,47 @@ class _AbstractCondition(AbstractContextManager[Any], Protocol):
|
|
|
153
155
|
class _cached_wrapper(Generic[_P, _R]):
|
|
154
156
|
__wrapped__: Callable[_P, _R]
|
|
155
157
|
__name__: str
|
|
158
|
+
__qualname__: str
|
|
156
159
|
__doc__: str | None
|
|
157
160
|
cache: MutableMapping[Any, Any] | None
|
|
158
161
|
cache_key: Callable[..., Any] = ...
|
|
159
162
|
cache_lock: AbstractContextManager[Any] | None = None
|
|
160
163
|
cache_condition: _AbstractCondition | None = None
|
|
164
|
+
@overload # class access, e.g. Cls.method
|
|
165
|
+
def __get__(
|
|
166
|
+
self, obj: None, objtype: type | None = None
|
|
167
|
+
) -> _cached_wrapper[_P, _R]: ...
|
|
168
|
+
@overload # instance access binds the first parameter
|
|
169
|
+
def __get__(
|
|
170
|
+
self: _cached_wrapper[Concatenate[_S, _Q], _R],
|
|
171
|
+
obj: _S,
|
|
172
|
+
objtype: type | None = None,
|
|
173
|
+
) -> _cached_wrapper[_Q, _R]: ...
|
|
174
|
+
@overload # fallback, e.g. when wrapped by @staticmethod or @classmethod
|
|
175
|
+
def __get__(
|
|
176
|
+
self, obj: object, objtype: type | None = None
|
|
177
|
+
) -> _cached_wrapper[_P, _R]: ...
|
|
161
178
|
def __call__(self, /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ...
|
|
162
179
|
def cache_clear(self) -> None: ...
|
|
163
180
|
|
|
164
181
|
@type_check_only
|
|
165
182
|
class _cached_wrapper_info(_cached_wrapper[_P, _R]):
|
|
183
|
+
@overload
|
|
184
|
+
def __get__(
|
|
185
|
+
self, obj: None, objtype: type | None = None
|
|
186
|
+
) -> _cached_wrapper_info[_P, _R]: ...
|
|
187
|
+
@overload
|
|
188
|
+
def __get__(
|
|
189
|
+
self: _cached_wrapper_info[Concatenate[_S, _Q], _R],
|
|
190
|
+
obj: _S,
|
|
191
|
+
objtype: type | None = None,
|
|
192
|
+
) -> _cached_wrapper_info[_Q, _R]: ...
|
|
193
|
+
# pyright cannot match the self-typed base overload; each return type is
|
|
194
|
+
# the _cached_wrapper_info subtype of the corresponding base return type
|
|
195
|
+
@overload
|
|
196
|
+
def __get__( # pyright: ignore[reportIncompatibleMethodOverride]
|
|
197
|
+
self, obj: object, objtype: type | None = None
|
|
198
|
+
) -> _cached_wrapper_info[_P, _R]: ...
|
|
166
199
|
def cache_info(self) -> _CacheInfo: ...
|
|
167
200
|
|
|
168
201
|
@overload
|
|
@@ -195,6 +228,7 @@ def cached(
|
|
|
195
228
|
class _cachedmethod_unbound(Generic[_P, _R]):
|
|
196
229
|
__wrapped__: Callable[Concatenate[Any, _P], _R]
|
|
197
230
|
__name__: str
|
|
231
|
+
__qualname__: str
|
|
198
232
|
__doc__: str | None
|
|
199
233
|
@overload
|
|
200
234
|
def __call__(self, obj: Any, /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ...
|
|
@@ -206,6 +240,7 @@ class _cachedmethod_unbound(Generic[_P, _R]):
|
|
|
206
240
|
class _cachedmethod_wrapper(Generic[_P, _R]):
|
|
207
241
|
__wrapped__: Callable[Concatenate[Any, _P], _R]
|
|
208
242
|
__name__: str
|
|
243
|
+
__qualname__: str
|
|
209
244
|
__doc__: str | None
|
|
210
245
|
cache: MutableMapping[Any, Any]
|
|
211
246
|
cache_key: Callable[..., Any] = ...
|
|
@@ -11,6 +11,10 @@ import warnings
|
|
|
11
11
|
# over ease of maintenance, thus providing separate wrappers for
|
|
12
12
|
# all valid combinations of decorator parameters lock, condition and
|
|
13
13
|
# info.
|
|
14
|
+
#
|
|
15
|
+
# Each wrapper calls functools.update_wrapper() before setting its own
|
|
16
|
+
# attributes, so func.__dict__ cannot override wrapper state, e.g. when
|
|
17
|
+
# stacking decorators.
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
def _condition_info(func, cache, key, lock, cond, info):
|
|
@@ -52,6 +56,7 @@ def _condition_info(func, cache, key, lock, cond, info):
|
|
|
52
56
|
with lock:
|
|
53
57
|
return info(hits, misses)
|
|
54
58
|
|
|
59
|
+
functools.update_wrapper(wrapper, func)
|
|
55
60
|
wrapper.cache_clear = cache_clear
|
|
56
61
|
wrapper.cache_info = cache_info
|
|
57
62
|
return wrapper
|
|
@@ -90,6 +95,7 @@ def _locked_info(func, cache, key, lock, info):
|
|
|
90
95
|
with lock:
|
|
91
96
|
return info(hits, misses)
|
|
92
97
|
|
|
98
|
+
functools.update_wrapper(wrapper, func)
|
|
93
99
|
wrapper.cache_clear = cache_clear
|
|
94
100
|
wrapper.cache_info = cache_info
|
|
95
101
|
return wrapper
|
|
@@ -122,6 +128,7 @@ def _unlocked_info(func, cache, key, info):
|
|
|
122
128
|
def cache_info():
|
|
123
129
|
return info(hits, misses)
|
|
124
130
|
|
|
131
|
+
functools.update_wrapper(wrapper, func)
|
|
125
132
|
wrapper.cache_clear = cache_clear
|
|
126
133
|
wrapper.cache_info = cache_info
|
|
127
134
|
return wrapper
|
|
@@ -139,6 +146,7 @@ def _uncached_info(func, info):
|
|
|
139
146
|
nonlocal misses
|
|
140
147
|
misses = 0
|
|
141
148
|
|
|
149
|
+
functools.update_wrapper(wrapper, func)
|
|
142
150
|
wrapper.cache_clear = cache_clear
|
|
143
151
|
wrapper.cache_info = lambda: info(0, misses)
|
|
144
152
|
return wrapper
|
|
@@ -173,6 +181,7 @@ def _condition(func, cache, key, lock, cond):
|
|
|
173
181
|
with lock:
|
|
174
182
|
cache.clear()
|
|
175
183
|
|
|
184
|
+
functools.update_wrapper(wrapper, func)
|
|
176
185
|
wrapper.cache_clear = cache_clear
|
|
177
186
|
return wrapper
|
|
178
187
|
|
|
@@ -199,6 +208,7 @@ def _locked(func, cache, key, lock):
|
|
|
199
208
|
with lock:
|
|
200
209
|
cache.clear()
|
|
201
210
|
|
|
211
|
+
functools.update_wrapper(wrapper, func)
|
|
202
212
|
wrapper.cache_clear = cache_clear
|
|
203
213
|
return wrapper
|
|
204
214
|
|
|
@@ -217,6 +227,7 @@ def _unlocked(func, cache, key):
|
|
|
217
227
|
pass # value too large
|
|
218
228
|
return v
|
|
219
229
|
|
|
230
|
+
functools.update_wrapper(wrapper, func)
|
|
220
231
|
wrapper.cache_clear = lambda: cache.clear()
|
|
221
232
|
return wrapper
|
|
222
233
|
|
|
@@ -225,6 +236,7 @@ def _uncached(func):
|
|
|
225
236
|
def wrapper(*args, **kwargs):
|
|
226
237
|
return func(*args, **kwargs)
|
|
227
238
|
|
|
239
|
+
functools.update_wrapper(wrapper, func)
|
|
228
240
|
wrapper.cache_clear = lambda: None
|
|
229
241
|
return wrapper
|
|
230
242
|
|
|
@@ -265,5 +277,4 @@ def _wrapper(func, cache, key, lock=None, cond=None, info=None):
|
|
|
265
277
|
wrapper.cache_key = key
|
|
266
278
|
wrapper.cache_lock = lock if lock is not None else cond
|
|
267
279
|
wrapper.cache_condition = cond
|
|
268
|
-
|
|
269
|
-
return functools.update_wrapper(wrapper, func)
|
|
280
|
+
return wrapper
|
|
@@ -1,19 +1,45 @@
|
|
|
1
1
|
from collections.abc import Callable, Sequence
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
Concatenate,
|
|
5
|
+
Final,
|
|
6
|
+
Generic,
|
|
7
|
+
ParamSpec,
|
|
8
|
+
TypeVar,
|
|
9
|
+
overload,
|
|
10
|
+
type_check_only,
|
|
11
|
+
)
|
|
3
12
|
|
|
4
13
|
from . import _CacheInfo
|
|
5
14
|
|
|
6
15
|
__all__: Final = ("fifo_cache", "lfu_cache", "lru_cache", "rr_cache", "ttl_cache")
|
|
7
16
|
|
|
8
17
|
_P = ParamSpec("_P")
|
|
9
|
-
|
|
18
|
+
_Q = ParamSpec("_Q")
|
|
10
19
|
_R = TypeVar("_R")
|
|
20
|
+
_S = TypeVar("_S")
|
|
21
|
+
_T = TypeVar("_T")
|
|
11
22
|
|
|
12
23
|
@type_check_only
|
|
13
24
|
class _cachetools_cache_wrapper(Generic[_P, _R]):
|
|
14
25
|
__wrapped__: Callable[_P, _R]
|
|
15
26
|
__name__: str
|
|
27
|
+
__qualname__: str
|
|
16
28
|
__doc__: str | None
|
|
29
|
+
@overload # class access, e.g. Cls.method
|
|
30
|
+
def __get__(
|
|
31
|
+
self, obj: None, objtype: type | None = None
|
|
32
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
33
|
+
@overload # instance access binds the first parameter
|
|
34
|
+
def __get__(
|
|
35
|
+
self: _cachetools_cache_wrapper[Concatenate[_S, _Q], _R],
|
|
36
|
+
obj: _S,
|
|
37
|
+
objtype: type | None = None,
|
|
38
|
+
) -> _cachetools_cache_wrapper[_Q, _R]: ...
|
|
39
|
+
@overload # fallback, e.g. when wrapped by @staticmethod or @classmethod
|
|
40
|
+
def __get__(
|
|
41
|
+
self, obj: object, objtype: type | None = None
|
|
42
|
+
) -> _cachetools_cache_wrapper[_P, _R]: ...
|
|
17
43
|
def __call__(self, /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ...
|
|
18
44
|
def cache_info(self) -> _CacheInfo: ...
|
|
19
45
|
def cache_clear(self) -> None: ...
|
|
@@ -154,6 +154,8 @@ class DecoratorTestMixin(SimplifiedTestCaseProtocol):
|
|
|
154
154
|
wrapper = cachetools.cached(cache)(self.func)
|
|
155
155
|
|
|
156
156
|
self.assertEqual(wrapper.__wrapped__, self.func)
|
|
157
|
+
self.assertEqual(wrapper.__name__, "func")
|
|
158
|
+
self.assertEqual(wrapper.__qualname__, "DecoratorTestMixin.func")
|
|
157
159
|
|
|
158
160
|
self.assertEqual(len(cache), 0)
|
|
159
161
|
self.assertEqual(wrapper.__wrapped__(0), 0)
|
|
@@ -316,6 +318,21 @@ class CacheWrapperTest(unittest.TestCase, DecoratorTestMixin):
|
|
|
316
318
|
self.assertEqual(wrapper.cache_info(), (0, 0, 2, 0))
|
|
317
319
|
self.assertEqual(lock.count, 13)
|
|
318
320
|
|
|
321
|
+
def test_stacked_decorators(self):
|
|
322
|
+
inner_cache = self.cache(2)
|
|
323
|
+
outer_cache = self.cache(2)
|
|
324
|
+
inner_wrapper = cachetools.cached(inner_cache, info=True)(self.func)
|
|
325
|
+
outer_wrapper = cachetools.cached(outer_cache, info=True)(inner_wrapper)
|
|
326
|
+
self.assertIs(outer_wrapper.__wrapped__, inner_wrapper)
|
|
327
|
+
self.assertIs(outer_wrapper.cache, outer_cache)
|
|
328
|
+
self.assertEqual(outer_wrapper(0), 0)
|
|
329
|
+
self.assertEqual(outer_wrapper(0), 0)
|
|
330
|
+
self.assertEqual(outer_wrapper.cache_info(), (1, 1, 2, 1))
|
|
331
|
+
self.assertEqual(inner_wrapper.cache_info(), (0, 1, 2, 1))
|
|
332
|
+
outer_wrapper.cache_clear()
|
|
333
|
+
self.assertEqual(len(outer_cache), 0)
|
|
334
|
+
self.assertEqual(len(inner_cache), 1)
|
|
335
|
+
|
|
319
336
|
def test_zero_size_cache_decorator(self):
|
|
320
337
|
cache = self.cache(0)
|
|
321
338
|
wrapper = cachetools.cached(cache)(self.func)
|
|
@@ -386,20 +403,40 @@ class CacheWrapperTest(unittest.TestCase, DecoratorTestMixin):
|
|
|
386
403
|
|
|
387
404
|
"""
|
|
388
405
|
|
|
406
|
+
cache = self.cache(2)
|
|
407
|
+
|
|
389
408
|
class Cached:
|
|
409
|
+
@cachetools.cached(cache, key=cachetools.keys.methodkey)
|
|
410
|
+
def get(self, value: int) -> int:
|
|
411
|
+
return value
|
|
412
|
+
|
|
390
413
|
@cachetools.cached(self.cache(2), key=cachetools.keys.methodkey, info=True)
|
|
391
|
-
def
|
|
414
|
+
def get_info(self, value):
|
|
415
|
+
return value
|
|
416
|
+
|
|
417
|
+
@staticmethod
|
|
418
|
+
@cachetools.cached(self.cache(2))
|
|
419
|
+
def get_static(value: int) -> int:
|
|
392
420
|
return value
|
|
393
421
|
|
|
394
422
|
cached = Cached()
|
|
395
|
-
self.assertEqual(cached.get(1), 1)
|
|
396
|
-
self.assertEqual(cached.get(1), 1) # type: ignore
|
|
423
|
+
self.assertEqual(cached.get(1), 1)
|
|
397
424
|
self.assertEqual(Cached.get(cached, 1), 1)
|
|
398
|
-
self.assertEqual(
|
|
399
|
-
self.assertEqual(Cached.get.cache_info(), (2, 1, 2, 1))
|
|
425
|
+
self.assertEqual(len(cache), 1)
|
|
400
426
|
cached.get.cache_clear()
|
|
401
|
-
self.assertEqual(
|
|
402
|
-
|
|
427
|
+
self.assertEqual(len(cache), 0)
|
|
428
|
+
|
|
429
|
+
self.assertEqual(cached.get_info(1), 1)
|
|
430
|
+
self.assertEqual(cached.get_info(1), 1)
|
|
431
|
+
self.assertEqual(Cached.get_info(cached, 1), 1)
|
|
432
|
+
self.assertEqual(cached.get_info.cache_info(), (2, 1, 2, 1))
|
|
433
|
+
self.assertEqual(Cached.get_info.cache_info(), (2, 1, 2, 1))
|
|
434
|
+
cached.get_info.cache_clear()
|
|
435
|
+
self.assertEqual(cached.get_info.cache_info(), (0, 0, 2, 0))
|
|
436
|
+
self.assertEqual(Cached.get_info.cache_info(), (0, 0, 2, 0))
|
|
437
|
+
|
|
438
|
+
self.assertEqual(cached.get_static(1), 1)
|
|
439
|
+
self.assertEqual(Cached.get_static(1), 1)
|
|
403
440
|
|
|
404
441
|
|
|
405
442
|
class DictWrapperTest(unittest.TestCase, DecoratorTestMixin):
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
# TODO: type stub overloads for unbound methods?
|
|
2
|
-
# pyright: reportCallIssue=false
|
|
3
|
-
|
|
4
1
|
import unittest
|
|
5
2
|
import warnings
|
|
6
3
|
|
|
@@ -359,6 +356,7 @@ class MethodDecoratorTestMixin(SimplifiedTestCaseProtocol):
|
|
|
359
356
|
self.assertEqual(len(cache), 0)
|
|
360
357
|
self.assertEqual(cached.get.__wrapped__(cached, 0), 0)
|
|
361
358
|
self.assertEqual(cached.get.__name__, "get")
|
|
359
|
+
self.assertEqual(cached.get.__qualname__, "Cached.get")
|
|
362
360
|
self.assertEqual((cached.get.__doc__ or "").strip(), "docstring")
|
|
363
361
|
self.assertEqual(len(cache), 0)
|
|
364
362
|
self.assertEqual(cached.get(0), 1)
|
|
@@ -636,7 +634,7 @@ class CacheMethodTest(unittest.TestCase, MethodDecoratorTestMixin):
|
|
|
636
634
|
|
|
637
635
|
def test_undecorated_override(self):
|
|
638
636
|
class Child(Cached):
|
|
639
|
-
def get_info(self, value): # type: ignore
|
|
637
|
+
def get_info(self, value): # type: ignore
|
|
640
638
|
return super().get_info(value) + 1
|
|
641
639
|
|
|
642
640
|
cache = self.cache(2)
|
|
@@ -787,6 +785,8 @@ class UnboundMethodTest(unittest.TestCase):
|
|
|
787
785
|
def test_wrapped_method(self):
|
|
788
786
|
cached = Cached(Cache(2))
|
|
789
787
|
self.assertIs(Cached.get.__wrapped__, cached.get.__wrapped__)
|
|
788
|
+
self.assertEqual(Cached.get.__name__, "get")
|
|
789
|
+
self.assertEqual(Cached.get.__qualname__, "Cached.get")
|
|
790
790
|
self.assertEqual(Cached.get.__wrapped__(cached, 1), 0)
|
|
791
791
|
self.assertEqual(Cached.get.__wrapped__(cached, 1), 1)
|
|
792
792
|
self.assertEqual(len(cached.cache), 0)
|
|
@@ -132,10 +132,54 @@ class DecoratorTestMixin(SimplifiedTestCaseProtocol):
|
|
|
132
132
|
self.assertEqual(cached.get.cache_info(), (0, 0, 2, 0))
|
|
133
133
|
self.assertEqual(Cached.get.cache_info(), (0, 0, 2, 0))
|
|
134
134
|
|
|
135
|
+
def test_stacked_decorators(self):
|
|
136
|
+
inner_wrapper = self.decorator(maxsize=2)(lambda n: n)
|
|
137
|
+
outer_wrapper = self.decorator(maxsize=3, typed=True)(inner_wrapper)
|
|
138
|
+
self.assertIs(outer_wrapper.__wrapped__, inner_wrapper)
|
|
139
|
+
self.assertEqual(
|
|
140
|
+
inner_wrapper.cache_parameters(), {"maxsize": 2, "typed": False}
|
|
141
|
+
)
|
|
142
|
+
self.assertEqual(
|
|
143
|
+
outer_wrapper.cache_parameters(), {"maxsize": 3, "typed": True}
|
|
144
|
+
)
|
|
145
|
+
self.assertEqual(outer_wrapper(1), 1)
|
|
146
|
+
self.assertEqual(outer_wrapper(1), 1)
|
|
147
|
+
self.assertEqual(outer_wrapper.cache_info(), (1, 1, 3, 1))
|
|
148
|
+
self.assertEqual(inner_wrapper.cache_info(), (0, 1, 2, 1))
|
|
149
|
+
outer_wrapper.cache_clear()
|
|
150
|
+
self.assertEqual(outer_wrapper.cache_info(), (0, 0, 3, 0))
|
|
151
|
+
self.assertEqual(inner_wrapper.cache_info(), (0, 1, 2, 1))
|
|
152
|
+
|
|
135
153
|
|
|
136
154
|
class FIFODecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
137
155
|
DECORATOR = staticmethod(cachetools.func.fifo_cache)
|
|
138
156
|
|
|
157
|
+
def test_method_typed(self):
|
|
158
|
+
"""Type-checked by pyright via the stub __get__ overloads."""
|
|
159
|
+
|
|
160
|
+
class Cached:
|
|
161
|
+
@cachetools.func.fifo_cache(maxsize=2)
|
|
162
|
+
def get(self, n: int) -> int:
|
|
163
|
+
return n
|
|
164
|
+
|
|
165
|
+
@cachetools.func.fifo_cache
|
|
166
|
+
def get_bare(self, n: int) -> int:
|
|
167
|
+
return n
|
|
168
|
+
|
|
169
|
+
@staticmethod
|
|
170
|
+
@cachetools.func.fifo_cache
|
|
171
|
+
def get_static(n: int) -> int:
|
|
172
|
+
return n
|
|
173
|
+
|
|
174
|
+
cached = Cached()
|
|
175
|
+
result: int = cached.get(1)
|
|
176
|
+
self.assertEqual(result, 1)
|
|
177
|
+
self.assertEqual(Cached.get(cached, 1), 1)
|
|
178
|
+
self.assertEqual(cached.get.cache_info(), (1, 1, 2, 1))
|
|
179
|
+
self.assertEqual(cached.get_bare(1), 1)
|
|
180
|
+
self.assertEqual(cached.get_static(1), 1)
|
|
181
|
+
self.assertEqual(Cached.get_static(1), 1)
|
|
182
|
+
|
|
139
183
|
|
|
140
184
|
class LFUDecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
141
185
|
DECORATOR = staticmethod(cachetools.func.lfu_cache)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|