[4.0.x] Fixed #33361 -- Fixed Redis cache backend crash on booleans.
Backport of 2f33217ea2
from main
This commit is contained in:
parent
cc5bbd447b
commit
3b03bce122
|
@ -10,8 +10,14 @@ from django.utils.module_loading import import_string
|
||||||
|
|
||||||
|
|
||||||
class RedisSerializer(PickleSerializer):
|
class RedisSerializer(PickleSerializer):
|
||||||
|
"""
|
||||||
|
Similar to PickSerializer, except integers are serialized as native Redis
|
||||||
|
integers for better incr() and decr() atomicity.
|
||||||
|
"""
|
||||||
def dumps(self, obj):
|
def dumps(self, obj):
|
||||||
if isinstance(obj, int):
|
# Only skip pickling for integers, a int subclasses as bool should be
|
||||||
|
# pickled.
|
||||||
|
if type(obj) is int:
|
||||||
return obj
|
return obj
|
||||||
return super().dumps(obj)
|
return super().dumps(obj)
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,6 @@ Bugfixes
|
||||||
* Fixed a regression in Django 4.0 that caused a crash of
|
* Fixed a regression in Django 4.0 that caused a crash of
|
||||||
:meth:`~django.test.SimpleTestCase.assertFormsetError` on a formset named
|
:meth:`~django.test.SimpleTestCase.assertFormsetError` on a formset named
|
||||||
``form`` (:ticket:`33346`).
|
``form`` (:ticket:`33346`).
|
||||||
|
|
||||||
|
* Fixed a bug in Django 4.0 that caused a crash on booleans with the
|
||||||
|
``RedisCache`` backend (:ticket:`33361`).
|
||||||
|
|
|
@ -411,17 +411,20 @@ class BaseCacheTests:
|
||||||
|
|
||||||
def test_data_types(self):
|
def test_data_types(self):
|
||||||
# Many different data types can be cached
|
# Many different data types can be cached
|
||||||
stuff = {
|
tests = {
|
||||||
'string': 'this is a string',
|
'string': 'this is a string',
|
||||||
'int': 42,
|
'int': 42,
|
||||||
|
'bool': True,
|
||||||
'list': [1, 2, 3, 4],
|
'list': [1, 2, 3, 4],
|
||||||
'tuple': (1, 2, 3, 4),
|
'tuple': (1, 2, 3, 4),
|
||||||
'dict': {'A': 1, 'B': 2},
|
'dict': {'A': 1, 'B': 2},
|
||||||
'function': f,
|
'function': f,
|
||||||
'class': C,
|
'class': C,
|
||||||
}
|
}
|
||||||
cache.set("stuff", stuff)
|
for key, value in tests.items():
|
||||||
self.assertEqual(cache.get("stuff"), stuff)
|
with self.subTest(key=key):
|
||||||
|
cache.set(key, value)
|
||||||
|
self.assertEqual(cache.get(key), value)
|
||||||
|
|
||||||
def test_cache_read_for_model_instance(self):
|
def test_cache_read_for_model_instance(self):
|
||||||
# Don't want fields with callable as default to be called on cache read
|
# Don't want fields with callable as default to be called on cache read
|
||||||
|
@ -1785,6 +1788,11 @@ class RedisCacheTests(BaseCacheTests, TestCase):
|
||||||
def test_get_client(self):
|
def test_get_client(self):
|
||||||
self.assertIsInstance(cache._cache.get_client(), self.lib.Redis)
|
self.assertIsInstance(cache._cache.get_client(), self.lib.Redis)
|
||||||
|
|
||||||
|
def test_serializer_dumps(self):
|
||||||
|
self.assertEqual(cache._cache._serializer.dumps(123), 123)
|
||||||
|
self.assertIsInstance(cache._cache._serializer.dumps(True), bytes)
|
||||||
|
self.assertIsInstance(cache._cache._serializer.dumps('abc'), bytes)
|
||||||
|
|
||||||
|
|
||||||
class FileBasedCachePathLibTests(FileBasedCacheTests):
|
class FileBasedCachePathLibTests(FileBasedCacheTests):
|
||||||
def mkdtemp(self):
|
def mkdtemp(self):
|
||||||
|
|
Loading…
Reference in New Issue