Eryk Sun <[email protected]> added the comment:
It seems to me that if `path == name`, then resetperms(path) and possibly a
recursive call are only needed on the first call. In subsequent calls, if `path
== name`, then we know that resetperms(path) was already called, so it
shouldn't handle PermissionError. If resetperms was ineffective (e.g. in
Windows, a sharing violation or custom discretionary/mandatory permissions), or
if something else changed the permissions in the mean time, just give up
instead of risking a RecursionError or stack overflow. For example:
@classmethod
def _rmtree(cls, name, first_call=True):
resetperms_funcs = (_os.unlink, _os.rmdir, _os.scandir, _os.open)
def resetperms(path):
try:
_os.chflags(path, 0)
except AttributeError:
pass
_os.chmod(path, 0o700)
def onerror(func, path, exc_info):
if (issubclass(exc_info[0], PermissionError) and
func in resetperms_funcs and (first_call or path != name)):
try:
if path != name:
resetperms(_os.path.dirname(path))
resetperms(path)
try:
_os.unlink(path)
# PermissionError is raised on FreeBSD for directories
except (IsADirectoryError, PermissionError):
cls._rmtree(path, first_call=False)
except FileNotFoundError:
pass
elif issubclass(exc_info[0], FileNotFoundError):
pass
else:
raise
_shutil.rmtree(name, onerror=onerror)
----------
nosy: +eryksun
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue35144>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com