@python_2_unicode_compatible causes infinite recursion when module imported more than once
|Reported by:||ntucker||Owned by:||nobody|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
Sometimes a module that uses @python_2_unicode_compatible is imported multiple times. Possibly because a different pathname is used to import it. When this occurs, it makes unicode be the str function that was originally assigned, which calls unicode. So anytime unicode is called on the object, there is infinite recursion.
A simple check whether the str function has already been assigned will prevent setting unicode to the provided recursive function. This will also guard against other cases of multiple @python_2_unicode_compatible calls.
class _STR(object): def __call__(self, obj): return self.__unicode__().encode('utf-8') _str = _STR() def python_2_unicode_compatible(klass): """ A decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method returning text and apply this decorator to the class. """ if six.PY2: if '__str__' not in klass.__dict__: raise ValueError("@python_2_unicode_compatible cannot be applied " "to %s because it doesn't define __str__()." % klass.__name__) # this was already applied once if klass.__str__ == _str: return klass klass.__unicode__ = klass.__str__ klass.__str__ = _str return klass
I will provide patch if this is accepted. Above is example code.
Change History (10)
Changed 16 months ago by ntucker
comment:1 Changed 16 months ago by ntucker
- Has patch set
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
comment:6 Changed 16 months ago by aaugustin
- Resolution set to invalid
- Status changed from new to closed