Skip to content

Commit 44cbe31

Browse files
committed
add cleanup_dest_on_error in move_file
1 parent a549250 commit 44cbe31

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

fs/move.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def move_file(
4646
dst_fs, # type: Union[Text, FS]
4747
dst_path, # type: Text
4848
preserve_time=False, # type: bool
49+
cleanup_dest_on_error=True, # type: bool
4950
):
5051
# type: (...) -> None
5152
"""Move a file from one filesystem to another.
@@ -57,6 +58,8 @@ def move_file(
5758
dst_path (str): Path to a file on ``dst_fs``.
5859
preserve_time (bool): If `True`, try to preserve mtime of the
5960
resources (defaults to `False`).
61+
cleanup_dest_on_error (bool): If `True`, tries to delete the file copied to
62+
dst_fs if deleting the file from src_fs fails.
6063
6164
"""
6265
with manage_fs(src_fs, writeable=True) as _src_fs:
@@ -100,7 +103,8 @@ def move_file(
100103
except FSError as e:
101104
# if the source cannot be removed we delete the copy on the
102105
# destination
103-
_dst_fs.remove(dst_path)
106+
if cleanup_dest_on_error:
107+
_dst_fs.remove(dst_path)
104108
raise e
105109

106110

tests/test_move.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
import unittest
44

5+
try:
6+
from unittest import mock
7+
except ImportError:
8+
import mock
9+
510
from parameterized import parameterized_class
611

12+
713
import fs.move
814
from fs import open_fs
9-
from fs.errors import ResourceReadOnly
15+
from fs.errors import FSError, ResourceReadOnly
1016
from fs.path import join
1117
from fs.wrap import read_only
1218

@@ -145,22 +151,24 @@ def test_move_file_read_only_mem_dest(self):
145151
)
146152
self.assertTrue(src.exists("file.txt"))
147153

148-
def test_move_dir_cleanup(self):
149-
src_fs = open_fs("mem://")
150-
src_fs.makedirs("foo/bar")
151-
src_fs.touch("foo/bar/baz.txt")
152-
src_fs.touch("foo/test.txt")
153-
154-
dst_fs = open_fs("mem://")
155-
dst_fs.create("test.txt")
156-
157-
ro_src = read_only(src_fs)
158-
159-
with self.assertRaises(ResourceReadOnly):
160-
fs.move.move_dir(ro_src, "/foo", dst_fs, "/")
154+
def test_move_file_cleanup_on_error(self):
155+
with open_fs("mem://") as src, open_fs("mem://") as dst:
156+
src.writetext("file.txt", "Content")
157+
with mock.patch.object(src, "remove") as mck:
158+
mck.side_effect = FSError
159+
with self.assertRaises(FSError):
160+
fs.move.move_file(src, "file.txt", dst, "file.txt")
161+
self.assertTrue(src.exists("file.txt"))
162+
self.assertFalse(dst.exists("file.txt"))
161163

162-
self.assertTrue(src_fs.exists("foo/bar/baz.txt"))
163-
self.assertTrue(src_fs.exists("foo/test.txt"))
164-
self.assertFalse(dst_fs.isdir("bar"))
165-
self.assertFalse(dst_fs.exists("bar/baz.txt"))
166-
self.assertTrue(dst_fs.exists("test.txt"))
164+
def test_move_file_no_cleanup_on_error(self):
165+
with open_fs("mem://") as src, open_fs("mem://") as dst:
166+
src.writetext("file.txt", "Content")
167+
with mock.patch.object(src, "remove") as mck:
168+
mck.side_effect = FSError
169+
with self.assertRaises(FSError):
170+
fs.move.move_file(
171+
src, "file.txt", dst, "file.txt", cleanup_dest_on_error=False
172+
)
173+
self.assertTrue(src.exists("file.txt"))
174+
self.assertTrue(dst.exists("file.txt"))

0 commit comments

Comments
 (0)