Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #20812 -- Error out if __unicode__/__str__ doesn't return a tex…

…t type.
  • Loading branch information...
commit 2326dedde81c59950d2b1e0653a837e1d7019acd 1 parent ffe21e1
@apollo13 apollo13 authored
Showing with 24 additions and 10 deletions.
  1. +8 −9 django/utils/encoding.py
  2. +16 −1 tests/utils_tests/test_encoding.py
View
17 django/utils/encoding.py
@@ -67,16 +67,15 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
return s
try:
if not isinstance(s, six.string_types):
- if hasattr(s, '__unicode__'):
- s = s.__unicode__()
- else:
- if six.PY3:
- if isinstance(s, bytes):
- s = six.text_type(s, encoding, errors)
- else:
- s = six.text_type(s)
+ if six.PY3:
+ if isinstance(s, bytes):
+ s = six.text_type(s, encoding, errors)
else:
- s = six.text_type(bytes(s), encoding, errors)
+ s = six.text_type(s)
+ elif hasattr(s, '__unicode__'):
+ s = six.text_type(s)
+ else:
+ s = six.text_type(bytes(s), encoding, errors)
else:
# Note: We use .decode() here, instead of six.text_type(s, encoding,
# errors), so that if s is a SafeBytes, it ends up being a
View
17 tests/utils_tests/test_encoding.py
@@ -4,10 +4,25 @@
import unittest
import datetime
-from django.utils.encoding import force_bytes, filepath_to_uri
+from django.utils import six
+from django.utils.encoding import force_bytes, force_text, filepath_to_uri
class TestEncodingUtils(unittest.TestCase):
+ def test_force_text_exception(self):
+ """
+ Check that broken __unicode__/__str__ actually raises an error.
+ """
+ class MyString(object):
+ def __str__(self):
+ return b'\xc3\xb6\xc3\xa4\xc3\xbc'
+
+ __unicode__ = __str__
+
+ # str(s) raises a TypeError on python 3 if the result is not a text type.
+ # python 2 fails when it tries converting from str to unicode (via ASCII).
+ exception = TypeError if six.PY3 else UnicodeError
+ self.assertRaises(exception, force_text, MyString())
def test_force_bytes_exception(self):
"""

2 comments on commit 2326ded

@colorfool-me

Maybe it`s a stupid question, but which version must I use to get this fix? I tried the head version of Django, 1.5.4 and 1.6 and I still get this error?

@apollo13
Owner

I only fixed it in master; I didn't want to risk introducing a breakage in 1.6 via that… You'll have to tell us which error exactly you are still seeing (including traceback etc), but please not on github, use code.djangoproject.com or the mailinglist.

Please sign in to comment.
Something went wrong with that request. Please try again.