mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-88745: Add _winapi.CopyFile2 and update shutil.copy2 to use it (GH-105055)
(cherry picked from commit cda1bd3c9d
)
Co-authored-by: Steve Dower <steve.dower@python.org>
This commit is contained in:
parent
aeee5a5756
commit
9ae49e3f3b
9 changed files with 1214 additions and 988 deletions
|
@ -42,6 +42,8 @@ elif _WINDOWS:
|
|||
|
||||
if sys.platform == 'win32':
|
||||
import _winapi
|
||||
else:
|
||||
_winapi = None
|
||||
|
||||
COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024
|
||||
# This should never be removed, see rationale in:
|
||||
|
@ -435,6 +437,29 @@ def copy2(src, dst, *, follow_symlinks=True):
|
|||
"""
|
||||
if os.path.isdir(dst):
|
||||
dst = os.path.join(dst, os.path.basename(src))
|
||||
|
||||
if hasattr(_winapi, "CopyFile2"):
|
||||
src_ = os.fsdecode(src)
|
||||
dst_ = os.fsdecode(dst)
|
||||
flags = _winapi.COPY_FILE_ALLOW_DECRYPTED_DESTINATION # for compat
|
||||
if not follow_symlinks:
|
||||
flags |= _winapi.COPY_FILE_COPY_SYMLINK
|
||||
try:
|
||||
_winapi.CopyFile2(src_, dst_, flags)
|
||||
return dst
|
||||
except OSError as exc:
|
||||
if (exc.winerror == _winapi.ERROR_PRIVILEGE_NOT_HELD
|
||||
and not follow_symlinks):
|
||||
# Likely encountered a symlink we aren't allowed to create.
|
||||
# Fall back on the old code
|
||||
pass
|
||||
elif exc.winerror == _winapi.ERROR_ACCESS_DENIED:
|
||||
# Possibly encountered a hidden or readonly file we can't
|
||||
# overwrite. Fall back on old code
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
copyfile(src, dst, follow_symlinks=follow_symlinks)
|
||||
copystat(src, dst, follow_symlinks=follow_symlinks)
|
||||
return dst
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue