Commit e1226def by rfkelly0

RemoteFileBuffer: ensure rfile is closed as soon as we're done with it

parent 9fe3ecd4
...@@ -99,6 +99,7 @@ class RemoteFileBuffer(object): ...@@ -99,6 +99,7 @@ class RemoteFileBuffer(object):
self._eof = True self._eof = True
if not hasattr(rfile, "read"): if not hasattr(rfile, "read"):
raise rfile
rfile = StringIO(unicode(rfile)) rfile = StringIO(unicode(rfile))
self._rfile = rfile self._rfile = rfile
...@@ -111,6 +112,8 @@ class RemoteFileBuffer(object): ...@@ -111,6 +112,8 @@ class RemoteFileBuffer(object):
# Do not use remote file object # Do not use remote file object
self._eof = True self._eof = True
self._rfile = None self._rfile = None
if rfile is not None and hasattr(rfile,"close"):
rfile.close()
def __del__(self): def __del__(self):
# Don't try to close a partially-constructed file # Don't try to close a partially-constructed file
...@@ -183,6 +186,8 @@ class RemoteFileBuffer(object): ...@@ -183,6 +186,8 @@ class RemoteFileBuffer(object):
self._eof = True self._eof = True
break break
if self._eof and self._rfile is not None:
self._rfile.close()
self._readlen += bytes_read self._readlen += bytes_read
def _fillbuffer(self, length=None): def _fillbuffer(self, length=None):
...@@ -281,6 +286,8 @@ class RemoteFileBuffer(object): ...@@ -281,6 +286,8 @@ class RemoteFileBuffer(object):
self._eof = True self._eof = True
self.flush() self.flush()
if self._rfile is not None:
self._rfile.close()
finally: finally:
self._lock.release() self._lock.release()
...@@ -315,6 +322,8 @@ class RemoteFileBuffer(object): ...@@ -315,6 +322,8 @@ class RemoteFileBuffer(object):
self._setcontents() self._setcontents()
self.file.close() self.file.close()
self.closed = True self.closed = True
if self._rfile is not None:
self._rfile.close()
finally: finally:
self._lock.release() self._lock.release()
......
...@@ -22,14 +22,16 @@ from fs.tempfs import TempFS ...@@ -22,14 +22,16 @@ from fs.tempfs import TempFS
from fs.path import * from fs.path import *
from fs.local_functools import wraps from fs.local_functools import wraps
class RemoteTempFS(TempFS): class RemoteTempFS(TempFS):
''' """
Simple filesystem implementing setfilecontents Simple filesystem implementing setfilecontents
for RemoteFileBuffer tests for RemoteFileBuffer tests
''' """
def open(self, path, mode='rb', write_on_flush=True): def open(self, path, mode='rb', write_on_flush=True):
if 'a' in mode or 'r' in mode or '+' in mode: if 'a' in mode or 'r' in mode or '+' in mode:
f = super(RemoteTempFS, self).open(path, 'rb') f = super(RemoteTempFS, self).open(path, 'rb')
f = TellAfterCloseFile(f)
else: else:
f = None f = None
...@@ -44,6 +46,28 @@ class RemoteTempFS(TempFS): ...@@ -44,6 +46,28 @@ class RemoteTempFS(TempFS):
f.write(content) f.write(content)
f.close() f.close()
class TellAfterCloseFile(object):
"""File-like object that allows calling tell() after it's been closed."""
def __init__(self,file):
self._finalpos = None
self.file = file
def close(self):
if self._finalpos is None:
self._finalpos = self.file.tell()
self.file.close()
def tell(self):
if self._finalpos is not None:
return self._finalpos
return self.file.tell()
def __getattr__(self,attr):
return getattr(self.file,attr)
class TestRemoteFileBuffer(unittest.TestCase, FSTestCases, ThreadingTestCases): class TestRemoteFileBuffer(unittest.TestCase, FSTestCases, ThreadingTestCases):
class FakeException(Exception): pass class FakeException(Exception): pass
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment