Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #11739 -- Made ContentFile support Unicode input

  • Loading branch information...
commit 361d6738f89f8443855d4378d3241566d9fca6e9 1 parent ebc773a
Claude Paroz authored August 29, 2012
6  django/core/files/base.py
... ...
@@ -1,10 +1,11 @@
1 1
 from __future__ import unicode_literals
2 2
 
3 3
 import os
4  
-from io import BytesIO, UnsupportedOperation
  4
+from io import BytesIO, StringIO, UnsupportedOperation
5 5
 
6 6
 from django.utils.encoding import smart_text
7 7
 from django.core.files.utils import FileProxyMixin
  8
+from django.utils import six
8 9
 from django.utils.encoding import python_2_unicode_compatible
9 10
 
10 11
 @python_2_unicode_compatible
@@ -132,7 +133,8 @@ class ContentFile(File):
132 133
     """
133 134
     def __init__(self, content, name=None):
134 135
         content = content or b''
135  
-        super(ContentFile, self).__init__(BytesIO(content), name=name)
  136
+        stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
  137
+        super(ContentFile, self).__init__(stream_class(content), name=name)
136 138
         self.size = len(content)
137 139
 
138 140
     def __str__(self):
12  docs/ref/files/file.txt
@@ -91,14 +91,18 @@ The ``ContentFile`` Class
91 91
 .. class:: ContentFile(File)
92 92
 
93 93
     The ``ContentFile`` class inherits from :class:`~django.core.files.File`,
94  
-    but unlike :class:`~django.core.files.File` it operates on string content,
95  
-    rather than an actual file. For example::
  94
+    but unlike :class:`~django.core.files.File` it operates on string content
  95
+    (bytes also supported), rather than an actual file. For example::
96 96
 
97 97
         from __future__ import unicode_literals
98 98
         from django.core.files.base import ContentFile
99 99
 
100  
-        f1 = ContentFile(b"my string content")
101  
-        f2 = ContentFile("my unicode content encoded as UTF-8".encode('UTF-8'))
  100
+        f1 = ContentFile("esta sentencia está en español")
  101
+        f2 = ContentFile(b"these are bytes")
  102
+
  103
+    .. versionchanged:: 1.5
  104
+
  105
+        ContentFile also accepts Unicode strings.
102 106
 
103 107
 .. currentmodule:: django.core.files.images
104 108
 
16  tests/regressiontests/file_storage/tests.py
@@ -21,6 +21,7 @@
21 21
 from django.core.files.storage import FileSystemStorage, get_storage_class
22 22
 from django.core.files.uploadedfile import UploadedFile
23 23
 from django.test import SimpleTestCase
  24
+from django.utils import six
24 25
 from django.utils import unittest
25 26
 from ..servers.tests import LiveServerBase
26 27
 
@@ -538,16 +539,25 @@ def test_multiple_calls(self):
538 539
         self.assertEqual(size_1, size_2)
539 540
 
540 541
 class ContentFileTestCase(unittest.TestCase):
541  
-    """
542  
-    Test that the constructor of ContentFile accepts 'name' (#16590).
543  
-    """
  542
+
544 543
     def test_content_file_default_name(self):
545 544
         self.assertEqual(ContentFile(b"content").name, None)
546 545
 
547 546
     def test_content_file_custom_name(self):
  547
+        """
  548
+        Test that the constructor of ContentFile accepts 'name' (#16590).
  549
+        """
548 550
         name = "I can have a name too!"
549 551
         self.assertEqual(ContentFile(b"content", name=name).name, name)
550 552
 
  553
+    def test_content_file_input_type(self):
  554
+        """
  555
+        Test that ContentFile can accept both bytes and unicode and that the
  556
+        retrieved content is of the same type.
  557
+        """
  558
+        self.assertTrue(isinstance(ContentFile(b"content").read(), bytes))
  559
+        self.assertTrue(isinstance(ContentFile("español").read(), six.text_type))
  560
+
551 561
 class NoNameFileTestCase(unittest.TestCase):
552 562
     """
553 563
     Other examples of unnamed files may be tempfile.SpooledTemporaryFile or

0 notes on commit 361d673

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