I've only tested this with Django 2.2 and python 3.7.5.
When attempting to use the thumbnail templatetag, specifying anchor='c' causes the template to render and cause an infinite recursion error. I've traced this down to the pickling logic to come up with the hash for the cache filename. The pickler includes the anchor value which is a SafeString instance which apparently has fits when pickled. It has to do with SafeString being a subclass of str, but I don't know enough to know why.
One fix would be to check if the kwarg to the templatetag includes the anchor, if it does, convert it to a regular string. However, that looks to be a really ugly hack.
The core problem of SafeString not being able to be pickled properly can be verified with:
from copy import copy
from hashlib import md5
from pickle import Pickler
from io import BytesIO
def pickle(obj):
file = BytesIO()
Pickler(file, 0).dump(obj)
return md5(file.getvalue()).hexdigest()
# Copied from Django's source
class SafeData:
def __html__(self):
"""
Return the html representation of a string for interoperability.
This allows other template engines to understand Django's SafeData.
"""
return self
class SafeText(str, SafeData):
"""
A str subclass that has been specifically marked as "safe" for HTML output
purposes.
"""
def __add__(self, rhs):
"""
Concatenating a safe string with another safe bytestring or
safe string is safe. Otherwise, the result is no longer safe.
"""
t = super().__add__(rhs)
if isinstance(rhs, SafeData):
return SafeText(t)
return t
def __str__(self):
return self
SafeString = SafeText
x = 'hello'
safe = SafeString(x)
pickle(x)
pickle(safe)
Changing the protocol on the pickler to 3 (the default for python3) does seem to resolve the issue.
I've only tested this with Django 2.2 and python 3.7.5.
When attempting to use the thumbnail templatetag, specifying
anchor='c'
causes the template to render and cause an infinite recursion error. I've traced this down to the pickling logic to come up with the hash for the cache filename. The pickler includes the anchor value which is aSafeString
instance which apparently has fits when pickled. It has to do with SafeString being a subclass ofstr
, but I don't know enough to know why.One fix would be to check if the kwarg to the templatetag includes the anchor, if it does, convert it to a regular string. However, that looks to be a really ugly hack.
The core problem of
SafeString
not being able to be pickled properly can be verified with:Changing the protocol on the pickler to 3 (the default for python3) does seem to resolve the issue.