mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
GH-73991: Add pathlib.Path.copy()
(#119058)
Add a `Path.copy()` method that copies the content of one file to another. This method is similar to `shutil.copyfile()` but differs in the following ways: - Uses `fcntl.FICLONE` where available (see GH-81338) - Uses `os.copy_file_range` where available (see GH-81340) - Uses `_winapi.CopyFile2` where available, even though this copies more metadata than the other implementations. This makes `WindowsPath.copy()` more similar to `shutil.copy2()`. The method is presently _less_ specified than the `shutil` functions to allow OS-specific optimizations that might copy more or less metadata. Incorporates code from GH-81338 and GH-93152. Co-authored-by: Eryk Sun <eryksun@gmail.com>
This commit is contained in:
parent
2bacc2343c
commit
7c38097add
7 changed files with 271 additions and 2 deletions
|
@ -1696,6 +1696,68 @@ class DummyPathTest(DummyPurePathTest):
|
|||
self.assertEqual((p / 'fileA').read_bytes(),
|
||||
b'abcde' + os_linesep_byte + b'fghlk' + os_linesep_byte + b'\rmnopq')
|
||||
|
||||
def test_copy_file(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'fileA'
|
||||
target = base / 'copyA'
|
||||
source.copy(target)
|
||||
self.assertTrue(target.exists())
|
||||
self.assertEqual(source.read_text(), target.read_text())
|
||||
|
||||
def test_copy_directory(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'dirA'
|
||||
target = base / 'copyA'
|
||||
with self.assertRaises(OSError):
|
||||
source.copy(target)
|
||||
|
||||
@needs_symlinks
|
||||
def test_copy_symlink(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'linkA'
|
||||
target = base / 'copyA'
|
||||
source.copy(target)
|
||||
self.assertTrue(target.exists())
|
||||
self.assertFalse(target.is_symlink())
|
||||
self.assertEqual(source.read_text(), target.read_text())
|
||||
|
||||
def test_copy_to_existing_file(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'fileA'
|
||||
target = base / 'dirB' / 'fileB'
|
||||
source.copy(target)
|
||||
self.assertTrue(target.exists())
|
||||
self.assertEqual(source.read_text(), target.read_text())
|
||||
|
||||
def test_copy_to_existing_directory(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'fileA'
|
||||
target = base / 'dirA'
|
||||
with self.assertRaises(OSError):
|
||||
source.copy(target)
|
||||
|
||||
@needs_symlinks
|
||||
def test_copy_to_existing_symlink(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'dirB' / 'fileB'
|
||||
target = base / 'linkA'
|
||||
real_target = base / 'fileA'
|
||||
source.copy(target)
|
||||
self.assertTrue(target.exists())
|
||||
self.assertTrue(target.is_symlink())
|
||||
self.assertTrue(real_target.exists())
|
||||
self.assertFalse(real_target.is_symlink())
|
||||
self.assertEqual(source.read_text(), real_target.read_text())
|
||||
|
||||
def test_copy_empty(self):
|
||||
base = self.cls(self.base)
|
||||
source = base / 'empty'
|
||||
target = base / 'copyA'
|
||||
source.write_bytes(b'')
|
||||
source.copy(target)
|
||||
self.assertTrue(target.exists())
|
||||
self.assertEqual(target.read_bytes(), b'')
|
||||
|
||||
def test_iterdir(self):
|
||||
P = self.cls
|
||||
p = P(self.base)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue