Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Made FileSystemStorage accept both text and byte streams

Thanks Alexey Boriskin for his help on the patch.
  • Loading branch information...
commit 4e70ad11d29bde54b846920ce0dcf8d10741d3ae 1 parent b5240d2
Claude Paroz authored August 29, 2012
11  django/core/files/storage.py
@@ -195,11 +195,18 @@ def _save(self, name, content):
195 195
                     fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0))
196 196
                     try:
197 197
                         locks.lock(fd, locks.LOCK_EX)
  198
+                        _file = None
198 199
                         for chunk in content.chunks():
199  
-                            os.write(fd, chunk)
  200
+                            if _file is None:
  201
+                                mode = 'wb' if isinstance(chunk, bytes) else 'wt'
  202
+                                _file = os.fdopen(fd, mode)
  203
+                            _file.write(chunk)
200 204
                     finally:
201 205
                         locks.unlock(fd)
202  
-                        os.close(fd)
  206
+                        if _file is not None:
  207
+                            _file.close()
  208
+                        else:
  209
+                            os.close(fd)
203 210
             except OSError as e:
204 211
                 if e.errno == errno.EEXIST:
205 212
                     # Ooops, the file exists. We need a new file name.
11  tests/regressiontests/file_storage/tests.py
@@ -356,6 +356,17 @@ def fake_remove(path):
356 356
         finally:
357 357
             os.remove = real_remove
358 358
 
  359
+    def test_file_chunks_error(self):
  360
+        """
  361
+        Test behaviour when file.chunks() is raising an error
  362
+        """
  363
+        f1 = ContentFile('chunks fails')
  364
+        def failing_chunks():
  365
+            raise IOError
  366
+        f1.chunks = failing_chunks
  367
+        with self.assertRaises(IOError):
  368
+            self.storage.save('error.file', f1)
  369
+
359 370
 
360 371
 class CustomStorage(FileSystemStorage):
361 372
     def get_available_name(self, name):

0 notes on commit 4e70ad1

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