CacheToolsUtils 8.6__tar.gz → 9.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CacheToolsUtils
3
- Version: 8.6
3
+ Version: 9.1
4
4
  Summary: Cachetools Utilities
5
5
  Author-email: Fabien Coelho <cachetools.utils@coelho.net>
6
6
  License: CC0
@@ -51,7 +51,7 @@ Classes to add key prefix and stats to
51
51
  and other cache-related utils.
52
52
 
53
53
  ![Status](https://github.com/zx80/cachetools-utils/actions/workflows/cachetools-utils.yml/badge.svg?branch=main&style=flat)
54
- ![Tests](https://img.shields.io/badge/tests-17%20✓-success)
54
+ ![Tests](https://img.shields.io/badge/tests-21%20✓-success)
55
55
  ![Coverage](https://img.shields.io/badge/coverage-100%25-success)
56
56
  ![Issues](https://img.shields.io/github/issues/zx80/cachetools-utils?style=flat)
57
57
  ![Python](https://img.shields.io/badge/python-3-informational)
@@ -75,12 +75,13 @@ with `cachetools`.
75
75
  class for Memcached.
76
76
  - `DictCache` a very simple `dict` cache.
77
77
 
78
- ### Other wrappers to extend cache capabilities
78
+ ### Wrappers to extend cache capabilities
79
79
 
80
80
  - `PrefixedCache`, `PrefixedMemCached` and `PrefixedRedisCache` add a prefix to
81
81
  distinguish sources on a shared cache.
82
- - `StatsCache`, `StatsMemCached` and `StatsRedisCache` add a `hits()` method
83
- to report the cache hit rate.
82
+ - `StatsCache`, `MemCached` and `RedisCache` add a `hits` method
83
+ to report the cache hit rate, `stats` to report statistics and
84
+ `reset` to reset statistics.
84
85
  - `LockedCache` use a (thread) lock to control cache accesses.
85
86
  - `TwoLevelCache` allows to combine two caches.
86
87
  - `DebugCache` to trace cache calls using `logging`.
@@ -90,6 +91,7 @@ with `cachetools`.
90
91
  - `cached` decorator: a cachetools replacement which allows to test if a
91
92
  function result is in cache, and to delete such an entry.
92
93
  - `cacheFunctions` and `cacheMethods`: add caching to functions or methods.
94
+ - `json_key` and `hash_json_key`: JSON-based cache key serialization functions
93
95
 
94
96
  ## License
95
97
 
@@ -25,7 +25,8 @@ _NO_DEFAULT = object()
25
25
  class _MutMapMix:
26
26
  """Convenient MutableMapping Mixin, forward to _cache."""
27
27
 
28
- _cache: MutableMapping
28
+ # FIXME coverage reports this as missing with Python 3.14
29
+ _cache: MutableMapping # pragma: no cover
29
30
 
30
31
  def __contains__(self, key):
31
32
  return self._cache.__contains__(key)
@@ -69,9 +70,12 @@ class _KeyMutMapMix(_MutMapMix):
69
70
  class _StatsMix:
70
71
  """Convenient Mixin to forward stats methods to _cache."""
71
72
 
72
- def hits(self):
73
+ def hits(self) -> float|None:
73
74
  return self._cache.hits() # type: ignore
74
75
 
76
+ def stats(self) -> dict[str, Any]:
77
+ return self._cache.stats() # type: ignore
78
+
75
79
  def reset(self):
76
80
  return self._cache.reset() # type: ignore
77
81
 
@@ -102,7 +106,7 @@ class _RedisMix: # pragma: no cover
102
106
  # CACHETOOLS EXTENSIONS
103
107
  #
104
108
 
105
- class DebugCache(MutableMapping):
109
+ class DebugCache(_StatsMix, MutableMapping):
106
110
  """Debug class.
107
111
 
108
112
  :param cache: actual cache
@@ -241,14 +245,25 @@ class StatsCache(_MutMapMix, MutableMapping):
241
245
  self._cache = cache
242
246
  self.reset()
243
247
 
244
- def hits(self):
248
+ def hits(self) -> float:
245
249
  """Return the cache hit ratio."""
246
- return float(self._hits) / float(max(self._reads, 1))
250
+ return float(self._hits) / max(self._reads, 1)
247
251
 
248
252
  def reset(self):
249
253
  """Reset internal stats data."""
250
254
  self._reads, self._writes, self._dels, self._hits = 0, 0, 0, 0
251
255
 
256
+ def stats(self) -> dict[str, Any]:
257
+ """Return available stats data as dict."""
258
+ return {
259
+ "type": 1,
260
+ "reads": self._reads,
261
+ "writes": self._writes,
262
+ "dels": self._dels,
263
+ "hits": self.hits(),
264
+ "size": self._cache.__len__()
265
+ }
266
+
252
267
  def __getitem__(self, key):
253
268
  self._reads += 1
254
269
  res = self._cache.__getitem__(key)
@@ -324,6 +339,27 @@ class TwoLevelCache(_MutMapMix, MutableMapping):
324
339
  # NOTE not passed on cache2…
325
340
  return self._cache.clear()
326
341
 
342
+ def stats(self) -> dict[str, Any]:
343
+ data = {"type": 2}
344
+ try:
345
+ data["cache1"] = self._cache.stats() # type: ignore
346
+ except Exception:
347
+ data["cache1"] = {} # type: ignore
348
+ try:
349
+ data["cache2"] = self._cache2.stats() # type: ignore
350
+ except Exception:
351
+ data["cache2"] = {} # type: ignore
352
+ return data
353
+
354
+ def hits(self) -> float|None:
355
+ data = self.stats()
356
+ c1, c2 = data["cache1"], data["cache2"]
357
+ if (c1 and "type" in c1 and c1["type"] == 1 and
358
+ c2 and "type" in c2 and c2["type"] == 1):
359
+ return float(c1["hits"] + c2["hits"]) / max(c1["reads"] + c2["reads"], 1)
360
+ # else
361
+ return None
362
+
327
363
  def reset(self): # pragma: no cover
328
364
  self._cache.reset() # type: ignore
329
365
  self._cache2.reset() # type: ignore
@@ -415,6 +451,38 @@ def cacheFunctions(
415
451
  globs[fun] = cached(cache=gen(cache, prefix))(f)
416
452
 
417
453
 
454
+ # JSON-based key function
455
+ # NOTE obviously this only works if parameters are json-serializable…
456
+ def json_key(*args, **kwargs):
457
+ if kwargs:
458
+ return json.dumps({"*": args, "**": kwargs}, sort_keys=True)
459
+ else: # array
460
+ return json.dumps(args)
461
+
462
+
463
+ # Hmmm…
464
+ class _HashJsonKey:
465
+ """A cache key with a persistant hash value."""
466
+
467
+ def __init__(self, *args, **kwargs):
468
+ self._hashed = None
469
+ self._args = args
470
+ self._kwargs = kwargs
471
+ self._key = json_key(*args, **kwargs)
472
+
473
+ def __hash__(self):
474
+ if self._hashed is None:
475
+ self._hashed = self._key.__hash__()
476
+ return self._hashed
477
+
478
+ def __str__(self):
479
+ return self._key
480
+
481
+
482
+ def hash_json_key(*args, **kwargs):
483
+ return _HashJsonKey(*args, **kwargs)
484
+
485
+
418
486
  #
419
487
  # MEMCACHED
420
488
  #
@@ -586,6 +654,9 @@ class RedisCache(MutableMapping):
586
654
  """Return redis informations."""
587
655
  return self._cache.info(*args, **kwargs)
588
656
 
657
+ def stats(self) -> dict[str, Any]:
658
+ return self.info(section="stats")
659
+
589
660
  def dbsize(self, *args, **kwargs):
590
661
  """Return redis database size."""
591
662
  return self._cache.dbsize(*args, **kwargs)
@@ -606,9 +677,9 @@ class RedisCache(MutableMapping):
606
677
  del self[index]
607
678
 
608
679
  # stats
609
- def hits(self):
680
+ def hits(self) -> float:
610
681
  """Return cache hits."""
611
- stats = self.info(section="stats")
682
+ stats = self.stats()
612
683
  return float(stats["keyspace_hits"]) / (
613
684
  stats["keyspace_hits"] + stats["keyspace_misses"]
614
685
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: CacheToolsUtils
3
- Version: 8.6
3
+ Version: 9.1
4
4
  Summary: Cachetools Utilities
5
5
  Author-email: Fabien Coelho <cachetools.utils@coelho.net>
6
6
  License: CC0
@@ -51,7 +51,7 @@ Classes to add key prefix and stats to
51
51
  and other cache-related utils.
52
52
 
53
53
  ![Status](https://github.com/zx80/cachetools-utils/actions/workflows/cachetools-utils.yml/badge.svg?branch=main&style=flat)
54
- ![Tests](https://img.shields.io/badge/tests-17%20✓-success)
54
+ ![Tests](https://img.shields.io/badge/tests-21%20✓-success)
55
55
  ![Coverage](https://img.shields.io/badge/coverage-100%25-success)
56
56
  ![Issues](https://img.shields.io/github/issues/zx80/cachetools-utils?style=flat)
57
57
  ![Python](https://img.shields.io/badge/python-3-informational)
@@ -75,12 +75,13 @@ with `cachetools`.
75
75
  class for Memcached.
76
76
  - `DictCache` a very simple `dict` cache.
77
77
 
78
- ### Other wrappers to extend cache capabilities
78
+ ### Wrappers to extend cache capabilities
79
79
 
80
80
  - `PrefixedCache`, `PrefixedMemCached` and `PrefixedRedisCache` add a prefix to
81
81
  distinguish sources on a shared cache.
82
- - `StatsCache`, `StatsMemCached` and `StatsRedisCache` add a `hits()` method
83
- to report the cache hit rate.
82
+ - `StatsCache`, `MemCached` and `RedisCache` add a `hits` method
83
+ to report the cache hit rate, `stats` to report statistics and
84
+ `reset` to reset statistics.
84
85
  - `LockedCache` use a (thread) lock to control cache accesses.
85
86
  - `TwoLevelCache` allows to combine two caches.
86
87
  - `DebugCache` to trace cache calls using `logging`.
@@ -90,6 +91,7 @@ with `cachetools`.
90
91
  - `cached` decorator: a cachetools replacement which allows to test if a
91
92
  function result is in cache, and to delete such an entry.
92
93
  - `cacheFunctions` and `cacheMethods`: add caching to functions or methods.
94
+ - `json_key` and `hash_json_key`: JSON-based cache key serialization functions
93
95
 
94
96
  ## License
95
97
 
@@ -7,7 +7,7 @@ Classes to add key prefix and stats to
7
7
  and other cache-related utils.
8
8
 
9
9
  ![Status](https://github.com/zx80/cachetools-utils/actions/workflows/cachetools-utils.yml/badge.svg?branch=main&style=flat)
10
- ![Tests](https://img.shields.io/badge/tests-17%20✓-success)
10
+ ![Tests](https://img.shields.io/badge/tests-21%20✓-success)
11
11
  ![Coverage](https://img.shields.io/badge/coverage-100%25-success)
12
12
  ![Issues](https://img.shields.io/github/issues/zx80/cachetools-utils?style=flat)
13
13
  ![Python](https://img.shields.io/badge/python-3-informational)
@@ -31,12 +31,13 @@ with `cachetools`.
31
31
  class for Memcached.
32
32
  - `DictCache` a very simple `dict` cache.
33
33
 
34
- ### Other wrappers to extend cache capabilities
34
+ ### Wrappers to extend cache capabilities
35
35
 
36
36
  - `PrefixedCache`, `PrefixedMemCached` and `PrefixedRedisCache` add a prefix to
37
37
  distinguish sources on a shared cache.
38
- - `StatsCache`, `StatsMemCached` and `StatsRedisCache` add a `hits()` method
39
- to report the cache hit rate.
38
+ - `StatsCache`, `MemCached` and `RedisCache` add a `hits` method
39
+ to report the cache hit rate, `stats` to report statistics and
40
+ `reset` to reset statistics.
40
41
  - `LockedCache` use a (thread) lock to control cache accesses.
41
42
  - `TwoLevelCache` allows to combine two caches.
42
43
  - `DebugCache` to trace cache calls using `logging`.
@@ -46,6 +47,7 @@ with `cachetools`.
46
47
  - `cached` decorator: a cachetools replacement which allows to test if a
47
48
  function result is in cache, and to delete such an entry.
48
49
  - `cacheFunctions` and `cacheMethods`: add caching to functions or methods.
50
+ - `json_key` and `hash_json_key`: JSON-based cache key serialization functions
49
51
 
50
52
  ## License
51
53
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "CacheToolsUtils"
7
- version = "8.6"
7
+ version = "9.1"
8
8
  authors = [ { name = "Fabien Coelho", email = "cachetools.utils@coelho.net" } ]
9
9
  description = "Cachetools Utilities"
10
10
  readme = "README.md"
File without changes
File without changes
File without changes