The documentation of the pathlib.Path.replace
method states:
Rename this file or directory to the given target. If target points to an existing file or directory, it will be unconditionally replaced.
This lacks a bit of detail. For comparison, here's the documentation of os.replace
:
Rename the file or directory
src
todst
. Ifdst
is a directory,OSError
will be raised. Ifdst
exists and is a file, it will be replaced silently if the user has permission. The operation may fail ifsrc
anddst
are on different filesystems. If successful, the renaming will be an atomic operation (this is a POSIX requirement).
The important part being "The operation may fail if src
and dst
are on different filesystems". Unlike os.replace
, shutil.move
does not have this problem:
If the destination is on the current filesystem, then
os.rename()
is used. Otherwise,src
is copied todst
usingcopy_function
and then removed.
So, which of these functions is Path.replace
using? Is there any risk of Path.replace
failing because the destination is on a different file system?
Path(x).replace(y)
just calls os.replace(x, y)
. You can see this in the source code:
class _NormalAccessor(_Accessor):
# [...]
replace = os.replace
# [...]
_normal_accessor = _NormalAccessor()
# [...]
class Path(PurePath):
# [...]
def _init(self,
# Private non-constructor arguments
template=None,
):
self._closed = False
if template is not None:
self._accessor = template._accessor
else:
self._accessor = _normal_accessor
# [...]
def replace(self, target):
"""
Rename this path to the given path, clobbering the existing
destination if it exists.
"""
if self._closed:
self._raise_closed()
self._accessor.replace(self, target)