Commit 8d1e513f by rfkelly0

more robustness (particularly cross-thread) for SimulateXAttr wrapper

parent 8697c1f5
......@@ -180,6 +180,8 @@ def convert_os_errors(func):
raise ResourceInvalidError(path,opname=opname,details=e)
if e.errno == errno.EINVAL:
raise ResourceInvalidError(path,opname=opname,details=e)
if e.errno == errno.EOPNOTSUPP:
raise UnsupportedError(opname,details=e)
# Sometimes windows gives some random errors...
if sys.platform == "win32":
if e.errno in (13,):
......
......@@ -196,19 +196,31 @@ class WrapFS(FS):
@rewrite_errors
def getxattr(self,path,name,default=None):
return self.wrapped_fs.getxattr(self._encode(path),name,default)
try:
return self.wrapped_fs.getxattr(self._encode(path),name,default)
except AttributeError:
raise UnsupportedError("getxattr")
@rewrite_errors
def setxattr(self,path,name,value):
return self.wrapped_fs.setxattr(self._encode(path),name,value)
try:
return self.wrapped_fs.setxattr(self._encode(path),name,value)
except AttributeError:
raise UnsupportedError("setxattr")
@rewrite_errors
def delxattr(self,path,name):
return self.wrapped_fs.delxattr(self._encode(path),name)
try:
return self.wrapped_fs.delxattr(self._encode(path),name)
except AttributeError:
raise UnsupportedError("delxattr")
@rewrite_errors
def listxattrs(self,path):
return self.wrapped_fs.listxattrs(self._encode(path))
try:
return self.wrapped_fs.listxattrs(self._encode(path))
except AttributeError:
raise UnsupportedError("listxattrs")
def __getattr__(self,attr):
return getattr(self.wrapped_fs,attr)
......
......@@ -31,6 +31,7 @@ except ImportError:
from fs.path import *
from fs.errors import *
from fs.wrapfs import WrapFS
from fs.base import synchronize
def ensure_xattrs(fs):
......@@ -42,9 +43,9 @@ def ensure_xattrs(fs):
"""
try:
# This attr doesn't have to exist, None should be returned by default
fs.getxattr("/","testingx-xattr")
fs.getxattr("/","testing-xattr")
return fs
except Exception:
except (AttributeError,UnsupportedError):
return SimulateXAttr(fs)
......@@ -52,7 +53,7 @@ class SimulateXAttr(WrapFS):
"""FS wrapper class that simulates xattr support.
The following methods are supplied for manipulating extended attributes:
* xattrs: list all extended attribute names for a path
* listxattrs: list all extended attribute names for a path
* getxattr: get an xattr of a path by name
* setxattr: set an xattr of a path by name
* delxattr: delete an xattr of a path by name
......@@ -83,7 +84,10 @@ class SimulateXAttr(WrapFS):
"""Retrieve the xattr dictionary for the given path."""
attr_path = self._get_attr_path(path)
if self.wrapped_fs.exists(attr_path):
return pickle.loads(self.wrapped_fs.getcontents(attr_path))
try:
return pickle.loads(self.wrapped_fs.getcontents(attr_path))
except EOFError:
return {}
else:
return {}
......@@ -92,6 +96,7 @@ class SimulateXAttr(WrapFS):
attr_path = self._get_attr_path(path)
self.wrapped_fs.setcontents(attr_path, pickle.dumps(attrs))
@synchronize
def setxattr(self, path, key, value):
"""Set an extended attribute on the given path."""
if not self.exists(path):
......@@ -100,6 +105,7 @@ class SimulateXAttr(WrapFS):
attrs[key] = str(value)
self._set_attr_dict(path, attrs)
@synchronize
def getxattr(self, path, key, default=None):
"""Retrieve an extended attribute for the given path."""
if not self.exists(path):
......@@ -107,6 +113,7 @@ class SimulateXAttr(WrapFS):
attrs = self._get_attr_dict(path)
return attrs.get(key, default)
@synchronize
def delxattr(self, path, key):
if not self.exists(path):
raise ResourceNotFoundError(path)
......
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