Skip to content

Commit 9713c61

Browse files
committed
add the move_dir optimization
1 parent b635cf2 commit 9713c61

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

fs/move.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
import typing
77

8-
import shutil
8+
import os
99

1010
from ._pathcompat import commonpath
1111
from .copy import copy_dir, copy_file
12-
from .errors import FSError
12+
from .error_tools import convert_os_errors
13+
from .errors import DirectoryExpected, FSError, IllegalDestination, ResourceNotFound
1314
from .opener import manage_fs
1415
from .osfs import OSFS
15-
from .path import frombase
16+
from .path import frombase, isbase
1617

1718
if typing.TYPE_CHECKING:
1819
from typing import Text, Union
@@ -139,13 +140,24 @@ def move_dir(
139140
"""
140141
with manage_fs(src_fs, writeable=True) as _src_fs:
141142
with manage_fs(dst_fs, writeable=True, create=True) as _dst_fs:
143+
if not _src_fs.exists(src_path):
144+
raise ResourceNotFound(src_path)
145+
if not _src_fs.isdir(src_path):
146+
raise DirectoryExpected(src_path)
142147

143-
# if both filesystems have a syspath we can use shutil to move the folder
148+
# if both filesystems have a syspath we use `os.rename` to move the folder
144149
if _src_fs.hassyspath(src_path) and _dst_fs.hassyspath(dst_path):
145150
src_syspath = _src_fs.getsyspath(src_path)
146151
dst_syspath = _dst_fs.getsyspath(dst_path)
152+
# recheck if the move operation is legal using the syspaths
153+
if isbase(src_syspath, dst_syspath):
154+
raise IllegalDestination(dst_path)
147155
with _src_fs.lock(), _dst_fs.lock():
148-
shutil.move(src=src_syspath, dst=dst_syspath)
156+
with convert_os_errors("move_dir", src_path, directory=True):
157+
os.rename(src=src_syspath, dst=dst_syspath)
158+
# recreate the root dir if it has been renamed
159+
if src_path == "/":
160+
_src_fs.makedir("/")
149161
return # optimization worked, exit early
150162

151163
# standard copy then delete

0 commit comments

Comments
 (0)