diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-05-31 08:30:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-31 08:30:37 (GMT) |
commit | e9b51c0ad81da1da11ae65840ac8b50a8521373c (patch) | |
tree | 612f275e9aa504fdf3e5e18d736f19bf56fdb06f /Lib/tempfile.py | |
parent | 38ab7d4721b422547f7b46b9d68968863fa70573 (diff) | |
download | cpython-e9b51c0ad81da1da11ae65840ac8b50a8521373c.zip cpython-e9b51c0ad81da1da11ae65840ac8b50a8521373c.tar.gz cpython-e9b51c0ad81da1da11ae65840ac8b50a8521373c.tar.bz2 |
bpo-26660, bpo-35144: Fix permission errors in TemporaryDirectory cleanup. (GH-10320)
TemporaryDirectory.cleanup() failed when non-writeable or non-searchable
files or directories were created inside a temporary directory.
Diffstat (limited to 'Lib/tempfile.py')
-rw-r--r-- | Lib/tempfile.py | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py index a66d6f3..e8b111e 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -778,8 +778,38 @@ class TemporaryDirectory(object): warn_message="Implicitly cleaning up {!r}".format(self)) @classmethod + def _rmtree(cls, name): + def onerror(func, path, exc_info): + if issubclass(exc_info[0], PermissionError): + def resetperms(path): + try: + _os.chflags(path, 0) + except AttributeError: + pass + _os.chmod(path, 0o700) + + 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) + except FileNotFoundError: + pass + elif issubclass(exc_info[0], FileNotFoundError): + pass + else: + raise + + _shutil.rmtree(name, onerror=onerror) + + @classmethod def _cleanup(cls, name, warn_message): - _shutil.rmtree(name) + cls._rmtree(name) _warnings.warn(warn_message, ResourceWarning) def __repr__(self): @@ -793,4 +823,4 @@ class TemporaryDirectory(object): def cleanup(self): if self._finalizer.detach(): - _shutil.rmtree(self.name) + self._rmtree(self.name) |