Opened 6 years ago
Last modified 6 years ago
#31140 closed Bug
Caching of dict containing django.utils.safestring.SafeText objects fails with bmemcached. — at Version 1
| Reported by: | Hugo Rodger-Brown | Owned by: | nobody |
|---|---|---|---|
| Component: | Core (Cache system) | Version: | 2.2 |
| Severity: | Normal | Keywords: | cache bmemcached |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Not sure if this is a Django issue per se. but we have recently started having an issue where cache.set is failing where we have certain SafeText objects inside a dict. (Issue has already
The underlying exception is raised within bmemcached, but posting here in case someone else has had a similar issue, and any insight.
Expected behaviour - object can be cached:
>>> from django.utils.safestring import SafeString
>>> from django.core.cache import cache
>>> cache.set("test", SafeString("foo"))
>>> cache.set("test", SafeString("£"))
Actual outcome - cache.set fails with a recursion error when the value being stored is a dict that contains a SafeText value.
>>> from django.utils.safestring import SafeString
>>> from django.core.cache import cache
>>> cache.set("test", {"foo": SafeString("£")})
Traceback (most recent call last):
File "/python3.7/site-packages/django/core/cache/backends/memcached.py", line 78, in set
if not self._cache.set(key, value, self.get_backend_timeout(timeout)):
File "/python3.7/site-packages/bmemcached/client/replicating.py", line 112, in set
returns.append(server.set(key, value, time, compress_level=compress_level))
File "/python3.7/site-packages/bmemcached/protocol.py", line 604, in set
return self._set_add_replace('set', key, value, time, compress_level=compress_level)
File "/python3.7/site-packages/bmemcached/protocol.py", line 561, in _set_add_replace
flags, value = self.serialize(value, compress_level=compress_level)
File "/python3.7/site-packages/bmemcached/protocol.py", line 347, in serialize
pickler.dump(value)
File "/python3.7/copyreg.py", line 66, in _reduce_ex
state = base(self)
RecursionError: maximum recursion depth exceeded while getting the str of an object
Running on Python 3.7, Django 2.2
Configuration:
CACHES = {
"default": {
"BACKEND": "django_bmemcached.memcached.BMemcached",
"BINARY": True,
"OPTIONS": {
"no_block": True,
"tcp_nodelay": True,
"tcp_keepalive": True,
"remove_failed": 4,
"retry_timeout": 2,
"dead_timeout": 10,
"_poll_timeout": 2000,
},
},
}
Can't be sure, but I think it's the internal implementation of
SafeTextand howbmemcachedis serializing that is causing the problem: https://github.com/django/django/blob/master/django/utils/safestring.py#L36-L37