Skip to content

Commit

Permalink
pythonGH-127381: pathlib ABCs: remove PathBase.rename() and `replac…
Browse files Browse the repository at this point in the history
…e()`

These methods are obviated by `PathBase.move()`, which can move directories
and supports any `PathBase` object as a target.
  • Loading branch information
barneygale committed Dec 5, 2024
1 parent 8b3cccf commit 55bb68b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 38 deletions.
37 changes: 1 addition & 36 deletions Lib/pathlib/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import functools
import operator
import posixpath
from errno import EINVAL, EXDEV
from errno import EINVAL
from glob import _GlobberBase, _no_recurse_symlinks
from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
from pathlib._os import copyfileobj
Expand Down Expand Up @@ -902,45 +902,10 @@ def copy_into(self, target_dir, *, follow_symlinks=True,
dirs_exist_ok=dirs_exist_ok,
preserve_metadata=preserve_metadata)

def rename(self, target):
"""
Rename this path to the target path.
The target path may be absolute or relative. Relative paths are
interpreted relative to the current working directory, *not* the
directory of the Path object.
Returns the new Path instance pointing to the target path.
"""
raise UnsupportedOperation(self._unsupported_msg('rename()'))

def replace(self, target):
"""
Rename this path to the target path, overwriting if that path exists.
The target path may be absolute or relative. Relative paths are
interpreted relative to the current working directory, *not* the
directory of the Path object.
Returns the new Path instance pointing to the target path.
"""
raise UnsupportedOperation(self._unsupported_msg('replace()'))

def move(self, target):
"""
Recursively move this file or directory tree to the given destination.
"""
self._ensure_different_file(target)
try:
return self.replace(target)
except UnsupportedOperation:
pass
except TypeError:
if not isinstance(target, PathBase):
raise
except OSError as err:
if err.errno != EXDEV:
raise
target = self.copy(target, follow_symlinks=False, preserve_metadata=True)
self._delete()
return target
Expand Down
17 changes: 17 additions & 0 deletions Lib/pathlib/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import posixpath
import sys
from errno import EXDEV
from glob import _StringGlobber
from itertools import chain
from _collections_abc import Sequence
Expand Down Expand Up @@ -876,6 +877,22 @@ def replace(self, target):
os.replace(self, target)
return self.with_segments(target)

def move(self, target):
"""
Recursively move this file or directory tree to the given destination.
"""
self._ensure_different_file(target)
try:
return self.replace(target)
except TypeError:
if not isinstance(target, PathBase):
raise
except OSError as err:
if err.errno != EXDEV:
raise
# Fall back to copy+delete.
return PathBase.move(self, target)

if hasattr(os, "symlink"):
def symlink_to(self, target, target_is_directory=False):
"""
Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_pathlib/test_pathlib_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1376,8 +1376,6 @@ def test_unsupported_operation(self):
self.assertRaises(e, p.hardlink_to, 'foo')
self.assertRaises(e, p.mkdir)
self.assertRaises(e, p.touch)
self.assertRaises(e, p.rename, 'foo')
self.assertRaises(e, p.replace, 'foo')
self.assertRaises(e, p.chmod, 0o755)
self.assertRaises(e, p.lchmod, 0o755)
self.assertRaises(e, p.unlink)
Expand Down

0 comments on commit 55bb68b

Please sign in to comment.