diff --git a/django/utils/encoding.py b/django/utils/encoding.py index 99c9da843a..4e347bdc5f 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -77,12 +77,12 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'): If strings_only is True, don't convert (some) non-string-like objects. """ # Handle the common case first for performance reasons. - if isinstance(s, six.text_type): + if issubclass(type(s), six.text_type): return s if strings_only and is_protected_type(s): return s try: - if not isinstance(s, six.string_types): + if not issubclass(type(s), six.string_types): if six.PY3: if isinstance(s, bytes): s = six.text_type(s, encoding, errors) diff --git a/docs/releases/1.8.3.txt b/docs/releases/1.8.3.txt index 1155ac1cb6..d965630c77 100644 --- a/docs/releases/1.8.3.txt +++ b/docs/releases/1.8.3.txt @@ -19,3 +19,6 @@ Bugfixes ``Count()`` (:ticket:`24835`). * Corrected ``HStoreField.has_changed()`` (:ticket:`24844`). + +* Reverted an optimization to the CSRF template context processor which caused + a regression (:ticket:`24836`). diff --git a/tests/csrf_tests/test_context_processor.py b/tests/csrf_tests/test_context_processor.py new file mode 100644 index 0000000000..270b3e4771 --- /dev/null +++ b/tests/csrf_tests/test_context_processor.py @@ -0,0 +1,15 @@ +import json + +from django.http import HttpRequest +from django.template.context_processors import csrf +from django.test import SimpleTestCase +from django.utils.encoding import force_text + + +class TestContextProcessor(SimpleTestCase): + + def test_force_text_on_token(self): + request = HttpRequest() + request.META['CSRF_COOKIE'] = 'test-token' + token = csrf(request).get('csrf_token') + self.assertEqual(json.dumps(force_text(token)), '"test-token"') diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py index 81024bdf12..9527f29dcf 100644 --- a/tests/utils_tests/test_encoding.py +++ b/tests/utils_tests/test_encoding.py @@ -9,6 +9,7 @@ from django.utils.encoding import ( escape_uri_path, filepath_to_uri, force_bytes, force_text, iri_to_uri, smart_text, uri_to_iri, ) +from django.utils.functional import SimpleLazyObject from django.utils.http import urlquote_plus @@ -28,6 +29,10 @@ class TestEncodingUtils(unittest.TestCase): exception = TypeError if six.PY3 else UnicodeError self.assertRaises(exception, force_text, MyString()) + def test_force_text_lazy(self): + s = SimpleLazyObject(lambda: 'x') + self.assertTrue(issubclass(type(force_text(s)), six.text_type)) + def test_force_bytes_exception(self): """ Test that force_bytes knows how to convert to bytes an exception