#25875: Unicode error when converting a Q object to a string
----------------------------------------------+----------------------------
     Reporter:  benjaminjkraft                |      Owner:  benjaminjkraft
         Type:  Bug                           |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  master
     Severity:  Normal                        |   Keywords:
 Triage Stage:  Unreviewed                    |  Has patch:  0
Easy pickings:  0                             |      UI/UX:  0
----------------------------------------------+----------------------------
 If you have a model whose `__str__` returns non-ASCII text, and you refer
 to that model in a `Q` object, attempting to `print` that `Q` object, or
 otherwise convert it to a string, will error.  This is a regression in
 Django 1.5, caused indirectly by
 [https://github.com/django/django/commit/3dd5d72 3dd5d72], and remains an
 issue in master; I believe it should only affect python 2 but I haven't
 actually checked.

 The issue appears to be that `django.utils.tree.Node.__str__`
 inadvertently attempts to convert the string back to unicode.  In
 particular, since [https://github.com/django/django/commit/3dd5d72
 3dd5d72], `self.connector` is a unicode string if `self` is a `Q` object.
 This causes python to convert the string being formatted and all its
 formatting arguments to unicode.  Since this is done implicitly it uses
 the default encoding (ASCII), which fails.

 Fixing this should be as simple as just explicitly doing
 `str(self.connector)` instead, although I haven't yet run the tests to see
 if that breaks anything else.  In any case, I'm happy to write a patch to
 do that later this week.  It's possible it would be better to instead
 define a `__unicode__` method and avoid the string-conversion entirely,
 I'm not sure, but this seems simpler.

 Complete repro:
 {{{
 # in models.py
 class Foo(models.Model):
     name = models.TextField()
     def __unicode__(self):
         return u'Foƶ'
     def __str__(self):
         return unicode(self).encode('utf-8')
     def __repr__(self):
         return str(self)

 # in a shell
 Q(baz=Foo(name="baz")) # raises UnicodeDecodeError
 }}}

 Note that the repro works as long as at least one of `__unicode__`,
 `__str__`, and `__repr__` is defined and returns non-ASCII text -- they
 don't need to all be explicitly defined.

--
Ticket URL: <https://code.djangoproject.com/ticket/25875>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/057.8c5d632c344cf497d28790ed0281c79f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to