summaryrefslogtreecommitdiffstats
path: root/Lib/tempfile.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/tempfile.py')
-rw-r--r--Lib/tempfile.py28
1 files changed, 26 insertions, 2 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index 2b4f431..55403ad 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -41,6 +41,7 @@ import warnings as _warnings
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 @@ class TemporaryDirectory:
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)
except FileNotFoundError:
pass