Skip to content

Commit 21b3611

Browse files
committed
use shutil to move folder
1 parent 93c2579 commit 21b3611

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

fs/move.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import typing
77

8+
import shutil
9+
810
from ._pathcompat import commonpath
911
from .copy import copy_dir, copy_file
1012
from .errors import FSError
@@ -137,6 +139,16 @@ def move_dir(
137139
"""
138140
with manage_fs(src_fs, writeable=True) as _src_fs:
139141
with manage_fs(dst_fs, writeable=True, create=True) as _dst_fs:
142+
143+
# if both filesystems have a syspath we can use shutil to move the folder
144+
if _src_fs.hassyspath(src_path) and _dst_fs.hassyspath(dst_path):
145+
src_syspath = _src_fs.getsyspath(src_path)
146+
dst_syspath = _dst_fs.getsyspath(dst_path)
147+
with _src_fs.lock(), _dst_fs.lock():
148+
shutil.move(src=src_syspath, dst=dst_syspath)
149+
return # optimization worked, exit early
150+
151+
# standard copy then delete
140152
with _src_fs.lock(), _dst_fs.lock():
141153
_dst_fs.makedir(dst_path, recreate=True)
142154
copy_dir(

tests/test_move.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
except ImportError:
88
import mock
99

10+
import shutil
1011
from parameterized import parameterized, parameterized_class
1112

1213
import fs.move
@@ -206,3 +207,16 @@ def test_move_file_cleanup_on_error(self, cleanup):
206207
)
207208
self.assertTrue(src.exists("file.txt"))
208209
self.assertEqual(not dst.exists("target.txt"), cleanup)
210+
211+
@parameterized.expand([("temp", "temp://", True), ("mem", "mem://", False)])
212+
def test_move_dir_optimized(self, _, fs_url, mv_called):
213+
with open_fs(fs_url) as tmp:
214+
with mock.patch.object(shutil, "move", wraps=shutil.move) as mv:
215+
new_dir = tmp.makedir("dir")
216+
new_dir.writetext("file.txt", "content")
217+
sub = new_dir.makedir("sub")
218+
sub.writetext("file.txt", "sub content")
219+
fs.move.move_dir(tmp, "dir", tmp, "newdir")
220+
self.assertEqual(tmp.readtext("newdir/file.txt"), "content")
221+
self.assertEqual(tmp.readtext("newdir/sub/file.txt"), "sub content")
222+
self.assertEqual(mv.called, mv_called)

0 commit comments

Comments
 (0)