cachetools 6.2.5__tar.gz → 6.2.6__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-6.2.5 → cachetools-6.2.6}/CHANGELOG.rst +12 -0
- {cachetools-6.2.5/src/cachetools.egg-info → cachetools-6.2.6}/PKG-INFO +1 -1
- {cachetools-6.2.5 → cachetools-6.2.6}/docs/index.rst +8 -7
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools/__init__.py +4 -2
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools/func.py +3 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools/keys.py +6 -3
- {cachetools-6.2.5 → cachetools-6.2.6/src/cachetools.egg-info}/PKG-INFO +1 -1
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/__init__.py +5 -2
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_keys.py +1 -1
- {cachetools-6.2.5 → cachetools-6.2.6}/LICENSE +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/MANIFEST.in +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/README.rst +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/docs/conf.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/pyproject.toml +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/setup.cfg +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools/_cached.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools/_cachedmethod.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools.egg-info/SOURCES.txt +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools.egg-info/dependency_links.txt +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/src/cachetools.egg-info/top_level.txt +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_cache.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_cached.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_cachedmethod.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_fifo.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_func.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_lfu.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_lru.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_rr.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_threading.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_tlru.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tests/test_ttl.py +0 -0
- {cachetools-6.2.5 → cachetools-6.2.6}/tox.ini +0 -0
|
@@ -35,11 +35,11 @@ Cache implementations
|
|
|
35
35
|
This module provides several classes implementing caches using
|
|
36
36
|
different cache algorithms. All these classes derive from class
|
|
37
37
|
:class:`Cache`, which in turn derives from
|
|
38
|
-
:class:`collections.MutableMapping`, and provide :attr:`maxsize`
|
|
39
|
-
:attr:`currsize` properties to retrieve the maximum and current
|
|
40
|
-
of the cache. When a cache is full, :meth:`Cache.__setitem__()`
|
|
41
|
-
:meth:`self.popitem()` repeatedly until there is enough room for
|
|
42
|
-
item to be added.
|
|
38
|
+
:class:`collections.abc.MutableMapping`, and provide :attr:`maxsize`
|
|
39
|
+
and :attr:`currsize` properties to retrieve the maximum and current
|
|
40
|
+
size of the cache. When a cache is full, :meth:`Cache.__setitem__()`
|
|
41
|
+
calls :meth:`self.popitem()` repeatedly until there is enough room for
|
|
42
|
+
the item to be added.
|
|
43
43
|
|
|
44
44
|
.. note::
|
|
45
45
|
|
|
@@ -53,8 +53,9 @@ returns the size of a given `value`. The default implementation of
|
|
|
53
53
|
:meth:`getsizeof` returns :const:`1` irrespective of its argument,
|
|
54
54
|
making the cache's size equal to the number of its items, or
|
|
55
55
|
`len(cache)`. For convenience, all cache classes accept an optional
|
|
56
|
-
named constructor parameter `getsizeof`, which may specify a
|
|
57
|
-
|
|
56
|
+
named constructor parameter `getsizeof`, which may specify a callable
|
|
57
|
+
``getsizeof(value) -> int`` used to retrieve the size of an item's
|
|
58
|
+
value.
|
|
58
59
|
|
|
59
60
|
The values of a :class:`Cache` are mutable by default, as are e.g. the
|
|
60
61
|
values of a :class:`dict`. It is the user's responsibility to take
|
|
@@ -12,7 +12,7 @@ __all__ = (
|
|
|
12
12
|
"cachedmethod",
|
|
13
13
|
)
|
|
14
14
|
|
|
15
|
-
__version__ = "6.2.
|
|
15
|
+
__version__ = "6.2.6"
|
|
16
16
|
|
|
17
17
|
import collections
|
|
18
18
|
import collections.abc
|
|
@@ -540,6 +540,8 @@ class TTLCache(_TimedCache):
|
|
|
540
540
|
class TLRUCache(_TimedCache):
|
|
541
541
|
"""Time aware Least Recently Used (TLRU) cache implementation."""
|
|
542
542
|
|
|
543
|
+
__HEAP_CLEANUP_FACTOR = 2 # clean up the heap if size > N * len(items)
|
|
544
|
+
|
|
543
545
|
@functools.total_ordering
|
|
544
546
|
class _Item:
|
|
545
547
|
__slots__ = ("key", "expires", "removed")
|
|
@@ -625,7 +627,7 @@ class TLRUCache(_TimedCache):
|
|
|
625
627
|
items = self.__items
|
|
626
628
|
order = self.__order
|
|
627
629
|
# clean up the heap if too many items are marked as removed
|
|
628
|
-
if len(order) > len(items) *
|
|
630
|
+
if len(order) > len(items) * self.__HEAP_CLEANUP_FACTOR:
|
|
629
631
|
self.__order = order = [item for item in order if not item.removed]
|
|
630
632
|
heapq.heapify(order)
|
|
631
633
|
expired = []
|
|
@@ -24,6 +24,9 @@ class _UnboundTTLCache(TTLCache):
|
|
|
24
24
|
|
|
25
25
|
def _cache(cache, maxsize, typed):
|
|
26
26
|
def decorator(func):
|
|
27
|
+
# like functools.lru_cache, this has to be thread-safe;
|
|
28
|
+
# additionally, this also prevents cache stampede scenarios
|
|
29
|
+
# using a condition variable
|
|
27
30
|
key = keys.typedkey if typed else keys.hashkey
|
|
28
31
|
wrapper = cached(cache=cache, key=key, condition=Condition(), info=True)(func)
|
|
29
32
|
wrapper.cache_parameters = lambda: {"maxsize": maxsize, "typed": typed}
|
|
@@ -51,10 +51,13 @@ def methodkey(self, *args, **kwargs):
|
|
|
51
51
|
def typedkey(*args, **kwargs):
|
|
52
52
|
"""Return a typed cache key for the specified hashable arguments."""
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
if kwargs:
|
|
55
|
+
sorted_kwargs = tuple(sorted(kwargs.items()))
|
|
56
|
+
key = _HashedTuple(args + _kwmark + sorted_kwargs)
|
|
57
|
+
key += tuple(type(v) for _, v in sorted_kwargs)
|
|
58
|
+
else:
|
|
59
|
+
key = _HashedTuple(args)
|
|
55
60
|
key += tuple(type(v) for v in args)
|
|
56
|
-
# TODO: avoid iterating twice over kwargs
|
|
57
|
-
key += tuple(type(v) for _, v in sorted(kwargs.items()))
|
|
58
61
|
return key
|
|
59
62
|
|
|
60
63
|
|
|
@@ -98,9 +98,12 @@ class CacheTestMixin:
|
|
|
98
98
|
cache = self.Cache(maxsize=2)
|
|
99
99
|
|
|
100
100
|
cache.update({1: 1, 2: 2})
|
|
101
|
-
|
|
101
|
+
|
|
102
|
+
key, _ = cache.popitem()
|
|
103
|
+
self.assertIn(key, {1, 2})
|
|
102
104
|
self.assertEqual(1, len(cache))
|
|
103
|
-
|
|
105
|
+
key, _ = cache.popitem()
|
|
106
|
+
self.assertIn(key, {1, 2})
|
|
104
107
|
self.assertEqual(0, len(cache))
|
|
105
108
|
|
|
106
109
|
with self.assertRaises(KeyError):
|
|
@@ -21,7 +21,7 @@ class CacheKeysTest(unittest.TestCase):
|
|
|
21
21
|
self.assertEqual(key(1, 2, 3), key(1.0, 2.0, 3.0))
|
|
22
22
|
self.assertEqual(hash(key(1, 2, 3)), hash(key(1.0, 2.0, 3.0)))
|
|
23
23
|
|
|
24
|
-
def
|
|
24
|
+
def test_methodkey(self, key=cachetools.keys.methodkey):
|
|
25
25
|
# similar to hashkey(), but ignores its first positional argument
|
|
26
26
|
self.assertEqual(key("x"), key("y"))
|
|
27
27
|
self.assertEqual(hash(key("x")), hash(key("y")))
|
|
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
|