Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ target/
# IPython
.ipynb_checkpoints
Untitled.ipynb

# Dev tools
.idea
35 changes: 16 additions & 19 deletions cloudpickle/cloudpickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,30 +541,27 @@ def save_file(self, obj):
return self.save_reduce(getattr, (sys,'stderr'), obj=obj)
if obj is sys.stdin:
raise pickle.PicklingError("Cannot pickle standard input")
if not obj.closed:
if hasattr(obj, 'isatty') and obj.isatty():
raise pickle.PicklingError("Cannot pickle files that map to tty objects")
if 'r' not in obj.mode and '+' not in obj.mode:
raise pickle.PicklingError("Cannot pickle files that are not opened for reading: %s" % obj.mode)
if obj.closed:
raise pickle.PicklingError("Cannot pickle closed files")
if hasattr(obj, 'isatty') and obj.isatty():
raise pickle.PicklingError("Cannot pickle files that map to tty objects")
if 'r' not in obj.mode and '+' not in obj.mode:
raise pickle.PicklingError("Cannot pickle files that are not opened for reading: %s" % obj.mode)

name = obj.name

retval = pystringIO.StringIO()

if obj.closed:
#create an empty closed string io
retval.close()
else:
try:
# Read the whole file
curloc = obj.tell()
obj.seek(0)
contents = obj.read()
obj.seek(curloc)
except IOError:
raise pickle.PicklingError("Cannot pickle file %s as it cannot be read" % name)
retval.write(contents)
retval.seek(curloc)
try:
# Read the whole file
curloc = obj.tell()
obj.seek(0)
contents = obj.read()
obj.seek(curloc)
except IOError:
raise pickle.PicklingError("Cannot pickle file %s as it cannot be read" % name)
retval.write(contents)
retval.seek(curloc)

retval.name = name
self.save(retval)
Expand Down
10 changes: 3 additions & 7 deletions tests/cloudpickle_file_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,13 @@ def test_empty_file(self):
self.assertEquals('', pickle.loads(cloudpickle.dumps(f)).read())
os.remove(self.tmpfilepath)

# XXX: investigate why this is a problem under Python 3
@pytest.mark.skipif(sys.version_info > (2, 7),
reason="only works on Python 2.x")
def test_closed_file(self):
# Write & close
with open(self.tmpfilepath, 'w') as f:
f.write(self.teststring)
# Cloudpickle returns an empty (& closed!) StringIO if the file was
# closed...
unpickled = pickle.loads(cloudpickle.dumps(f))
self.assertTrue(unpickled.closed)
with pytest.raises(pickle.PicklingError) as excinfo:
cloudpickle.dumps(f)
assert "Cannot pickle closed files" in str(excinfo.value)
os.remove(self.tmpfilepath)

def test_r_mode(self):
Expand Down