Fixed #20812 -- Error out if __unicode__/__str__ doesn't return a text type.

This commit is contained in:
Florian Apolloner 2013-09-06 19:16:06 +02:00
parent ffe21e1f40
commit 2326dedde8
2 changed files with 24 additions and 10 deletions

View File

@ -67,16 +67,15 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
return s return s
try: try:
if not isinstance(s, six.string_types): if not isinstance(s, six.string_types):
if hasattr(s, '__unicode__'): if six.PY3:
s = s.__unicode__() if isinstance(s, bytes):
else: s = six.text_type(s, encoding, errors)
if six.PY3:
if isinstance(s, bytes):
s = six.text_type(s, encoding, errors)
else:
s = six.text_type(s)
else: 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: else:
# Note: We use .decode() here, instead of six.text_type(s, encoding, # 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 # errors), so that if s is a SafeBytes, it ends up being a

View File

@ -4,10 +4,25 @@ from __future__ import unicode_literals
import unittest import unittest
import datetime 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): 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): def test_force_bytes_exception(self):
""" """