From 3d82da3684aefa58176648302fdeea933ccc0ab0 Mon Sep 17 00:00:00 2001 From: Kotesh Kumar Yelamati Date: Fri, 3 Jul 2026 12:28:32 -0400 Subject: [PATCH] fix: LRUCache.get() and __getitem__() fail for cached None values When a cached value is None, LRUCache.get() incorrectly returns the default instead of the cached None, and LRUCache.__getitem__() raises KeyError even though the key exists. Root cause: both methods check `if value is not None` / `if value is None` to detect cache misses, but this fails when None is a legitimate cached value. Fix: check `if key not in self.cache` instead, mirroring the fix applied to LRUCache.set() in PR #597. Reproducer: cache = LRUCache(capacity=5) cache['key'] = None assert cache.get('key', 'default') == None # fails before fix assert cache['key'] is None # raises KeyError before fix --- tinydb/utils.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tinydb/utils.py b/tinydb/utils.py index 85a224cc..e88b1c08 100644 --- a/tinydb/utils.py +++ b/tinydb/utils.py @@ -78,9 +78,10 @@ def __delitem__(self, key: K) -> None: del self.cache[key] def __getitem__(self, key) -> V: - value = self.get(key) - if value is None: + if key not in self.cache: raise KeyError(key) + value = self.cache[key] + self.cache.move_to_end(key, last=True) return value @@ -88,14 +89,12 @@ def __iter__(self) -> Iterator[K]: return iter(self.cache) def get(self, key: K, default: Optional[D] = None) -> Optional[Union[V, D]]: - value = self.cache.get(key) + if key not in self.cache: + return default + value = self.cache[key] + self.cache.move_to_end(key, last=True) - if value is not None: - self.cache.move_to_end(key, last=True) - - return value - - return default + return value def set(self, key: K, value: V): if key in self.cache: