Commit dd808d70 by willmcgugan

implemented auto closing for multi/mount fs

parent bdcfff98
...@@ -71,7 +71,6 @@ class FileMount(object): ...@@ -71,7 +71,6 @@ class FileMount(object):
class MountFS(FS): class MountFS(FS):
"""A filesystem that delegates to other filesystems.""" """A filesystem that delegates to other filesystems."""
_meta = { 'virtual': True, _meta = { 'virtual': True,
'read_only' : False, 'read_only' : False,
'unicode_paths' : True, 'unicode_paths' : True,
...@@ -81,7 +80,8 @@ class MountFS(FS): ...@@ -81,7 +80,8 @@ class MountFS(FS):
DirMount = DirMount DirMount = DirMount
FileMount = FileMount FileMount = FileMount
def __init__(self, thread_synchronize=_thread_synchronize_default): def __init__(self, auto_close=True, thread_synchronize=_thread_synchronize_default):
self.auto_close = auto_close
super(MountFS, self).__init__(thread_synchronize=thread_synchronize) super(MountFS, self).__init__(thread_synchronize=thread_synchronize)
self.mount_tree = PathMap() self.mount_tree = PathMap()
...@@ -121,6 +121,16 @@ class MountFS(FS): ...@@ -121,6 +121,16 @@ class MountFS(FS):
else: else:
return self, "/", path return self, "/", path
@synchronize
def close(self):
# Explicitly closes children if requested
if self.auto_close:
for mount in self.mount_tree.itervalues():
mount.fs.close()
# Free references (which may incidently call the close method of the child filesystems)
self.mount_tree.clear()
super(MountFS, self).close()
def getsyspath(self, path, allow_none=False): def getsyspath(self, path, allow_none=False):
fs, _mount_path, delegate_path = self._delegate(path) fs, _mount_path, delegate_path = self._delegate(path)
if fs is self or fs is None: if fs is self or fs is None:
...@@ -341,7 +351,6 @@ class MountFS(FS): ...@@ -341,7 +351,6 @@ class MountFS(FS):
if object is None: if object is None:
raise ResourceNotFoundError(src) raise ResourceNotFoundError(src)
# TODO!
raise UnsupportedError("rename resource", path=src) raise UnsupportedError("rename resource", path=src)
@synchronize @synchronize
......
...@@ -83,9 +83,15 @@ class MultiFS(FS): ...@@ -83,9 +83,15 @@ class MultiFS(FS):
'case_insensitive_paths' : False 'case_insensitive_paths' : False
} }
def __init__(self): def __init__(self, auto_close=True):
"""
:param auto_close: If True the child filesystems will be closed when the MultiFS is closed
"""
super(MultiFS, self).__init__(thread_synchronize=_thread_synchronize_default) super(MultiFS, self).__init__(thread_synchronize=_thread_synchronize_default)
self.auto_close = auto_close
self.fs_sequence = [] self.fs_sequence = []
self.fs_lookup = {} self.fs_lookup = {}
self.write_fs = None self.write_fs = None
...@@ -100,6 +106,19 @@ class MultiFS(FS): ...@@ -100,6 +106,19 @@ class MultiFS(FS):
def __unicode__(self): def __unicode__(self):
return u"<MultiFS: %s>" % ", ".join(unicode(fs) for fs in self.fs_sequence) return u"<MultiFS: %s>" % ", ".join(unicode(fs) for fs in self.fs_sequence)
@synchronize
def close(self):
# Explicitly close if requested
if self.auto_close:
for fs in self.fs_sequence:
fs.close()
if self.write_fs is not None:
self.write_fs.close()
# Discard any references
del self.fs_sequence[:]
self.fs_lookup.clear()
self.write_fs = None
super(MultiFS, self).close()
@synchronize @synchronize
def addfs(self, name, fs, write=False): def addfs(self, name, fs, write=False):
......
from fs.mountfs import MountFS
from fs.memoryfs import MemoryFS
import unittest
class TestMultiFS(unittest.TestCase):
def test_auto_close(self):
"""Test MultiFS auto close is working"""
multi_fs = MountFS()
m1 = MemoryFS()
m2 = MemoryFS()
multi_fs.mount('/m1', m1)
multi_fs.mount('/m2', m2)
self.assert_(not m1.closed)
self.assert_(not m2.closed)
multi_fs.close()
self.assert_(m1.closed)
self.assert_(m2.closed)
def test_no_auto_close(self):
"""Test MultiFS auto close can be disabled"""
multi_fs = MountFS(auto_close=False)
m1 = MemoryFS()
m2 = MemoryFS()
multi_fs.mount('/m1', m1)
multi_fs.mount('/m2', m2)
self.assert_(not m1.closed)
self.assert_(not m2.closed)
multi_fs.close()
self.assert_(not m1.closed)
self.assert_(not m2.closed)
from fs.multifs import MultiFS
from fs.memoryfs import MemoryFS
import unittest
class TestMultiFS(unittest.TestCase):
def test_auto_close(self):
"""Test MultiFS auto close is working"""
multi_fs = MultiFS()
m1 = MemoryFS()
m2 = MemoryFS()
multi_fs.addfs('m1', m1)
multi_fs.addfs('m2', m2)
self.assert_(not m1.closed)
self.assert_(not m2.closed)
multi_fs.close()
self.assert_(m1.closed)
self.assert_(m2.closed)
def test_no_auto_close(self):
"""Test MultiFS auto close can be disables"""
multi_fs = MultiFS(auto_close=False)
m1 = MemoryFS()
m2 = MemoryFS()
multi_fs.addfs('m1', m1)
multi_fs.addfs('m2', m2)
self.assert_(not m1.closed)
self.assert_(not m2.closed)
multi_fs.close()
self.assert_(not m1.closed)
self.assert_(not m2.closed)
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