mirror of
https://github.com/python/cpython.git
synced 2025-11-01 06:01:29 +00:00
GH-73991: Add follow_symlinks argument to pathlib.Path.copy() (#120519)
Add support for not following symlinks in `pathlib.Path.copy()`. On Windows we add the `COPY_FILE_COPY_SYMLINK` flag is following symlinks is disabled. If the source is symlink to a directory, this call will fail with `ERROR_ACCESS_DENIED`. In this case we add `COPY_FILE_DIRECTORY` to the flags and retry. This can fail on old Windowses, which we note in the docs. No news as `copy()` was only just added.
This commit is contained in:
parent
9f741e55c1
commit
20d5b84f57
6 changed files with 86 additions and 11 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
from errno import EBADF, EOPNOTSUPP, ETXTBSY, EXDEV
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
try:
|
||||
import fcntl
|
||||
|
|
@ -91,12 +92,32 @@ def copyfd(source_fd, target_fd):
|
|||
copyfd = None
|
||||
|
||||
|
||||
if _winapi and hasattr(_winapi, 'CopyFile2'):
|
||||
def copyfile(source, target):
|
||||
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):
|
||||
"""
|
||||
Copy from one file to another using CopyFile2 (Windows only).
|
||||
"""
|
||||
_winapi.CopyFile2(source, target, 0)
|
||||
if follow_symlinks:
|
||||
flags = 0
|
||||
else:
|
||||
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 or not _is_dirlink(source):
|
||||
raise
|
||||
flags |= _winapi.COPY_FILE_DIRECTORY
|
||||
_winapi.CopyFile2(source, target, flags)
|
||||
else:
|
||||
copyfile = None
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue