Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make all self-move operations raise IllegalDestination error #549

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 5 additions & 3 deletions fs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1091,15 +1091,15 @@ def movedir(self, src_path, dst_path, create=False, preserve_time=False):
and ``create`` is `False`.
fs.errors.DirectoryExpected: if ``src_path`` or one of its
ancestors is not a directory.
fs.errors.IllegalDestination: when attempting to move the
folder at ``src_path`` to itself or one of its subfolders.

"""
from .move import move_dir

with self._lock:
_src_path = self.validatepath(src_path)
_dst_path = self.validatepath(dst_path)
if _src_path == _dst_path:
return
if isbase(_src_path, _dst_path):
raise errors.IllegalDestination(dst_path)
if not create and not self.exists(dst_path):
Expand Down Expand Up @@ -1169,6 +1169,8 @@ def move(self, src_path, dst_path, overwrite=False, preserve_time=False):
and ``overwrite`` is `False`.
fs.errors.ResourceNotFound: If a parent directory of
``dst_path`` does not exist.
fs.errors.IllegalDestination: If ``src_path`` and ``dst_path``
refer to the same resource, and ``overwrite`` is `True`.

"""
_src_path = self.validatepath(src_path)
Expand All @@ -1179,7 +1181,7 @@ def move(self, src_path, dst_path, overwrite=False, preserve_time=False):
raise errors.FileExpected(src_path)
if _src_path == _dst_path:
# early exit when moving a file onto itself
return
raise errors.IllegalDestination(dst_path)
if self.getmeta().get("supports_rename", False):
try:
src_sys_path = self.getsyspath(_src_path)
Expand Down
10 changes: 4 additions & 6 deletions fs/memoryfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,9 @@ def move(self, src_path, dst_path, overwrite=False, preserve_time=False):
# handle moving a file onto itself
if src_dir == dst_dir and src_name == dst_name:
if overwrite:
return
raise errors.DestinationExists(dst_path)
raise errors.IllegalDestination(dst_path)
else:
raise errors.DestinationExists(dst_path)

# move the entry from the src folder to the dst folder
dst_dir_entry.set_entry(dst_name, src_entry)
Expand All @@ -483,10 +484,7 @@ def movedir(self, src_path, dst_path, create=False, preserve_time=False):
dst_dir, dst_name = split(_dst_path)
src_dir, src_name = split(_src_path)

# move a dir onto itself
if _src_path == _dst_path:
return
# move a dir into itself
# move a dir onto or into itself
if isbase(_src_path, _dst_path):
raise errors.IllegalDestination(dst_path)

Expand Down
16 changes: 8 additions & 8 deletions fs/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1813,20 +1813,20 @@ def test_move_file_temp(self):

def test_move_file_onto_itself(self):
self.fs.writetext("file.txt", "Hello")
self.fs.move("file.txt", "file.txt", overwrite=True)
self.assert_text("file.txt", "Hello")

with self.assertRaises(errors.IllegalDestination):
self.fs.move("file.txt", "file.txt", overwrite=True)
with self.assertRaises(errors.DestinationExists):
self.fs.move("file.txt", "file.txt", overwrite=False)
self.assert_text("file.txt", "Hello")

def test_move_file_onto_itself_relpath(self):
subdir = self.fs.makedir("sub")
subdir.writetext("file.txt", "Hello")
self.fs.move("sub/file.txt", "sub/../sub/file.txt", overwrite=True)
self.assert_text("sub/file.txt", "Hello")

with self.assertRaises(errors.IllegalDestination):
self.fs.move("sub/file.txt", "sub/../sub/file.txt", overwrite=True)
with self.assertRaises(errors.DestinationExists):
self.fs.move("sub/file.txt", "sub/../sub/file.txt", overwrite=False)
self.assert_text("sub/file.txt", "Hello")

def test_copy_file_onto_itself(self):
self.fs.writetext("file.txt", "Hello")
Expand Down Expand Up @@ -1911,8 +1911,8 @@ def test_movedir_onto_itself(self):
folder.writetext("file1.txt", "Hello1")
sub = folder.makedir("sub")
sub.writetext("file2.txt", "Hello2")

self.fs.movedir("folder", "folder")
with self.assertRaises(errors.IllegalDestination):
self.fs.movedir("folder", "folder")
self.assert_text("folder/file1.txt", "Hello1")
self.assert_text("folder/sub/file2.txt", "Hello2")

Expand Down
8 changes: 5 additions & 3 deletions tests/test_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import fs.move
from fs import open_fs
from fs.errors import FSError, ResourceReadOnly
from fs.errors import FSError, ResourceReadOnly, IllegalDestination
from fs.path import join
from fs.wrap import read_only

Expand Down Expand Up @@ -175,7 +175,8 @@ def test_move_file_overwrite_itself(self, _, fs_url):
# behaves like the regular one (TempFS tests the optmized code path).
with open_fs(fs_url) as tmp:
tmp.writetext("file.txt", "content")
fs.move.move_file(tmp, "file.txt", tmp, "file.txt")
with self.assertRaises(IllegalDestination):
fs.move.move_file(tmp, "file.txt", tmp, "file.txt")
self.assertTrue(tmp.exists("file.txt"))
self.assertEquals(tmp.readtext("file.txt"), "content")

Expand All @@ -186,7 +187,8 @@ def test_move_file_overwrite_itself_relpath(self, _, fs_url):
with open_fs(fs_url) as tmp:
new_dir = tmp.makedir("dir")
new_dir.writetext("file.txt", "content")
fs.move.move_file(tmp, "dir/../dir/file.txt", tmp, "dir/file.txt")
with self.assertRaises(IllegalDestination):
fs.move.move_file(tmp, "dir/../dir/file.txt", tmp, "dir/file.txt")
self.assertTrue(tmp.exists("dir/file.txt"))
self.assertEquals(tmp.readtext("dir/file.txt"), "content")

Expand Down