Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #11739 -- Made ContentFile support Unicode input

  • Loading branch information...
commit 361d6738f89f8443855d4378d3241566d9fca6e9 1 parent ebc773a
@claudep claudep authored
View
6 django/core/files/base.py
@@ -1,10 +1,11 @@
from __future__ import unicode_literals
import os
-from io import BytesIO, UnsupportedOperation
+from io import BytesIO, StringIO, UnsupportedOperation
from django.utils.encoding import smart_text
from django.core.files.utils import FileProxyMixin
+from django.utils import six
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
@@ -132,7 +133,8 @@ class ContentFile(File):
"""
def __init__(self, content, name=None):
content = content or b''
- super(ContentFile, self).__init__(BytesIO(content), name=name)
+ stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
+ super(ContentFile, self).__init__(stream_class(content), name=name)
self.size = len(content)
def __str__(self):
View
12 docs/ref/files/file.txt
@@ -91,14 +91,18 @@ The ``ContentFile`` Class
.. class:: ContentFile(File)
The ``ContentFile`` class inherits from :class:`~django.core.files.File`,
- but unlike :class:`~django.core.files.File` it operates on string content,
- rather than an actual file. For example::
+ but unlike :class:`~django.core.files.File` it operates on string content
+ (bytes also supported), rather than an actual file. For example::
from __future__ import unicode_literals
from django.core.files.base import ContentFile
- f1 = ContentFile(b"my string content")
- f2 = ContentFile("my unicode content encoded as UTF-8".encode('UTF-8'))
+ f1 = ContentFile("esta sentencia está en español")
+ f2 = ContentFile(b"these are bytes")
+
+ .. versionchanged:: 1.5
+
+ ContentFile also accepts Unicode strings.
.. currentmodule:: django.core.files.images
View
16 tests/regressiontests/file_storage/tests.py
@@ -21,6 +21,7 @@
from django.core.files.storage import FileSystemStorage, get_storage_class
from django.core.files.uploadedfile import UploadedFile
from django.test import SimpleTestCase
+from django.utils import six
from django.utils import unittest
from ..servers.tests import LiveServerBase
@@ -538,16 +539,25 @@ def test_multiple_calls(self):
self.assertEqual(size_1, size_2)
class ContentFileTestCase(unittest.TestCase):
- """
- Test that the constructor of ContentFile accepts 'name' (#16590).
- """
+
def test_content_file_default_name(self):
self.assertEqual(ContentFile(b"content").name, None)
def test_content_file_custom_name(self):
+ """
+ Test that the constructor of ContentFile accepts 'name' (#16590).
+ """
name = "I can have a name too!"
self.assertEqual(ContentFile(b"content", name=name).name, name)
+ def test_content_file_input_type(self):
+ """
+ Test that ContentFile can accept both bytes and unicode and that the
+ retrieved content is of the same type.
+ """
+ self.assertTrue(isinstance(ContentFile(b"content").read(), bytes))
+ self.assertTrue(isinstance(ContentFile("español").read(), six.text_type))
+
class NoNameFileTestCase(unittest.TestCase):
"""
Other examples of unnamed files may be tempfile.SpooledTemporaryFile or
Please sign in to comment.
Something went wrong with that request. Please try again.