From f27704506ae4dac599d68d3ad6c5d036ed72e4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20G=C3=B3mez?= Date: Sat, 4 Feb 2017 13:23:23 -0400 Subject: [PATCH] Fix bug __repr__ting an XmlModel on Python3 (doesn't define unicode) The `__repr__` implementation on class `XmlModel` uses the function `unicode` which is only defined in Python 2. So in Python 3, this raises an exception. I changed the usage of `unicode` with `smart_str` from `django.utils.encoding` as it promises to use `smart_bytes` if running in Python 2 and `smart_text` if Python 3. What happens is that Python 3 expects `__repr__` to return a `str` not a bytestring. That's why changed the import logic and leverage on Django logic behind the `smart_*` methods handling Python 2 and 3. --- djxml/xmlmodels/base.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/djxml/xmlmodels/base.py b/djxml/xmlmodels/base.py index 8bf83b5..18a3561 100644 --- a/djxml/xmlmodels/base.py +++ b/djxml/xmlmodels/base.py @@ -10,11 +10,8 @@ from django.core.exceptions import (ObjectDoesNotExist, FieldError, MultipleObjectsReturned,) from django.db.models.base import subclass_exception -try: - from django.utils.encoding import ( - smart_bytes as smart_str, force_text as force_unicode) -except ImportError: - from django.utils.encoding import smart_str, force_unicode +from django.utils.encoding import smart_str, force_text +from django.utils.encoding import python_2_unicode_compatible from .signals import xmlclass_prepared from .options import Options, DEFAULT_NAMES @@ -130,7 +127,7 @@ def _prepare(cls): xmlclass_prepared.send(sender=cls) - +@python_2_unicode_compatible @six.add_metaclass(XmlModelBase) class XmlModel(object): @@ -218,14 +215,14 @@ def create_from_file(cls, xml_file): def __repr__(self): try: - u = unicode(self) + u = smart_str(self) except (UnicodeEncodeError, UnicodeDecodeError): u = '[Bad Unicode data]' return smart_str(u'<%s: %s>' % (self.__class__.__name__, u)) def __str__(self): if hasattr(self, '__unicode__'): - return force_unicode(self).encode('utf-8') + return force_text(self).encode('utf-8') return '%s object' % self.__class__.__name__ def __eq__(self, other):