mirror of
https://github.com/python/cpython.git
synced 2025-08-02 16:13:13 +00:00
GH-73991: Rework pathlib.Path.copytree()
into copy()
(#122369)
Rename `pathlib.Path.copy()` to `_copy_file()` (i.e. make it private.) Rename `pathlib.Path.copytree()` to `copy()`, and add support for copying non-directories. This simplifies the interface for users, and nicely complements the upcoming `move()` and `delete()` methods (which will also accept any type of file.) Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
This commit is contained in:
parent
ea70439bd2
commit
a6644d4464
10 changed files with 141 additions and 197 deletions
|
@ -20,15 +20,6 @@ except ImportError:
|
|||
_winapi = None
|
||||
|
||||
|
||||
__all__ = ["UnsupportedOperation"]
|
||||
|
||||
|
||||
class UnsupportedOperation(NotImplementedError):
|
||||
"""An exception that is raised when an unsupported operation is attempted.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def get_copy_blocksize(infd):
|
||||
"""Determine blocksize for fastcopying on Linux.
|
||||
Hopefully the whole file will be copied in a single call.
|
||||
|
@ -101,44 +92,12 @@ else:
|
|||
copyfd = None
|
||||
|
||||
|
||||
if _winapi and hasattr(_winapi, 'CopyFile2') and hasattr(os.stat_result, 'st_file_attributes'):
|
||||
def _is_dirlink(path):
|
||||
try:
|
||||
st = os.lstat(path)
|
||||
except (OSError, ValueError):
|
||||
return False
|
||||
return (st.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY and
|
||||
st.st_reparse_tag == stat.IO_REPARSE_TAG_SYMLINK)
|
||||
|
||||
def copyfile(source, target, follow_symlinks):
|
||||
if _winapi and hasattr(_winapi, 'CopyFile2'):
|
||||
def copyfile(source, target):
|
||||
"""
|
||||
Copy from one file to another using CopyFile2 (Windows only).
|
||||
"""
|
||||
if follow_symlinks:
|
||||
_winapi.CopyFile2(source, target, 0)
|
||||
else:
|
||||
# Use COPY_FILE_COPY_SYMLINK to copy a file symlink.
|
||||
flags = _winapi.COPY_FILE_COPY_SYMLINK
|
||||
try:
|
||||
_winapi.CopyFile2(source, target, flags)
|
||||
return
|
||||
except OSError as err:
|
||||
# Check for ERROR_ACCESS_DENIED
|
||||
if err.winerror == 5 and _is_dirlink(source):
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
# Add COPY_FILE_DIRECTORY to copy a directory symlink.
|
||||
flags |= _winapi.COPY_FILE_DIRECTORY
|
||||
try:
|
||||
_winapi.CopyFile2(source, target, flags)
|
||||
except OSError as err:
|
||||
# Check for ERROR_INVALID_PARAMETER
|
||||
if err.winerror == 87:
|
||||
raise UnsupportedOperation(err) from None
|
||||
else:
|
||||
raise
|
||||
_winapi.CopyFile2(source, target, 0)
|
||||
else:
|
||||
copyfile = None
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue