Skip to content

Conversation

dynamicy
Copy link

@dynamicy dynamicy commented Sep 18, 2025

@bedevere-app
Copy link

bedevere-app bot commented Sep 18, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot
Copy link

python-cla-bot bot commented Sep 18, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app
Copy link

bedevere-app bot commented Sep 18, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@dynamicy dynamicy force-pushed the fix-pathlib-copyfile2-windows-privilege-fallback branch 2 times, most recently from 1461184 to 85637e2 Compare September 18, 2025 16:42
@dynamicy dynamicy marked this pull request as ready for review September 18, 2025 17:08
Copy link
Contributor

@barneygale barneygale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this :-)

Comment on lines 1151 to 1160
try:
copyfile2(source_fspath, str(self))
except OSError as exc:
winerror = getattr(exc, 'winerror', None)
if (_winapi is not None and
winerror in (_winapi.ERROR_PRIVILEGE_NOT_HELD,
_winapi.ERROR_ACCESS_DENIED)):
self._copy_from_file_fallback(source, preserve_metadata)
return
raise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try:
copyfile2(source_fspath, str(self))
except OSError as exc:
winerror = getattr(exc, 'winerror', None)
if (_winapi is not None and
winerror in (_winapi.ERROR_PRIVILEGE_NOT_HELD,
_winapi.ERROR_ACCESS_DENIED)):
self._copy_from_file_fallback(source, preserve_metadata)
return
raise
try:
copyfile2(source_fspath, str(self))
except OSError as exc:
# Use fallback on ERROR_ACCESS_DENIED
# or ERROR_PRIVILEGE_NOT_HELD
if exc.winerror not in (5, 1314):
raise
else:
return

This code is Windows-specific because of the if copyfile2: line above, so we can access exc.winerror directly I think.

We usually hard-code Windows error numbers rather than using _winapi in pathlib - I'm not sure if that's wise but I guess let's be consistent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks—good call. I switched to exc.winerror and check for 5/1314. If we hit either, we fall back to _copy_from_file_fallback; otherwise we re-raise. I also added a tiny comment mapping those to ERROR_ACCESS_DENIED and ERROR_PRIVILEGE_NOT_HELD. Still under the if copyfile2: guard, so Windows-only. Happy to tweak wording or style if you prefer.

@dynamicy dynamicy force-pushed the fix-pathlib-copyfile2-windows-privilege-fallback branch from 5ec9c09 to f5866e7 Compare September 19, 2025 13:55
@dynamicy dynamicy requested a review from barneygale September 19, 2025 15:17
@dynamicy dynamicy force-pushed the fix-pathlib-copyfile2-windows-privilege-fallback branch from f5866e7 to 9d80882 Compare September 19, 2025 16:56
Comment on lines +28 to +31
try:
import _winapi
except ImportError:
_winapi = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try:
import _winapi
except ImportError:
_winapi = None

This is unused now

try:
copyfile2(source_path, str(self))
except OSError as exc:
if hasattr(exc, "winerror") and exc.winerror in (5, 1314):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if hasattr(exc, "winerror") and exc.winerror in (5, 1314):
if exc.winerror in (5, 1314):

IIUC winerror is guaranteed to exist for any OSError raised from CopyFile2().

@@ -0,0 +1 @@
Fix ``pathlib.Path.copy()`` failing on Windows when copying files that require elevated privileges (e.g., hidden or system files) by adding a fallback mechanism when ``copyfile2`` encounters privilege-related errors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Fix ``pathlib.Path.copy()`` failing on Windows when copying files that require elevated privileges (e.g., hidden or system files) by adding a fallback mechanism when ``copyfile2`` encounters privilege-related errors.
Fix :meth:`pathlib.Path.copy` failing on Windows when copying files that require elevated privileges (e.g., hidden or system files) by adding a fallback mechanism when ``CopyFile2()`` encounters privilege-related errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants