-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-43153: Don't mask PermissionError
with NotADirectoryError
during tempdirectory cleanup
#29940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5111fa7
b3da7cd
0673393
98725c8
283df0a
b9f074f
b658bfc
11a31ac
499e424
bfd39ea
45d5dea
77f5e8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ | |
import io as _io | ||
import os as _os | ||
import shutil as _shutil | ||
import stat as _stat | ||
import errno as _errno | ||
from random import Random as _Random | ||
import sys as _sys | ||
|
@@ -889,8 +890,31 @@ def resetperms(path): | |
|
||
try: | ||
_os.unlink(path) | ||
# PermissionError is raised on FreeBSD for directories | ||
except (IsADirectoryError, PermissionError): | ||
except IsADirectoryError: | ||
cls._rmtree(path, ignore_errors=ignore_errors) | ||
except PermissionError: | ||
# The PermissionError handler was originally added for | ||
# FreeBSD in directories, but it seems that it is raised | ||
# on Windows too. | ||
# bpo-43153: Calling _rmtree again may | ||
# raise NotADirectoryError and mask the PermissionError. | ||
# So we must re-raise the current PermissionError if | ||
# path is not a directory. | ||
try: | ||
st = _os.lstat(path) | ||
except OSError: | ||
if ignore_errors: | ||
return | ||
raise | ||
if (_stat.S_ISLNK(st.st_mode) or | ||
not _stat.S_ISDIR(st.st_mode) or | ||
(hasattr(st, 'st_file_attributes') and | ||
st.st_file_attributes & _stat.FILE_ATTRIBUTE_REPARSE_POINT and | ||
st.st_reparse_tag == _stat.IO_REPARSE_TAG_MOUNT_POINT) | ||
): | ||
if ignore_errors: | ||
return | ||
raise | ||
cls._rmtree(path, ignore_errors=ignore_errors) | ||
Comment on lines
891
to
918
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not go with an "ask-for-forgiveness-rather-than-permission" type of solution, e.g.: try:
_os.unlink(path)
except IsADirectoryError:
cls._rmtree(path, ignore_errors=ignore_errors)
except PermissionError as pe:
# PermissionError is raised on FreeBSD for directories
# and by Windows on lock files used by other processes
try:
cls._rmtree(path, ignore_errors=ignore_errors)
except NotADirectoryError:
# NOTE: This is raised if PermissionError did not
# correspond to a IsADirectoryError, e.g. on
# Windows.
if not ignore_errors:
raise pe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmmh... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like a responsibility inversion to me. Sure there could be a bug deep down in Also I see the diff I commented on is not the final version so I'll look at the final version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not necessary a bug. It may be a race condition. Although the LBYL approach is also prone to race conditions, I think it has less chance to override error with a wrong exception. I myself prefer the EAFP approach, but I do not think that it has advantages in this case. |
||
except FileNotFoundError: | ||
pass | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
On Windows, ``tempfile.TemporaryDirectory`` previously masked a | ||
``PermissionError`` with ``NotADirectoryError`` during directory cleanup. It | ||
now correctly raises ``PermissionError`` if errors are not ignored. Patch by | ||
Andrei Kulakov and Ken Jin. |
Uh oh!
There was an error while loading. Please reload this page.