cachetools 7.0.3__tar.gz → 7.0.4__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.
Files changed (33) hide show
  1. {cachetools-7.0.3 → cachetools-7.0.4}/CHANGELOG.rst +8 -0
  2. {cachetools-7.0.3/src/cachetools.egg-info → cachetools-7.0.4}/PKG-INFO +1 -1
  3. {cachetools-7.0.3 → cachetools-7.0.4}/docs/index.rst +15 -8
  4. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools/__init__.py +3 -3
  5. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools/_cachedmethod.py +4 -4
  6. {cachetools-7.0.3 → cachetools-7.0.4/src/cachetools.egg-info}/PKG-INFO +1 -1
  7. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_cachedmethod.py +18 -6
  8. {cachetools-7.0.3 → cachetools-7.0.4}/LICENSE +0 -0
  9. {cachetools-7.0.3 → cachetools-7.0.4}/MANIFEST.in +0 -0
  10. {cachetools-7.0.3 → cachetools-7.0.4}/README.rst +0 -0
  11. {cachetools-7.0.3 → cachetools-7.0.4}/docs/conf.py +0 -0
  12. {cachetools-7.0.3 → cachetools-7.0.4}/pyproject.toml +0 -0
  13. {cachetools-7.0.3 → cachetools-7.0.4}/setup.cfg +0 -0
  14. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools/_cached.py +0 -0
  15. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools/func.py +0 -0
  16. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools/keys.py +0 -0
  17. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools.egg-info/SOURCES.txt +0 -0
  18. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools.egg-info/dependency_links.txt +0 -0
  19. {cachetools-7.0.3 → cachetools-7.0.4}/src/cachetools.egg-info/top_level.txt +0 -0
  20. {cachetools-7.0.3 → cachetools-7.0.4}/tests/__init__.py +0 -0
  21. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_cache.py +0 -0
  22. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_cached.py +0 -0
  23. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_classmethod.py +0 -0
  24. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_fifo.py +0 -0
  25. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_func.py +0 -0
  26. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_keys.py +0 -0
  27. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_lfu.py +0 -0
  28. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_lru.py +0 -0
  29. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_rr.py +0 -0
  30. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_threading.py +0 -0
  31. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_tlru.py +0 -0
  32. {cachetools-7.0.3 → cachetools-7.0.4}/tests/test_ttl.py +0 -0
  33. {cachetools-7.0.3 → cachetools-7.0.4}/tox.ini +0 -0
@@ -1,3 +1,11 @@
1
+ v7.0.4 (2026-03-08)
2
+ ===================
3
+
4
+ - Fix and properly document ``@cachedmethod.cache_key`` behavior.
5
+
6
+ - Minor documentation improvements.
7
+
8
+
1
9
  v7.0.3 (2026-03-05)
2
10
  ===================
3
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachetools
3
- Version: 7.0.3
3
+ Version: 7.0.4
4
4
  Summary: Extensible memoizing collections and decorators
5
5
  Author-email: Thomas Kemmer <tkemmer@computer.org>
6
6
  Maintainer-email: Thomas Kemmer <tkemmer@computer.org>
@@ -370,13 +370,10 @@ often called with the same arguments:
370
370
  with urllib.request.urlopen(url) as s:
371
371
  return s.read()
372
372
 
373
- # make sure access to cache is synchronized
373
+ # remove (pop) an individual cached PEP from the cache
374
+ key = get_pep.cache_key(42)
374
375
  with get_pep.cache_lock:
375
- get_pep.cache.clear()
376
-
377
- # always use the key function for accessing cache items
378
- with get_pep.cache_lock:
379
- get_pep.cache.pop(get_pep.cache_key(42), None)
376
+ get_pep.cache.pop(key, None)
380
377
 
381
378
  For the common use case of clearing or invalidating the cache, the
382
379
  decorator also provides a :func:`cache_clear()` function which
@@ -582,6 +579,15 @@ often called with the same arguments:
582
579
  >>> peps.get.cache_info()
583
580
  CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
584
581
 
582
+ >>> # remove an individual cached PEP from the cache
583
+ >>> key = peps.get.cache_key(320)
584
+ >>> with peps.get.cache_lock:
585
+ ... del peps.get.cache[key]
586
+
587
+ >>> peps.get.cache_info()
588
+ CacheInfo(hits=3, misses=8, maxsize=32, currsize=7)
589
+
590
+ >>> # remove all cached PEPs and clear cache info
585
591
  >>> peps.get.cache_clear()
586
592
 
587
593
  >>> peps.get.cache_info()
@@ -590,8 +596,9 @@ often called with the same arguments:
590
596
  The `key` function will be called as `key(self, *args, **kwargs)`
591
597
  to retrieve a suitable cache key. Note that the default `key`
592
598
  function, :func:`cachetools.keys.methodkey`, ignores its first
593
- argument, i.e. :const:`self`. This has mostly historical reasons,
594
- but also ensures that :const:`self` does not have to be hashable.
599
+ implicit argument, i.e. :const:`self`. This has mostly historical
600
+ reasons, but also ensures that :const:`self` does not have to be
601
+ hashable.
595
602
 
596
603
  You may provide a different `key` function,
597
604
  e.g. :func:`cachetools.keys.hashkey`, if you need :const:`self` to
@@ -12,7 +12,7 @@ __all__ = (
12
12
  "cachedmethod",
13
13
  )
14
14
 
15
- __version__ = "7.0.3"
15
+ __version__ = "7.0.4"
16
16
 
17
17
  import collections
18
18
  import collections.abc
@@ -748,8 +748,8 @@ def cached(cache, key=keys.hashkey, lock=None, condition=None, info=False):
748
748
 
749
749
 
750
750
  def cachedmethod(cache, key=keys.methodkey, lock=None, condition=None, info=False):
751
- """Decorator to wrap a class or instance method with a memoizing
752
- callable that saves results in a cache.
751
+ """Decorator to wrap a method with a memoizing callable that saves
752
+ results in a cache.
753
753
 
754
754
  """
755
755
  from ._cachedmethod import _wrapper
@@ -48,7 +48,7 @@ class _WrapperBase:
48
48
 
49
49
  @property
50
50
  def cache_key(self):
51
- return self.__key
51
+ return functools.partial(self.__key, self._obj)
52
52
 
53
53
  @property
54
54
  def cache_lock(self):
@@ -153,7 +153,7 @@ def _condition_info(method, cache, key, lock, cond, info):
153
153
  cache = self.cache
154
154
  lock = self.cache_lock
155
155
  cond = self.cache_condition
156
- key = self.cache_key(self._obj, *args, **kwargs)
156
+ key = self.cache_key(*args, **kwargs)
157
157
 
158
158
  with lock:
159
159
  cond.wait_for(lambda: key not in self.__pending)
@@ -199,7 +199,7 @@ def _locked_info(method, cache, key, lock, info):
199
199
  def __call__(self, *args, **kwargs):
200
200
  cache = self.cache
201
201
  lock = self.cache_lock
202
- key = self.cache_key(self._obj, *args, **kwargs)
202
+ key = self.cache_key(*args, **kwargs)
203
203
  with lock:
204
204
  try:
205
205
  result = cache[key]
@@ -238,7 +238,7 @@ def _unlocked_info(method, cache, key, info):
238
238
 
239
239
  def __call__(self, *args, **kwargs):
240
240
  cache = self.cache
241
- key = self.cache_key(self._obj, *args, **kwargs)
241
+ key = self.cache_key(*args, **kwargs)
242
242
  try:
243
243
  result = cache[key]
244
244
  self.__hits += 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachetools
3
- Version: 7.0.3
3
+ Version: 7.0.4
4
4
  Summary: Extensible memoizing collections and decorators
5
5
  Author-email: Thomas Kemmer <tkemmer@computer.org>
6
6
  Maintainer-email: Thomas Kemmer <tkemmer@computer.org>
@@ -370,24 +370,26 @@ class MethodDecoratorTestMixin:
370
370
  cached = Cached(cache)
371
371
 
372
372
  self.assertIs(cached.get.cache, cache)
373
- self.assertIs(cached.get.cache_key, keys.methodkey)
374
373
  self.assertIs(cached.get.cache_lock, None)
375
374
  self.assertIs(cached.get.cache_condition, None)
375
+ self.assertEqual(cached.get.cache_key(42), keys.methodkey(cached, 42))
376
376
 
377
377
  self.assertIs(cached.get_lock.cache, cache)
378
- self.assertIs(cached.get_lock.cache_key, keys.methodkey)
379
378
  self.assertIs(cached.get_lock.cache_lock, cached.lock)
380
379
  self.assertIs(cached.get_lock.cache_condition, None)
380
+ self.assertEqual(cached.get_lock.cache_key(42), keys.methodkey(cached, 42))
381
381
 
382
382
  self.assertIs(cached.get_cond.cache, cache)
383
- self.assertIs(cached.get_cond.cache_key, keys.methodkey)
384
383
  self.assertIs(cached.get_cond.cache_lock, cached.cond)
385
384
  self.assertIs(cached.get_cond.cache_condition, cached.cond)
385
+ self.assertEqual(cached.get_cond.cache_key(42), keys.methodkey(cached, 42))
386
386
 
387
387
  self.assertIs(cached.get_lock_cond_info.cache, cache)
388
- self.assertIs(cached.get_lock_cond_info.cache_key, keys.methodkey)
389
388
  self.assertIs(cached.get_lock_cond_info.cache_lock, cached.lock)
390
389
  self.assertIs(cached.get_lock_cond_info.cache_condition, cached.cond)
390
+ self.assertEqual(
391
+ cached.get_lock_cond_info.cache_key(42), keys.methodkey(cached, 42)
392
+ )
391
393
 
392
394
  def test_decorator_clear(self):
393
395
  cache = self.cache(2)
@@ -603,15 +605,25 @@ class CacheMethodTest(unittest.TestCase, MethodDecoratorTestMixin):
603
605
  self.assertEqual(cached1.get_info.cache_info(), (0, 0, 2, 0))
604
606
  self.assertEqual(cached2.get_info.cache_info(), (0, 0, 2, 0))
605
607
 
608
+ # hits/misses are counted by instance
606
609
  self.assertEqual(cached1.get_info(0), 0)
607
-
608
610
  self.assertEqual(cached1.get_info.cache_info(), (0, 1, 2, 1))
609
611
  self.assertEqual(cached2.get_info.cache_info(), (0, 0, 2, 1))
610
612
 
613
+ # default methodkey discards "self", so results will be shared
614
+ # across instances
611
615
  self.assertEqual(cached2.get_info(0), 0)
612
-
613
616
  self.assertEqual(cached1.get_info.cache_info(), (0, 1, 2, 1))
614
617
  self.assertEqual(cached2.get_info.cache_info(), (1, 0, 2, 1))
618
+ self.assertEqual(cached1.get_info(0), 0)
619
+ self.assertEqual(cached1.get_info.cache_info(), (1, 1, 2, 1))
620
+ self.assertEqual(cached2.get_info.cache_info(), (1, 0, 2, 1))
621
+ self.assertEqual(cached1.get_info(1), 1)
622
+ self.assertEqual(cached1.get_info.cache_info(), (1, 2, 2, 2))
623
+ self.assertEqual(cached2.get_info.cache_info(), (1, 0, 2, 2))
624
+ self.assertEqual(cached2.get_info(1), 1)
625
+ self.assertEqual(cached1.get_info.cache_info(), (1, 2, 2, 2))
626
+ self.assertEqual(cached2.get_info.cache_info(), (2, 0, 2, 2))
615
627
 
616
628
  def test_value_too_large(self):
617
629
  cache = self.cache(1, getsizeof=lambda x: x)
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