Commit a534d7d3 by rfkelly0

ensure that rename() raises ParentDirectoryMissingError when appropriate

parent 52f3de1a
...@@ -927,6 +927,8 @@ class FTPFS(FS): ...@@ -927,6 +927,8 @@ class FTPFS(FS):
code = int(code) code = int(code)
if code == 550: if code == 550:
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
if code == 552:
raise StorageSpaceError
raise PermissionDeniedError(str(exception), path=path, msg="FTP error: %s (see details)" % str(exception), details=exception) raise PermissionDeniedError(str(exception), path=path, msg="FTP error: %s (see details)" % str(exception), details=exception)
raise exception raise exception
...@@ -1067,6 +1069,11 @@ class FTPFS(FS): ...@@ -1067,6 +1069,11 @@ class FTPFS(FS):
self.clear_dircache(dirname(src), dirname(dst), src, dst) self.clear_dircache(dirname(src), dirname(dst), src, dst)
try: try:
self.ftp.rename(_encode(src), _encode(dst)) self.ftp.rename(_encode(src), _encode(dst))
except error_perm, exception:
code, message = str(exception).split(' ', 1)
if code == "550":
if not self.exists(dirname(dst)):
raise ParentDirectoryMissingError(dst)
except error_reply: except error_reply:
pass pass
......
...@@ -414,6 +414,8 @@ class MemoryFS(FS): ...@@ -414,6 +414,8 @@ class MemoryFS(FS):
src_dir_entry = self._get_dir_entry(src_dir) src_dir_entry = self._get_dir_entry(src_dir)
dst_dir_entry = self._get_dir_entry(dst_dir) dst_dir_entry = self._get_dir_entry(dst_dir)
if dst_dir_entry is None:
raise ParentDirectoryMissingError(dst)
dst_dir_entry.contents[dst_name] = src_dir_entry.contents[src_name] dst_dir_entry.contents[dst_name] = src_dir_entry.contents[src_name]
dst_dir_entry.contents[dst_name].name = dst_name dst_dir_entry.contents[dst_name].name = dst_name
del src_dir_entry.contents[src_name] del src_dir_entry.contents[src_name]
......
...@@ -180,11 +180,18 @@ class OSFS(FS): ...@@ -180,11 +180,18 @@ class OSFS(FS):
try: try:
os.rename(path_src, path_dst) os.rename(path_src, path_dst)
except OSError, e: except OSError, e:
# Linux (at least) can rename over an empty directory but gives if e.errno:
# ENOTEMPTY if the dir has contents. Raise UnsupportedError # POSIX rename() can rename over an empty directory but gives
# instead of DirectoryEmptyError in this case. # ENOTEMPTY if the dir has contents. Raise UnsupportedError
if e.errno and e.errno == errno.ENOTEMPTY: # instead of DirectoryEmptyError in this case.
raise UnsupportedError("rename") if e.errno == errno.ENOTEMPTY:
raise UnsupportedError("rename")
# Linux (at least) gives ENOENT when trying to rename into
# a directory that doesn't exist. We want ParentMissingError
# in this case.
if e.errno == errno.ENOENT:
if not os.path.exists(dirname(path_dst)):
raise ParentDirectoryMissingError(dst)
raise raise
......
...@@ -263,6 +263,8 @@ class SFTPFS(FS): ...@@ -263,6 +263,8 @@ class SFTPFS(FS):
except IOError, e: except IOError, e:
if getattr(e,"errno",None) == 2: if getattr(e,"errno",None) == 2:
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
if not self.isdir(dirname(dst)):
raise ParentDirectoryMissingError(dst)
raise raise
@convert_os_errors @convert_os_errors
......
...@@ -259,6 +259,8 @@ class FSTestCases(object): ...@@ -259,6 +259,8 @@ class FSTestCases(object):
self.fs.rename("dir_b/test.txt","dir_a/test.txt") self.fs.rename("dir_b/test.txt","dir_a/test.txt")
self.assert_(not check("dir_b/test.txt")) self.assert_(not check("dir_b/test.txt"))
self.assert_(check("dir_a/test.txt")) self.assert_(check("dir_a/test.txt"))
# test renaming a file into a non-existent directory
self.assertRaises(ParentDirectoryMissingError,self.fs.rename,"dir_a/test.txt","nonexistent/test.txt")
def test_info(self): def test_info(self):
test_str = "Hello, World!" test_str = "Hello, World!"
......
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