Fixed #26792 -- Allowed None for the value of cache.get_or_set().

This commit is contained in:
Dmitry S..ky / skype: dvska-at-skype 2016-06-22 21:28:43 +03:00 committed by Tim Graham
parent ee2f0f311a
commit 82be474efa
2 changed files with 13 additions and 6 deletions

View File

@ -147,7 +147,7 @@ class BaseCache(object):
d[k] = val d[k] = val
return d return d
def get_or_set(self, key, default=None, timeout=DEFAULT_TIMEOUT, version=None): def get_or_set(self, key, default, timeout=DEFAULT_TIMEOUT, version=None):
""" """
Fetch a given key from the cache. If the key does not exist, Fetch a given key from the cache. If the key does not exist,
the key is added and set to the default value. The default value can the key is added and set to the default value. The default value can
@ -156,10 +156,8 @@ class BaseCache(object):
Return the value of the key stored or retrieved. Return the value of the key stored or retrieved.
""" """
if default is None:
raise ValueError('You need to specify a value.')
val = self.get(key, version=version) val = self.get(key, version=version)
if val is None: if val is None and default is not None:
if callable(default): if callable(default):
default = default() default = default()
self.add(key, default, timeout=timeout, version=version) self.add(key, default, timeout=timeout, version=version)

13
tests/cache/tests.py vendored
View File

@ -213,12 +213,14 @@ class DummyCacheTests(SimpleTestCase):
def test_get_or_set(self): def test_get_or_set(self):
self.assertEqual(cache.get_or_set('mykey', 'default'), 'default') self.assertEqual(cache.get_or_set('mykey', 'default'), 'default')
self.assertEqual(cache.get_or_set('mykey', None), None)
def test_get_or_set_callable(self): def test_get_or_set_callable(self):
def my_callable(): def my_callable():
return 'default' return 'default'
self.assertEqual(cache.get_or_set('mykey', my_callable), 'default') self.assertEqual(cache.get_or_set('mykey', my_callable), 'default')
self.assertEqual(cache.get_or_set('mykey', my_callable()), 'default')
def custom_key_func(key, key_prefix, version): def custom_key_func(key, key_prefix, version):
@ -918,18 +920,25 @@ class BaseCacheTests(object):
self.assertIsNone(cache.get('projector')) self.assertIsNone(cache.get('projector'))
self.assertEqual(cache.get_or_set('projector', 42), 42) self.assertEqual(cache.get_or_set('projector', 42), 42)
self.assertEqual(cache.get('projector'), 42) self.assertEqual(cache.get('projector'), 42)
self.assertEqual(cache.get_or_set('null', None), None)
def test_get_or_set_callable(self): def test_get_or_set_callable(self):
def my_callable(): def my_callable():
return 'value' return 'value'
self.assertEqual(cache.get_or_set('mykey', my_callable), 'value') self.assertEqual(cache.get_or_set('mykey', my_callable), 'value')
self.assertEqual(cache.get_or_set('mykey', my_callable()), 'value')
def test_get_or_set_version(self): def test_get_or_set_version(self):
msg = (
"get_or_set() missing 1 required positional argument: 'default'"
if six.PY3
else 'get_or_set() takes at least 3 arguments'
)
cache.get_or_set('brian', 1979, version=2) cache.get_or_set('brian', 1979, version=2)
with self.assertRaisesMessage(ValueError, 'You need to specify a value.'): with self.assertRaisesMessage(TypeError, msg):
cache.get_or_set('brian') cache.get_or_set('brian')
with self.assertRaisesMessage(ValueError, 'You need to specify a value.'): with self.assertRaisesMessage(TypeError, msg):
cache.get_or_set('brian', version=1) cache.get_or_set('brian', version=1)
self.assertIsNone(cache.get('brian', version=1)) self.assertIsNone(cache.get('brian', version=1))
self.assertEqual(cache.get_or_set('brian', 42, version=1), 42) self.assertEqual(cache.get_or_set('brian', 42, version=1), 42)