cachetools 5.3.3__tar.gz → 5.4.0__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-5.3.3 → cachetools-5.4.0}/CHANGELOG.rst +12 -0
- {cachetools-5.3.3/src/cachetools.egg-info → cachetools-5.4.0}/PKG-INFO +1 -1
- {cachetools-5.3.3 → cachetools-5.4.0}/docs/index.rst +20 -3
- {cachetools-5.3.3 → cachetools-5.4.0}/src/cachetools/__init__.py +5 -1
- {cachetools-5.3.3 → cachetools-5.4.0}/src/cachetools/func.py +4 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/src/cachetools/keys.py +6 -1
- {cachetools-5.3.3 → cachetools-5.4.0/src/cachetools.egg-info}/PKG-INFO +1 -1
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_cachedmethod.py +21 -21
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_func.py +8 -6
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_mru.py +18 -3
- {cachetools-5.3.3 → cachetools-5.4.0}/tox.ini +1 -1
- {cachetools-5.3.3 → cachetools-5.4.0}/LICENSE +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/MANIFEST.in +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/README.rst +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/docs/conf.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/pyproject.toml +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/setup.cfg +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/setup.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/src/cachetools.egg-info/SOURCES.txt +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/src/cachetools.egg-info/dependency_links.txt +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/src/cachetools.egg-info/top_level.txt +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/__init__.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_cache.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_cached.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_fifo.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_keys.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_lfu.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_lru.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_rr.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_tlru.py +0 -0
- {cachetools-5.3.3 → cachetools-5.4.0}/tests/test_ttl.py +0 -0
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
v5.4.0 (2024-07-15)
|
|
2
|
+
===================
|
|
3
|
+
|
|
4
|
+
- Add the ``keys.typedmethodkey`` decorator.
|
|
5
|
+
|
|
6
|
+
- Deprecate ``MRUCache`` class.
|
|
7
|
+
|
|
8
|
+
- Deprecate ``@func.mru_cache`` decorator.
|
|
9
|
+
|
|
10
|
+
- Update CI environment.
|
|
11
|
+
|
|
12
|
+
|
|
1
13
|
v5.3.3 (2024-02-26)
|
|
2
14
|
===================
|
|
3
15
|
|
|
@@ -96,6 +96,12 @@ computed when the item is inserted into the cache.
|
|
|
96
96
|
This class discards the most recently used items first to make
|
|
97
97
|
space when necessary.
|
|
98
98
|
|
|
99
|
+
.. deprecated:: 5.4
|
|
100
|
+
|
|
101
|
+
`MRUCache` has been deprecated due to lack of use, to reduce
|
|
102
|
+
maintenance. Please choose another cache implementation that suits
|
|
103
|
+
your needs.
|
|
104
|
+
|
|
99
105
|
.. autoclass:: RRCache(maxsize, choice=random.choice, getsizeof=None)
|
|
100
106
|
:members: choice, popitem
|
|
101
107
|
|
|
@@ -416,7 +422,7 @@ often called with the same arguments:
|
|
|
416
422
|
|
|
417
423
|
.. testcode::
|
|
418
424
|
|
|
419
|
-
class CachedPEPs
|
|
425
|
+
class CachedPEPs:
|
|
420
426
|
|
|
421
427
|
def __init__(self, cachesize):
|
|
422
428
|
self.cache = LRUCache(maxsize=cachesize)
|
|
@@ -444,7 +450,7 @@ often called with the same arguments:
|
|
|
444
450
|
|
|
445
451
|
.. testcode::
|
|
446
452
|
|
|
447
|
-
class CachedReferences
|
|
453
|
+
class CachedReferences:
|
|
448
454
|
|
|
449
455
|
def __init__(self, cachesize):
|
|
450
456
|
self.cache = LRUCache(maxsize=cachesize)
|
|
@@ -491,7 +497,7 @@ functions with the :func:`cached` and :func:`cachedmethod` decorators:
|
|
|
491
497
|
|
|
492
498
|
.. autofunction:: methodkey
|
|
493
499
|
|
|
494
|
-
This function is
|
|
500
|
+
This function is similar to :func:`hashkey`, but ignores its
|
|
495
501
|
first positional argument, i.e. `self` when used with the
|
|
496
502
|
:func:`cachedmethod` decorator.
|
|
497
503
|
|
|
@@ -502,6 +508,12 @@ functions with the :func:`cached` and :func:`cachedmethod` decorators:
|
|
|
502
508
|
``typedkey(3)`` and ``typedkey(3.0)`` will return different
|
|
503
509
|
results.
|
|
504
510
|
|
|
511
|
+
.. autofunction:: typedmethodkey
|
|
512
|
+
|
|
513
|
+
This function is similar to :func:`typedkey`, but ignores its
|
|
514
|
+
first positional argument, i.e. `self` when used with the
|
|
515
|
+
:func:`cachedmethod` decorator.
|
|
516
|
+
|
|
505
517
|
These functions can also be helpful when implementing custom key
|
|
506
518
|
functions for handling some non-hashable arguments. For example,
|
|
507
519
|
calling the following function with a dictionary as its `env` argument
|
|
@@ -598,6 +610,11 @@ all the decorators in this module are thread-safe by default.
|
|
|
598
610
|
saves up to `maxsize` results based on a Most Recently Used (MRU)
|
|
599
611
|
algorithm.
|
|
600
612
|
|
|
613
|
+
.. deprecated:: 5.4
|
|
614
|
+
|
|
615
|
+
The `mru_cache` decorator has been deprecated due to lack of use.
|
|
616
|
+
Please choose a decorator based on some other algorithm.
|
|
617
|
+
|
|
601
618
|
.. decorator:: rr_cache(user_function)
|
|
602
619
|
rr_cache(maxsize=128, choice=random.choice, typed=False)
|
|
603
620
|
|
|
@@ -13,7 +13,7 @@ __all__ = (
|
|
|
13
13
|
"cachedmethod",
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
__version__ = "5.
|
|
16
|
+
__version__ = "5.4.0"
|
|
17
17
|
|
|
18
18
|
import collections
|
|
19
19
|
import collections.abc
|
|
@@ -241,6 +241,10 @@ class MRUCache(Cache):
|
|
|
241
241
|
"""Most Recently Used (MRU) cache implementation."""
|
|
242
242
|
|
|
243
243
|
def __init__(self, maxsize, getsizeof=None):
|
|
244
|
+
from warnings import warn
|
|
245
|
+
|
|
246
|
+
warn("MRUCache is deprecated", DeprecationWarning, stacklevel=2)
|
|
247
|
+
|
|
244
248
|
Cache.__init__(self, maxsize, getsizeof)
|
|
245
249
|
self.__order = collections.OrderedDict()
|
|
246
250
|
|
|
@@ -82,6 +82,10 @@ def mru_cache(maxsize=128, typed=False):
|
|
|
82
82
|
up to `maxsize` results based on a Most Recently Used (MRU)
|
|
83
83
|
algorithm.
|
|
84
84
|
"""
|
|
85
|
+
from warnings import warn
|
|
86
|
+
|
|
87
|
+
warn("@mru_cache is deprecated", DeprecationWarning, stacklevel=2)
|
|
88
|
+
|
|
85
89
|
if maxsize is None:
|
|
86
90
|
return _cache({}, None, typed)
|
|
87
91
|
elif callable(maxsize):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Key functions for memoizing decorators."""
|
|
2
2
|
|
|
3
|
-
__all__ = ("hashkey", "methodkey", "typedkey")
|
|
3
|
+
__all__ = ("hashkey", "methodkey", "typedkey", "typedmethodkey")
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class _HashedTuple(tuple):
|
|
@@ -55,3 +55,8 @@ def typedkey(*args, **kwargs):
|
|
|
55
55
|
key += tuple(type(v) for v in args)
|
|
56
56
|
key += tuple(type(v) for _, v in sorted(kwargs.items()))
|
|
57
57
|
return key
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def typedmethodkey(self, *args, **kwargs):
|
|
61
|
+
"""Return a typed cache key for use with cached methods."""
|
|
62
|
+
return typedkey(*args, **kwargs)
|
|
@@ -14,8 +14,8 @@ class Cached:
|
|
|
14
14
|
self.count += 1
|
|
15
15
|
return count
|
|
16
16
|
|
|
17
|
-
@cachedmethod(lambda self: self.cache, key=keys.
|
|
18
|
-
def
|
|
17
|
+
@cachedmethod(lambda self: self.cache, key=keys.typedmethodkey)
|
|
18
|
+
def get_typedmethod(self, value):
|
|
19
19
|
count = self.count
|
|
20
20
|
self.count += 1
|
|
21
21
|
return count
|
|
@@ -67,16 +67,16 @@ class CachedMethodTest(unittest.TestCase):
|
|
|
67
67
|
cached.cache.clear()
|
|
68
68
|
self.assertEqual(cached.get(1), 2)
|
|
69
69
|
|
|
70
|
-
def
|
|
70
|
+
def test_typedmethod_dict(self):
|
|
71
71
|
cached = Cached(LRUCache(maxsize=2))
|
|
72
72
|
|
|
73
|
-
self.assertEqual(cached.
|
|
74
|
-
self.assertEqual(cached.
|
|
75
|
-
self.assertEqual(cached.
|
|
76
|
-
self.assertEqual(cached.
|
|
77
|
-
self.assertEqual(cached.
|
|
78
|
-
self.assertEqual(cached.
|
|
79
|
-
self.assertEqual(cached.
|
|
73
|
+
self.assertEqual(cached.get_typedmethod(0), 0)
|
|
74
|
+
self.assertEqual(cached.get_typedmethod(1), 1)
|
|
75
|
+
self.assertEqual(cached.get_typedmethod(1), 1)
|
|
76
|
+
self.assertEqual(cached.get_typedmethod(1.0), 2)
|
|
77
|
+
self.assertEqual(cached.get_typedmethod(1.0), 2)
|
|
78
|
+
self.assertEqual(cached.get_typedmethod(0.0), 3)
|
|
79
|
+
self.assertEqual(cached.get_typedmethod(0), 4)
|
|
80
80
|
|
|
81
81
|
def test_lru(self):
|
|
82
82
|
cached = Cached(LRUCache(maxsize=2))
|
|
@@ -90,16 +90,16 @@ class CachedMethodTest(unittest.TestCase):
|
|
|
90
90
|
cached.cache.clear()
|
|
91
91
|
self.assertEqual(cached.get(1), 2)
|
|
92
92
|
|
|
93
|
-
def
|
|
93
|
+
def test_typedmethod_lru(self):
|
|
94
94
|
cached = Cached(LRUCache(maxsize=2))
|
|
95
95
|
|
|
96
|
-
self.assertEqual(cached.
|
|
97
|
-
self.assertEqual(cached.
|
|
98
|
-
self.assertEqual(cached.
|
|
99
|
-
self.assertEqual(cached.
|
|
100
|
-
self.assertEqual(cached.
|
|
101
|
-
self.assertEqual(cached.
|
|
102
|
-
self.assertEqual(cached.
|
|
96
|
+
self.assertEqual(cached.get_typedmethod(0), 0)
|
|
97
|
+
self.assertEqual(cached.get_typedmethod(1), 1)
|
|
98
|
+
self.assertEqual(cached.get_typedmethod(1), 1)
|
|
99
|
+
self.assertEqual(cached.get_typedmethod(1.0), 2)
|
|
100
|
+
self.assertEqual(cached.get_typedmethod(1.0), 2)
|
|
101
|
+
self.assertEqual(cached.get_typedmethod(0.0), 3)
|
|
102
|
+
self.assertEqual(cached.get_typedmethod(0), 4)
|
|
103
103
|
|
|
104
104
|
def test_nospace(self):
|
|
105
105
|
cached = Cached(LRUCache(maxsize=0))
|
|
@@ -141,10 +141,10 @@ class CachedMethodTest(unittest.TestCase):
|
|
|
141
141
|
self.assertEqual(cached.get(1), 2)
|
|
142
142
|
self.assertEqual(cached.get(1.0), 2)
|
|
143
143
|
|
|
144
|
-
ref = cached.
|
|
144
|
+
ref = cached.get_typedmethod(1)
|
|
145
145
|
self.assertEqual(ref, 3)
|
|
146
|
-
self.assertEqual(cached.
|
|
147
|
-
self.assertEqual(cached.
|
|
146
|
+
self.assertEqual(cached.get_typedmethod(1), 3)
|
|
147
|
+
self.assertEqual(cached.get_typedmethod(1.0), 4)
|
|
148
148
|
|
|
149
149
|
cached.cache.clear()
|
|
150
150
|
self.assertEqual(cached.get(1), 5)
|
|
@@ -100,30 +100,32 @@ class DecoratorTestMixin:
|
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
class FIFODecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
103
|
-
|
|
104
103
|
DECORATOR = staticmethod(cachetools.func.fifo_cache)
|
|
105
104
|
|
|
106
105
|
|
|
107
106
|
class LFUDecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
108
|
-
|
|
109
107
|
DECORATOR = staticmethod(cachetools.func.lfu_cache)
|
|
110
108
|
|
|
111
109
|
|
|
112
110
|
class LRUDecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
113
|
-
|
|
114
111
|
DECORATOR = staticmethod(cachetools.func.lru_cache)
|
|
115
112
|
|
|
116
113
|
|
|
117
114
|
class MRUDecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
115
|
+
def decorator(self, maxsize, **kwargs):
|
|
116
|
+
import warnings
|
|
118
117
|
|
|
119
|
-
|
|
118
|
+
with warnings.catch_warnings(record=True) as w:
|
|
119
|
+
warnings.simplefilter("always")
|
|
120
|
+
d = cachetools.func.mru_cache(maxsize, **kwargs)
|
|
121
|
+
self.assertNotEqual(len(w), 0)
|
|
122
|
+
self.assertIs(w[0].category, DeprecationWarning)
|
|
123
|
+
return d
|
|
120
124
|
|
|
121
125
|
|
|
122
126
|
class RRDecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
123
|
-
|
|
124
127
|
DECORATOR = staticmethod(cachetools.func.rr_cache)
|
|
125
128
|
|
|
126
129
|
|
|
127
130
|
class TTLDecoratorTest(unittest.TestCase, DecoratorTestMixin):
|
|
128
|
-
|
|
129
131
|
DECORATOR = staticmethod(cachetools.func.ttl_cache)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import unittest
|
|
2
|
+
import warnings
|
|
2
3
|
|
|
3
4
|
from cachetools import MRUCache
|
|
4
5
|
|
|
@@ -7,10 +8,16 @@ from . import CacheTestMixin
|
|
|
7
8
|
|
|
8
9
|
class MRUCacheTest(unittest.TestCase, CacheTestMixin):
|
|
9
10
|
|
|
11
|
+
# TODO: method to create cache that can be overridden
|
|
10
12
|
Cache = MRUCache
|
|
11
13
|
|
|
12
14
|
def test_evict__writes_only(self):
|
|
13
|
-
|
|
15
|
+
|
|
16
|
+
with warnings.catch_warnings(record=True) as w:
|
|
17
|
+
warnings.simplefilter("always")
|
|
18
|
+
cache = MRUCache(maxsize=2)
|
|
19
|
+
self.assertEqual(len(w), 1)
|
|
20
|
+
self.assertIs(w[0].category, DeprecationWarning)
|
|
14
21
|
|
|
15
22
|
cache[1] = 1
|
|
16
23
|
cache[2] = 2
|
|
@@ -22,7 +29,11 @@ class MRUCacheTest(unittest.TestCase, CacheTestMixin):
|
|
|
22
29
|
assert 3 in cache
|
|
23
30
|
|
|
24
31
|
def test_evict__with_access(self):
|
|
25
|
-
|
|
32
|
+
with warnings.catch_warnings(record=True) as w:
|
|
33
|
+
warnings.simplefilter("always")
|
|
34
|
+
cache = MRUCache(maxsize=2)
|
|
35
|
+
self.assertEqual(len(w), 1)
|
|
36
|
+
self.assertIs(w[0].category, DeprecationWarning)
|
|
26
37
|
|
|
27
38
|
cache[1] = 1
|
|
28
39
|
cache[2] = 2
|
|
@@ -34,7 +45,11 @@ class MRUCacheTest(unittest.TestCase, CacheTestMixin):
|
|
|
34
45
|
assert 3 in cache
|
|
35
46
|
|
|
36
47
|
def test_evict__with_delete(self):
|
|
37
|
-
|
|
48
|
+
with warnings.catch_warnings(record=True) as w:
|
|
49
|
+
warnings.simplefilter("always")
|
|
50
|
+
cache = MRUCache(maxsize=2)
|
|
51
|
+
self.assertEqual(len(w), 1)
|
|
52
|
+
self.assertIs(w[0].category, DeprecationWarning)
|
|
38
53
|
|
|
39
54
|
cache[1] = 1
|
|
40
55
|
cache[2] = 2
|
|
@@ -32,7 +32,7 @@ commands =
|
|
|
32
32
|
deps =
|
|
33
33
|
flake8
|
|
34
34
|
flake8-black; implementation_name == "cpython"
|
|
35
|
-
black==22.12.0; implementation_name == "cpython"
|
|
35
|
+
black==22.12.0; implementation_name == "cpython" and python_version < "3.8"
|
|
36
36
|
flake8-bugbear
|
|
37
37
|
flake8-import-order
|
|
38
38
|
commands =
|
|
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
|