Skip to content

Commit 8199fd5

Browse files
committed
Undo changes from pythonGH-122924.
1 parent b8372aa commit 8199fd5

File tree

3 files changed

+37
-53
lines changed

3 files changed

+37
-53
lines changed

Lib/pathlib/_abc.py

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
resemble pathlib's PurePath and Path respectively.
1212
"""
1313

14-
import errno
1514
import functools
1615
import operator
1716
import posixpath
17+
from errno import EXDEV
1818
from glob import _GlobberBase, _no_recurse_symlinks
1919
from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
2020
from pathlib._os import copyfileobj
@@ -565,33 +565,14 @@ def samefile(self, other_path):
565565
return (st.st_ino == other_st.st_ino and
566566
st.st_dev == other_st.st_dev)
567567

568-
def _check_files_differ(self, other_path):
568+
def _samefile_safe(self, other_path):
569569
"""
570-
Raise OSError(EINVAL) if both paths refer to the same file.
570+
Like samefile(), but returns False rather than raising OSError.
571571
"""
572572
try:
573-
if not self.samefile(other_path):
574-
return
573+
return self.samefile(other_path)
575574
except (OSError, ValueError):
576-
return
577-
err = OSError(errno.EINVAL, "Source and target are the same file")
578-
err.filename = str(self)
579-
err.filename2 = str(other_path)
580-
raise err
581-
582-
def _check_paths_disjoint(self, other_path):
583-
"""
584-
Raise OSError(EINVAL) if the other path is within this path.
585-
"""
586-
if self == other_path:
587-
err = OSError(errno.EINVAL, "Source and target are the same path")
588-
elif self in other_path.parents:
589-
err = OSError(errno.EINVAL, "Source path is a parent of target path")
590-
else:
591-
return
592-
err.filename = str(self)
593-
err.filename2 = str(other_path)
594-
raise err
575+
return False
595576

596577
def open(self, mode='r', buffering=-1, encoding=None,
597578
errors=None, newline=None):
@@ -846,7 +827,8 @@ def _copy_file(self, target):
846827
"""
847828
Copy the contents of this file to the given target.
848829
"""
849-
self._check_files_differ(target)
830+
if self._samefile_safe(target):
831+
raise OSError(f"{self!r} and {target!r} are the same file")
850832
with self.open('rb') as source_f:
851833
try:
852834
with target.open('wb') as target_f:
@@ -866,13 +848,6 @@ def copy(self, target, *, follow_symlinks=True, dirs_exist_ok=False,
866848
"""
867849
if not isinstance(target, PathBase):
868850
target = self.with_segments(target)
869-
try:
870-
self._check_paths_disjoint(target)
871-
except OSError as err:
872-
if on_error is None:
873-
raise
874-
on_error(err)
875-
return
876851
stack = [(self, target)]
877852
while stack:
878853
src, dst = stack.pop()
@@ -927,7 +902,8 @@ def move(self, target):
927902
"""
928903
Recursively move this file or directory tree to the given destination.
929904
"""
930-
self._check_files_differ(target)
905+
if self._samefile_safe(target):
906+
raise OSError(f"{self!r} and {target!r} are the same file")
931907
try:
932908
return self.replace(target)
933909
except UnsupportedOperation:
@@ -936,7 +912,7 @@ def move(self, target):
936912
if not isinstance(target, PathBase):
937913
raise
938914
except OSError as err:
939-
if err.errno != errno.EXDEV:
915+
if err.errno != EXDEV:
940916
raise
941917
target = self.copy(target, follow_symlinks=False, preserve_metadata=True)
942918
self.delete()

Lib/test/test_pathlib/test_pathlib.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,11 +793,21 @@ def test_move_dir_into_itself_other_fs(self):
793793
def test_move_file_symlink_other_fs(self):
794794
self.test_move_file_symlink()
795795

796+
@patch_replace
797+
@needs_symlinks
798+
def test_move_file_symlink_to_itself_other_fs(self):
799+
self.test_move_file_symlink_to_itself()
800+
796801
@patch_replace
797802
@needs_symlinks
798803
def test_move_dir_symlink_other_fs(self):
799804
self.test_move_dir_symlink()
800805

806+
@patch_replace
807+
@needs_symlinks
808+
def test_move_dir_symlink_to_itself_other_fs(self):
809+
self.test_move_dir_symlink_to_itself()
810+
801811
@patch_replace
802812
@needs_symlinks
803813
def test_move_dangling_symlink_other_fs(self):

Lib/test/test_pathlib/test_pathlib_abc.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,12 +1825,6 @@ def test_copy_file_empty(self):
18251825
self.assertTrue(target.exists())
18261826
self.assertEqual(target.read_bytes(), b'')
18271827

1828-
def test_copy_file_to_itself(self):
1829-
base = self.cls(self.base)
1830-
source = base / 'empty'
1831-
source.write_bytes(b'')
1832-
self.assertRaises(OSError, source.copy, source)
1833-
18341828
def test_copy_dir_simple(self):
18351829
base = self.cls(self.base)
18361830
source = base / 'dirC'
@@ -1917,19 +1911,6 @@ def test_copy_dir_to_existing_directory_dirs_exist_ok(self):
19171911
self.assertTrue(target.joinpath('fileC').read_text(),
19181912
"this is file C\n")
19191913

1920-
def test_copy_dir_to_itself(self):
1921-
base = self.cls(self.base)
1922-
source = base / 'dirC'
1923-
self.assertRaises(OSError, source.copy, source)
1924-
1925-
def test_copy_dir_to_itself_on_error(self):
1926-
base = self.cls(self.base)
1927-
source = base / 'dirC'
1928-
errors = []
1929-
source.copy(source, on_error=errors.append)
1930-
self.assertEqual(len(errors), 1)
1931-
self.assertIsInstance(errors[0], OSError)
1932-
19331914
def test_copy_missing_on_error(self):
19341915
base = self.cls(self.base)
19351916
source = base / 'foo'
@@ -2056,17 +2037,22 @@ def test_move_dir_to_dir(self):
20562037
source = base / 'dirC'
20572038
target = base / 'dirB'
20582039
self.assertRaises(OSError, source.move, target)
2040+
self.assertTrue(source.exists())
2041+
self.assertTrue(target.exists())
20592042

20602043
def test_move_dir_to_itself(self):
20612044
base = self.cls(self.base)
20622045
source = base / 'dirC'
20632046
self.assertRaises(OSError, source.move, source)
2047+
self.assertTrue(source.exists())
20642048

20652049
def test_move_dir_into_itself(self):
20662050
base = self.cls(self.base)
20672051
source = base / 'dirC'
20682052
target = base / 'dirC' / 'bar'
20692053
self.assertRaises(OSError, source.move, target)
2054+
self.assertTrue(source.exists())
2055+
self.assertFalse(target.exists())
20702056

20712057
@needs_symlinks
20722058
def test_move_file_symlink(self):
@@ -2080,6 +2066,12 @@ def test_move_file_symlink(self):
20802066
self.assertTrue(target.is_symlink())
20812067
self.assertEqual(source_readlink, target.readlink())
20822068

2069+
@needs_symlinks
2070+
def test_move_file_symlink_to_itself(self):
2071+
base = self.cls(self.base)
2072+
source = base / 'linkA'
2073+
self.assertRaises(OSError, source.move, source)
2074+
20832075
@needs_symlinks
20842076
def test_move_dir_symlink(self):
20852077
base = self.cls(self.base)
@@ -2092,6 +2084,12 @@ def test_move_dir_symlink(self):
20922084
self.assertTrue(target.is_symlink())
20932085
self.assertEqual(source_readlink, target.readlink())
20942086

2087+
@needs_symlinks
2088+
def test_move_dir_symlink_to_itself(self):
2089+
base = self.cls(self.base)
2090+
source = base / 'linkB'
2091+
self.assertRaises(OSError, source.move, source)
2092+
20952093
@needs_symlinks
20962094
def test_move_dangling_symlink(self):
20972095
base = self.cls(self.base)

0 commit comments

Comments
 (0)