Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
@claudep claudep authored
View
11 django/core/files/storage.py
@@ -195,11 +195,18 @@ def _save(self, name, content):
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.
View
11 tests/regressiontests/file_storage/tests.py
@@ -356,6 +356,17 @@ def fake_remove(path):
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):
Please sign in to comment.
Something went wrong with that request. Please try again.