Commit 8e838d9c authored by Emre Yilmaz's avatar Emre Yilmaz Committed by Tim Graham
Browse files

Fixed #25840 -- Fixed BaseCache.get_or_set() on the DummyCache backend.

This also fixes a possible data eviction race condition between
setting and getting a key. Another thread could remove the key
before get_and_set() accesses it again. In this case, now the
default value will be returned instead of None.
parent 25f5b5c1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -165,7 +165,7 @@ class BaseCache(object):
                default = default()
            val = self.add(key, default, timeout=timeout, version=version)
            if val:
                return self.get(key, version=version)
                return self.get(key, default, version)
        return val

    def has_key(self, key, version=None):
+2 −1
Original line number Diff line number Diff line
@@ -9,4 +9,5 @@ Django 1.9.1 fixes several bugs in 1.9.
Bugfixes
========

* ...
* Fixed ``BaseCache.get_or_set()`` with the ``DummyCache`` backend
  (:ticket:`25840`).
+9 −0
Original line number Diff line number Diff line
@@ -202,6 +202,15 @@ class DummyCacheTests(SimpleTestCase):
        self.assertRaises(ValueError, cache.decr_version, 'answer')
        self.assertRaises(ValueError, cache.decr_version, 'does_not_exist')

    def test_get_or_set(self):
        self.assertEqual(cache.get_or_set('mykey', 'default'), 'default')

    def test_get_or_set_callable(self):
        def my_callable():
            return 'default'

        self.assertEqual(cache.get_or_set('mykey', my_callable), 'default')


def custom_key_func(key, key_prefix, version):
    "A customized cache key function"