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:
Barney Gale 2024-06-14 17:15:49 +01:00 committed by GitHub
parent 2bacc2343c
commit 7c38097add
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 271 additions and 2 deletions

View file

@ -18,6 +18,7 @@ except ImportError:
grp = None
from ._abc import UnsupportedOperation, PurePathBase, PathBase
from ._os import copyfile
__all__ = [
@ -780,6 +781,21 @@ class Path(PathBase, PurePath):
if not exist_ok or not self.is_dir():
raise
if copyfile:
def copy(self, target):
"""
Copy the contents of this file to the given target.
"""
try:
target = os.fspath(target)
except TypeError:
if isinstance(target, PathBase):
# Target is an instance of PathBase but not os.PathLike.
# Use generic implementation from PathBase.
return PathBase.copy(self, target)
raise
copyfile(os.fspath(self), target)
def chmod(self, mode, *, follow_symlinks=True):
"""
Change the permissions of the path, like os.chmod().