Skip to content

Instantly share code, notes, and snippets.

@keturn
Last active November 11, 2015 21:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keturn/125118cefce2a21d64e1 to your computer and use it in GitHub Desktop.
Save keturn/125118cefce2a21d64e1 to your computer and use it in GitHub Desktop.
the perils of returning unicode from __str__ in Python 2 compatible code
# -*- coding: utf-8 -*-
from django.utils.encoding import force_str
class BadStr(object):
def __init__(self, content):
self.content = content
def __str__(self):
assert isinstance(self.content, unicode), "returning it from __str__ anyway"
return self.content
class GoodStr(object):
def __init__(self, content):
self.content = content
def __str__(self):
return force_str(self.content)
def test_case():
bad = BadStr(u"an object of ClassName")
good_1 = GoodStr(u"\N{HOT BEVERAGE}")
good_2 = GoodStr(u"\N{SNOWMAN}")
template = b"%s and %s"
this_works = template % (good_1, good_2)
this_doesnt = template % (bad, good_1)
if __name__ == '__main__':
test_case()
$ python2 dunder_str_unicode.py
Traceback (most recent call last):
File "dunder_str_unicode.py", line 35, in <module>
test_case()
File "dunder_str_unicode.py", line 31, in test_case
this_doesnt = template % (bad, good_1)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)
Process finished with exit code 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment