Skip to content

Commit

Permalink
Made FileSystemStorage accept both text and byte streams
Browse files Browse the repository at this point in the history
Thanks Alexey Boriskin for his help on the patch.
  • Loading branch information
claudep committed Aug 29, 2012
1 parent b5240d2 commit 4e70ad1
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
11 changes: 9 additions & 2 deletions django/core/files/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions tests/regressiontests/file_storage/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down

0 comments on commit 4e70ad1

Please sign in to comment.