diff options
| author | Claude Paroz <claude@2xlibre.net> | 2012-08-29 15:13:20 +0200 |
|---|---|---|
| committer | Claude Paroz <claude@2xlibre.net> | 2012-08-29 16:37:37 +0200 |
| commit | 4e70ad11d29bde54b846920ce0dcf8d10741d3ae (patch) | |
| tree | ab5ae6c4212571d09aad681f16f66326f7962373 | |
| parent | b5240d25c1bf724f0008478e7f6cccd0a6d6bd1e (diff) | |
Made FileSystemStorage accept both text and byte streams
Thanks Alexey Boriskin for his help on the patch.
| -rw-r--r-- | django/core/files/storage.py | 11 | ||||
| -rw-r--r-- | tests/regressiontests/file_storage/tests.py | 11 |
2 files changed, 20 insertions, 2 deletions
diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 7542dcda46..0b300cd31e 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -195,11 +195,18 @@ class FileSystemStorage(Storage): fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0)) try: locks.lock(fd, locks.LOCK_EX) + _file = None for chunk in content.chunks(): - os.write(fd, chunk) + if _file is None: + mode = 'wb' if isinstance(chunk, bytes) else 'wt' + _file = os.fdopen(fd, mode) + _file.write(chunk) finally: locks.unlock(fd) - os.close(fd) + if _file is not None: + _file.close() + else: + os.close(fd) except OSError as e: if e.errno == errno.EEXIST: # Ooops, the file exists. We need a new file name. diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py index 396e70f5e6..87b509e320 100644 --- a/tests/regressiontests/file_storage/tests.py +++ b/tests/regressiontests/file_storage/tests.py @@ -356,6 +356,17 @@ class FileStorageTests(unittest.TestCase): finally: os.remove = real_remove + def test_file_chunks_error(self): + """ + Test behaviour when file.chunks() is raising an error + """ + f1 = ContentFile('chunks fails') + def failing_chunks(): + raise IOError + f1.chunks = failing_chunks + with self.assertRaises(IOError): + self.storage.save('error.file', f1) + class CustomStorage(FileSystemStorage): def get_available_name(self, name): |
