From 66880e4cd128ea81ae53ac6f292f00c563521009 Mon Sep 17 00:00:00 2001 From: Malcolm Box Date: Fri, 9 May 2014 11:23:28 +0100 Subject: [PATCH] Fixed #22606 -- Locmemcache has_key() failed for infinite cache expiry Refactored cache expiry logic for Locmemcache to make consistent across all places where accessed, and correctly handle None as expiry time. --- django/core/cache/backends/locmem.py | 17 +++++++++-------- tests/cache/tests.py | 2 ++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py index aba8b61a4de..7c2609c2373 100644 --- a/django/core/cache/backends/locmem.py +++ b/django/core/cache/backends/locmem.py @@ -29,8 +29,7 @@ class LocMemCache(BaseCache): self.validate_key(key) pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) with self._lock.writer(): - exp = self._expire_info.get(key, 0) - if exp is not None and exp <= time.time(): + if self._has_expired(key): self._set(key, pickled, timeout) return True return False @@ -40,8 +39,7 @@ class LocMemCache(BaseCache): self.validate_key(key) pickled = None with self._lock.reader(): - exp = self._expire_info.get(key, 0) - if exp is None or exp > time.time(): + if not self._has_expired(key): pickled = self._cache[key] if pickled is not None: try: @@ -85,10 +83,7 @@ class LocMemCache(BaseCache): key = self.make_key(key, version=version) self.validate_key(key) with self._lock.reader(): - exp = self._expire_info.get(key) - if exp is None: - return False - elif exp > time.time(): + if not self._has_expired(key): return True with self._lock.writer(): @@ -99,6 +94,12 @@ class LocMemCache(BaseCache): pass return False + def _has_expired(self, key): + exp = self._expire_info.get(key, -1) + if exp is None or exp > time.time(): + return False + return True + def _cull(self): if self._cull_frequency == 0: self.clear() diff --git a/tests/cache/tests.py b/tests/cache/tests.py index 8dbdb33ca9c..6e0f755477d 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -285,6 +285,8 @@ class BaseCacheTests(object): cache.set("hello1", "goodbye1") self.assertEqual(cache.has_key("hello1"), True) self.assertEqual(cache.has_key("goodbye1"), False) + cache.set("no_expiry", "here", None) + self.assertEqual(cache.has_key("no_expiry"), True) def test_in(self): # The in operator can be used to inspect cache contents