Skip to content

Commit

Permalink
Fix moving a file/directory to itself.
Browse files Browse the repository at this point in the history
  • Loading branch information
barneygale committed Jul 22, 2024
1 parent be48d2a commit a5ee60a
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1598,8 +1598,9 @@ Copying, moving and deleting
return a new :class:`!Path` instance pointing to *target*.

If the *target* doesn't exist it will be created. If both this path and the
*target* are existing files, then the target is overwritten. If the
*target* is a non-empty directory, :exc:`OSError` is raised.
*target* are existing files, then the target is overwritten. If both paths
point to the same file or directory, or the *target* is a non-empty
directory, then :exc:`OSError` is raised.

If both paths are on the same filesystem, the move is performed with
:func:`os.replace`. Otherwise, this path is copied (preserving metadata and
Expand Down
3 changes: 2 additions & 1 deletion Lib/pathlib/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,8 @@ def move(self, target):
"""
Recursively move this file or directory tree to the given destination.
"""

if self._samefile_safe(target):
raise OSError(f"{self!r} and {target!r} are the same file")
try:
return self.replace(target)
except TypeError:
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_pathlib/test_pathlib_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2011,6 +2011,11 @@ def test_move_file_to_dir(self):
target = base / 'dirB'
self.assertRaises(OSError, source.move, target)

def test_move_file_to_itself(self):
base = self.cls(self.base)
source = base / 'fileA'
self.assertRaises(OSError, source.move, source)

def test_move_dir(self):
base = self.cls(self.base)
source = base / 'dirC'
Expand All @@ -2033,6 +2038,11 @@ def test_move_dir_to_dir(self):
target = base / 'dirB'
self.assertRaises(OSError, source.move, target)

def test_move_dir_to_itself(self):
base = self.cls(self.base)
source = base / 'dirC'
self.assertRaises(OSError, source.move, source)

def test_move_dir_into_itself(self):
base = self.cls(self.base)
source = base / 'dirC'
Expand Down

0 comments on commit a5ee60a

Please sign in to comment.