Skip to content

Commit

Permalink
Merge pull request #76 from betatim/py2-file-peek
Browse files Browse the repository at this point in the history
[WIP] Fix check for empty file when on python 2
  • Loading branch information
betatim committed Jul 10, 2017
2 parents f57fcb3 + a61af93 commit e814f2a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 6 deletions.
9 changes: 5 additions & 4 deletions osfclient/models/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from .file import ContainerMixin
from .file import File
from ..utils import norm_remote_path
from ..utils import file_empty


if six.PY2:
class FileExistsError(OSError):
Expand Down Expand Up @@ -74,11 +76,10 @@ def create_file(self, path, fp, update=False):
# peek at the file to check if it is an ampty file which needs special
# handling in requests. If we pass a file like object to data that
# turns out to be of length zero then no file is created on the OSF
not_empty = fp.peek(1)
if not_empty:
response = self._put(url, params={'name': fname}, data=fp)
else:
if file_empty(fp):
response = self._put(url, params={'name': fname}, data=b'')
else:
response = self._put(url, params={'name': fname}, data=fp)

if response.status_code == 409:
if not update:
Expand Down
6 changes: 5 additions & 1 deletion osfclient/tests/test_storage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from mock import patch, MagicMock, call

import pytest
import six

from osfclient.models import OSFCore
from osfclient.models import Storage
Expand Down Expand Up @@ -256,7 +257,10 @@ def test_create_new_zero_length_file():

fake_fp = MagicMock()
fake_fp.mode = 'rb'
fake_fp.peek = lambda x: ''
if six.PY3:
fake_fp.peek = lambda: ''
if six.PY2:
fake_fp.read = lambda: ''

store.create_file('foo.txt', fake_fp)

Expand Down
25 changes: 24 additions & 1 deletion osfclient/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from mock import call, patch
from mock import call, patch, Mock

from osfclient.utils import file_empty
from osfclient.utils import norm_remote_path
from osfclient.utils import makedirs
from osfclient.utils import split_storage
Expand Down Expand Up @@ -84,3 +85,25 @@ def test_makedirs_py3(mock_makedirs):

expected = [call('/this/path/exists', 511, True)]
assert expected == mock_makedirs.mock_calls


def test_empty_file():
fake_fp = Mock()
with patch('osfclient.utils.six.PY2', False):
empty = file_empty(fake_fp)

expected = [call.peek()]
assert expected == fake_fp.mock_calls
# mocks and calls on mocks always return True, so this should be False
assert not empty


def test_empty_file_py2():
fake_fp = Mock()
with patch('osfclient.utils.six.PY2', True):
empty = file_empty(fake_fp)

expected = [call.read(), call.seek(0)]
assert expected == fake_fp.mock_calls
# mocks and calls on mocks always return True, so this should be False
assert not empty
12 changes: 12 additions & 0 deletions osfclient/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,15 @@ def makedirs(path, mode=511, exist_ok=False):
return None
else:
return os.makedirs(path, mode)


def file_empty(fp):
"""Determine if a file is empty or not."""
# for python 2 we need to use a homemade peek()
if six.PY2:
contents = fp.read()
fp.seek(0)
return not bool(contents)

else:
return not fp.peek()

0 comments on commit e814f2a

Please sign in to comment.