3
This module provides generic, low- and high-level interfaces for
4
creating temporary files and directories. All of the interfaces
5
provided by this module can be used without fear of race conditions
6
except for 'mktemp'. 'mktemp' is subject to race conditions and
7
should not be used; it is provided for backward compatibility only.
9
The default path names are returned as str. If you supply bytes as
10
input, all return values will be in bytes. Ex:
12
>>> tempfile.mkstemp()
13
(4, '/tmp/tmptpu9nin8')
14
>>> tempfile.mkdtemp(suffix=b'')
17
This module also provides some data items to the user:
19
TMP_MAX - maximum number of names that will be tried before
21
tempdir - If this is set to a string before the first use of
22
any routine from this module, it will be considered as
23
another candidate location to store temporary files.
27
"NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
28
"SpooledTemporaryFile", "TemporaryDirectory",
29
"mkstemp", "mkdtemp", # low level safe interfaces
30
"mktemp", # deprecated unsafe interface
31
"TMP_MAX", "gettempprefix", # constants
32
"tempdir", "gettempdir",
33
"gettempprefixb", "gettempdirb",
39
import functools as _functools
40
import warnings as _warnings
43
import shutil as _shutil
44
import errno as _errno
45
from random import Random as _Random
48
import types as _types
49
import weakref as _weakref
51
_allocate_lock = _thread.allocate_lock
53
_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
54
if hasattr(_os, 'O_NOFOLLOW'):
55
_text_openflags |= _os.O_NOFOLLOW
57
_bin_openflags = _text_openflags
58
if hasattr(_os, 'O_BINARY'):
59
_bin_openflags |= _os.O_BINARY
61
# This is more than enough.
62
# Each name contains over 40 random bits. Even with a million temporary
63
# files, the chance of a conflict is less than 1 in a million, and with
64
# 20 attempts, it is less than 1e-120.
67
# This variable _was_ unused for legacy reasons, see issue 10354.
68
# But as of 3.5 we actually use it at runtime so changing it would
69
# have a possibly desirable side effect... But we do not want to support
70
# that as an API. It is undocumented on purpose. Do not depend on this.
75
_once_lock = _allocate_lock()
87
def _infer_return_type(*args):
88
"""Look at the type of all args and divine their implied return type."""
94
if isinstance(arg, _os.PathLike):
97
if isinstance(arg, bytes):
98
if return_type is str:
99
raise TypeError("Can't mix bytes and non-bytes in "
103
if return_type is bytes:
104
raise TypeError("Can't mix bytes and non-bytes in "
107
if return_type is None:
108
if tempdir is None or isinstance(tempdir, str):
109
return str # tempfile APIs return a str by default.
111
# we could check for bytes but it'll fail later on anyway
116
def _sanitize_params(prefix, suffix, dir):
117
"""Common parameter processing for most APIs in this module."""
118
output_type = _infer_return_type(prefix, suffix, dir)
120
suffix = output_type()
122
if output_type is str:
125
prefix = _os.fsencode(template)
127
if output_type is str:
131
return prefix, suffix, dir, output_type
134
class _RandomNameSequence:
135
"""An instance of _RandomNameSequence generates an endless
136
sequence of unpredictable strings which can safely be incorporated
137
into file names. Each string is eight characters long. Multiple
138
threads can safely use the same instance at the same time.
140
_RandomNameSequence is an iterator."""
142
characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
146
cur_pid = _os.getpid()
147
if cur_pid != getattr(self, '_rng_pid', None):
148
self._rng = _Random()
149
self._rng_pid = cur_pid
156
return ''.join(self.rng.choices(self.characters, k=8))
158
def _candidate_tempdir_list():
159
"""Generate a list of candidate temporary directories which
160
_get_default_tempdir will try."""
164
# First, try the environment.
165
for envname in 'TMPDIR', 'TEMP', 'TMP':
166
dirname = _os.getenv(envname)
167
if dirname: dirlist.append(dirname)
169
# Failing that, try OS-specific locations.
171
dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'),
172
_os.path.expandvars(r'%SYSTEMROOT%\Temp'),
173
r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
175
dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])
177
# As a last resort, the current directory.
179
dirlist.append(_os.getcwd())
180
except (AttributeError, OSError):
181
dirlist.append(_os.curdir)
185
def _get_default_tempdir(dirlist=None):
186
"""Calculate the default directory to use for temporary files.
187
This routine should be called exactly once.
189
We determine whether or not a candidate temp dir is usable by
190
trying to create and write to a file in that directory. If this
191
is successful, the test file is deleted. To prevent denial of
192
service, the name of the test file must be randomized."""
194
namer = _RandomNameSequence()
196
dirlist = _candidate_tempdir_list()
199
if dir != _os.curdir:
200
dir = _os.path.abspath(dir)
201
for seq in range(TMP_MAX):
203
filename = _os.path.join(dir, name)
205
fd = _os.open(filename, _bin_openflags, 0o600)
208
_os.write(fd, b'blat')
214
except FileExistsError:
216
except PermissionError:
217
# See the comment in mkdtemp().
218
if _os.name == 'nt' and _os.path.isdir(dir):
220
break # no point trying more names in this directory
222
break # no point trying more names in this directory
223
raise FileNotFoundError(_errno.ENOENT,
224
"No usable temporary directory found in %s" %
227
_name_sequence = None
229
def _get_candidate_names():
230
"""Common setup sequence for all user-callable interfaces."""
232
global _name_sequence
233
if _name_sequence is None:
236
if _name_sequence is None:
237
_name_sequence = _RandomNameSequence()
240
return _name_sequence
243
def _mkstemp_inner(dir, pre, suf, flags, output_type):
244
"""Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
246
dir = _os.path.abspath(dir)
247
names = _get_candidate_names()
248
if output_type is bytes:
249
names = map(_os.fsencode, names)
251
for seq in range(TMP_MAX):
253
1
file = _os.path.join(dir, pre + name + suf)
254
_sys.audit("tempfile.mkstemp", file)
256
24
24
fd = _os.open(file, flags, 0o600)
257
except FileExistsError:
259
except PermissionError:
260
# See the comment in mkdtemp().
261
if _os.name == 'nt' and _os.path.isdir(dir) and seq < TMP_MAX - 1:
267
raise FileExistsError(_errno.EEXIST,
268
"No usable temporary file name found")
270
def _dont_follow_symlinks(func, path, *args):
271
# Pass follow_symlinks=False, unless not supported on this platform.
272
if func in _os.supports_follow_symlinks:
273
func(path, *args, follow_symlinks=False)
274
elif not _os.path.islink(path):
277
def _resetflags(path):
279
chflags = _os.chflags
280
except AttributeError:
283
_dont_follow_symlinks(chflags, path, 0)
285
def _resetperms(path):
287
_dont_follow_symlinks(_os.chmod, path, 0o700)
289
# True if TemporaryDirectory._rmtree() can work relative to open directories
290
# instead of resolving paths again.
291
_rmtree_use_dir_fd = (
292
{_os.chmod, _os.unlink, _os.lstat} <= _os.supports_dir_fd
293
and _os.chmod in _os.supports_fd
296
def _resetperms_fd(dir_fd, path):
297
# Same as _resetperms(), but for the directory referred to by dir_fd.
302
_os.chmod(dir_fd, 0o700)
305
_nofollow_mode = _os.O_RDONLY | _os.O_NONBLOCK | _os.O_NOFOLLOW
306
except AttributeError:
307
_nofollow_mode = None
309
def _resetperms_at(name, dir_fd, path):
310
# Same as _resetperms(), but name is resolved relative to the directory
311
# file descriptor dir_fd. path is only used for os.chflags(), which
312
# doesn't support dir_fd or file descriptors.
317
if _os.chmod in _os.supports_follow_symlinks:
318
_os.chmod(name, 0o700, dir_fd=dir_fd, follow_symlinks=False)
320
# dir_fd & follow_symlinks is not supported on this platform.
321
# Try chmod opening the file with O_NOFOLLOW.
322
if _nofollow_mode is not None:
324
fd = _os.open(name, _nofollow_mode, dir_fd=dir_fd)
333
# If that did not work, we change by name, which is subject to a race
335
stat = _os.lstat(name, dir_fd=dir_fd)
336
if not _stat.S_ISLNK(stat.st_mode):
337
_os.chmod(name, 0o700, dir_fd=dir_fd)
340
# User visible interfaces.
343
"""The default prefix for temporary directories as string."""
344
return _os.fsdecode(template)
346
def gettempprefixb():
347
"""The default prefix for temporary directories as bytes."""
348
return _os.fsencode(template)
353
"""Private accessor for tempfile.tempdir."""
359
tempdir = _get_default_tempdir()
365
"""Returns tempfile.tempdir as str."""
366
return _os.fsdecode(_gettempdir())
369
"""Returns tempfile.tempdir as bytes."""
370
return _os.fsencode(_gettempdir())
372
def mkstemp(suffix=None, prefix=None, dir=None, text=False):
373
"""User-callable function to create and return a unique temporary
374
file. The return value is a pair (fd, name) where fd is the
375
file descriptor returned by os.open, and name is the filename.
377
If 'suffix' is not None, the file name will end with that suffix,
378
otherwise there will be no suffix.
380
If 'prefix' is not None, the file name will begin with that prefix,
381
otherwise a default prefix is used.
383
If 'dir' is not None, the file will be created in that directory,
384
otherwise a default directory is used.
386
If 'text' is specified and true, the file is opened in text
387
mode. Else (the default) the file is opened in binary mode.
389
If any of 'suffix', 'prefix' and 'dir' are not None, they must be the
390
same type. If they are bytes, the returned name will be bytes; str
393
The file is readable and writable only by the creating user ID.
394
If the operating system uses permission bits to indicate whether a
395
file is executable, the file is executable by no one. The file
396
descriptor is not inherited by children of this process.
398
Caller is responsible for deleting the file when done with it.
401
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
404
flags = _text_openflags
406
flags = _bin_openflags
408
return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
411
def mkdtemp(suffix=None, prefix=None, dir=None):
412
"""User-callable function to create and return a unique temporary
413
directory. The return value is the pathname of the directory.
415
Arguments are as for mkstemp, except that the 'text' argument is
418
The directory is readable, writable, and searchable only by the
421
Caller is responsible for deleting the directory when done with it.
424
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
426
names = _get_candidate_names()
427
if output_type is bytes:
428
names = map(_os.fsencode, names)
430
for seq in range(TMP_MAX):
432
file = _os.path.join(dir, prefix + name + suffix)
433
_sys.audit("tempfile.mkdtemp", file)
435
_os.mkdir(file, 0o700)
436
except FileExistsError:
438
except PermissionError:
439
# On Posix, this exception is raised when the user has no
440
# write access to the parent directory.
441
# On Windows, it is also raised when a directory with
442
# the chosen name already exists, or if the parent directory
443
# is not a directory.
444
# We cannot distinguish between "directory-exists-error" and
445
# "access-denied-error".
446
if _os.name == 'nt' and _os.path.isdir(dir) and seq < TMP_MAX - 1:
450
return _os.path.abspath(file)
452
raise FileExistsError(_errno.EEXIST,
453
"No usable temporary directory name found")
455
def mktemp(suffix="", prefix=template, dir=None):
456
"""User-callable function to return a unique temporary file name. The
459
Arguments are similar to mkstemp, except that the 'text' argument is
460
not accepted, and suffix=None, prefix=None and bytes file names are not
463
THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may
464
refer to a file that did not exist at some point, but by the time
465
you get around to creating it, someone else may have beaten you to
469
## from warnings import warn as _warn
470
## _warn("mktemp is a potential security risk to your program",
471
## RuntimeWarning, stacklevel=2)
476
names = _get_candidate_names()
477
for seq in range(TMP_MAX):
479
file = _os.path.join(dir, prefix + name + suffix)
480
if not _exists(file):
483
raise FileExistsError(_errno.EEXIST,
484
"No usable temporary filename found")
487
class _TemporaryFileCloser:
488
"""A separate object allowing proper closing of a temporary file's
489
underlying file object, without adding a __del__ method to the
492
cleanup_called = False
500
delete_on_close=True,
501
warn_message="Implicitly cleaning up unknown file",
506
self.delete_on_close = delete_on_close
507
self.warn_message = warn_message
509
def cleanup(self, windows=(_os.name == 'nt'), unlink=_os.unlink):
510
if not self.cleanup_called:
511
self.cleanup_called = True
513
if not self.close_called:
514
self.close_called = True
517
# Windows provides delete-on-close as a primitive, in which
518
# case the file was deleted by self.file.close().
519
if self.delete and not (windows and self.delete_on_close):
522
except FileNotFoundError:
526
if not self.close_called:
527
self.close_called = True
531
if self.delete and self.delete_on_close:
535
close_called = self.close_called
538
_warnings.warn(self.warn_message, ResourceWarning)
541
class _TemporaryFileWrapper:
542
"""Temporary file wrapper
544
This class provides a wrapper around files opened for
545
temporary use. In particular, it seeks to automatically
546
remove the file when it is no longer needed.
549
def __init__(self, file, name, delete=True, delete_on_close=True):
552
self._closer = _TemporaryFileCloser(
557
warn_message=f"Implicitly cleaning up {self!r}",
561
file = self.__dict__['file']
562
return f"<{type(self).__name__} {file=}>"
564
def __getattr__(self, name):
565
# Attribute lookups are delegated to the underlying file
566
# and cached for non-numeric results
567
# (i.e. methods are cached, closed and friends are not)
568
file = self.__dict__['file']
569
a = getattr(file, name)
570
if hasattr(a, '__call__'):
572
1
1
@_functools.wraps(func)
573
def func_wrapper(*args, **kwargs):
574
33
33
return func(*args, **kwargs)
575
# Avoid closing the file as long as the wrapper is alive,
577
func_wrapper._closer = self._closer
579
if not isinstance(a, int):
580
setattr(self, name, a)
583
# The underlying __enter__ method returns the wrong object
584
# (self.file) so override it to return the wrapper
586
self.file.__enter__()
589
# Need to trap __exit__ as well to ensure the file gets
590
# deleted when used in a with statement
591
def __exit__(self, exc, value, tb):
592
result = self.file.__exit__(exc, value, tb)
593
self._closer.cleanup()
598
Close the temporary file, possibly deleting it.
602
# iter() doesn't use __getattr__ to find the __iter__ method
604
# Don't return iter(self.file), but yield from it to avoid closing
605
# file as long as it's being used as iterator (see issue #23700). We
606
# can't use 'yield from' here because iter(file) returns the file
607
# object itself, which has a close method, and thus the file would get
608
# closed when the generator is finalized, due to PEP380 semantics.
609
for line in self.file:
612
def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
613
newline=None, suffix=None, prefix=None,
614
dir=None, delete=True, *, errors=None,
615
delete_on_close=True):
616
"""Create and return a temporary file.
618
'prefix', 'suffix', 'dir' -- as for mkstemp.
619
'mode' -- the mode argument to io.open (default "w+b").
620
'buffering' -- the buffer size argument to io.open (default -1).
621
'encoding' -- the encoding argument to io.open (default None)
622
'newline' -- the newline argument to io.open (default None)
623
'delete' -- whether the file is automatically deleted (default True).
624
'delete_on_close' -- if 'delete', whether the file is deleted on close
625
(default True) or otherwise either on context manager exit
626
(if context manager was used) or on object finalization. .
627
'errors' -- the errors argument to io.open (default None)
628
The file is created as mkstemp() would do it.
630
Returns an object with a file-like interface; the name of the file
631
is accessible as its 'name' attribute. The file will be automatically
632
deleted when it is closed unless the 'delete' argument is set to False.
634
On POSIX, NamedTemporaryFiles cannot be automatically deleted if
635
the creating process is terminated abruptly with a SIGKILL signal.
636
Windows can delete the file even in this case.
639
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
641
flags = _bin_openflags
643
# Setting O_TEMPORARY in the flags causes the OS to delete
644
# the file when it is closed. This is only supported by Windows.
645
if _os.name == 'nt' and delete and delete_on_close:
646
flags |= _os.O_TEMPORARY
649
encoding = _io.text_encoding(encoding)
654
1
26
fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
657
1
27
file = _io.open(dir, mode, buffering=buffering,
658
newline=newline, encoding=encoding, errors=errors,
661
raw = getattr(file, 'buffer', file)
662
raw = getattr(raw, 'raw', raw)
664
2
2
return _TemporaryFileWrapper(file, name, delete, delete_on_close)
669
if name is not None and not (
670
_os.name == 'nt' and delete and delete_on_close):
674
if _os.name != 'posix' or _sys.platform == 'cygwin':
675
# On non-POSIX and Cygwin systems, assume that we cannot unlink a file
677
TemporaryFile = NamedTemporaryFile
680
# Is the O_TMPFILE flag available and does it work?
681
# The flag is set to False if os.open(dir, os.O_TMPFILE) raises an
682
# IsADirectoryError exception
683
_O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE')
685
def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
686
newline=None, suffix=None, prefix=None,
687
dir=None, *, errors=None):
688
"""Create and return a temporary file.
690
'prefix', 'suffix', 'dir' -- as for mkstemp.
691
'mode' -- the mode argument to io.open (default "w+b").
692
'buffering' -- the buffer size argument to io.open (default -1).
693
'encoding' -- the encoding argument to io.open (default None)
694
'newline' -- the newline argument to io.open (default None)
695
'errors' -- the errors argument to io.open (default None)
696
The file is created as mkstemp() would do it.
698
Returns an object with a file-like interface. The file has no
699
name, and will cease to exist when it is closed.
701
global _O_TMPFILE_WORKS
704
encoding = _io.text_encoding(encoding)
706
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
708
flags = _bin_openflags
713
flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT & ~_os.O_EXCL
714
fd = _os.open(dir, flags2, 0o600)
717
file = _io.open(dir, mode, buffering=buffering,
718
newline=newline, encoding=encoding,
719
errors=errors, opener=opener)
720
raw = getattr(file, 'buffer', file)
721
raw = getattr(raw, 'raw', raw)
724
except IsADirectoryError:
725
# Linux kernel older than 3.11 ignores the O_TMPFILE flag:
726
# O_TMPFILE is read as O_DIRECTORY. Trying to open a directory
727
# with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a
728
# directory cannot be open to write. Set flag to False to not
730
_O_TMPFILE_WORKS = False
732
# The filesystem of the directory does not support O_TMPFILE.
733
# For example, OSError(95, 'Operation not supported').
735
# On Linux kernel older than 3.11, trying to open a regular
736
# file (or a symbolic link to a regular file) with O_TMPFILE
737
# fails with NotADirectoryError, because O_TMPFILE is read as
740
# Fallback to _mkstemp_inner().
745
fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
748
except BaseException:
752
file = _io.open(dir, mode, buffering=buffering,
753
newline=newline, encoding=encoding, errors=errors,
755
raw = getattr(file, 'buffer', file)
756
raw = getattr(raw, 'raw', raw)
760
class SpooledTemporaryFile(_io.IOBase):
761
"""Temporary file wrapper, specialized to switch from BytesIO
762
or StringIO to a real file when it exceeds a certain size or
763
when a fileno is needed.
767
def __init__(self, max_size=0, mode='w+b', buffering=-1,
768
encoding=None, newline=None,
769
suffix=None, prefix=None, dir=None, *, errors=None):
771
self._file = _io.BytesIO()
773
encoding = _io.text_encoding(encoding)
774
self._file = _io.TextIOWrapper(_io.BytesIO(),
775
encoding=encoding, errors=errors,
777
self._max_size = max_size
779
self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
780
'suffix': suffix, 'prefix': prefix,
781
'encoding': encoding, 'newline': newline,
782
'dir': dir, 'errors': errors}
784
__class_getitem__ = classmethod(_types.GenericAlias)
786
def _check(self, file):
787
if self._rolled: return
788
max_size = self._max_size
789
if max_size and file.tell() > max_size:
793
if self._rolled: return
795
newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
796
del self._TemporaryFileArgs
799
if hasattr(newfile, 'buffer'):
800
newfile.buffer.write(file.detach().getvalue())
802
newfile.write(file.getvalue())
807
# The method caching trick from NamedTemporaryFile
808
# won't work here, because _file may change from a
809
# BytesIO/StringIO instance to a real file. So we list
810
# all the methods directly.
812
# Context management protocol
814
if self._file.closed:
815
raise ValueError("Cannot enter context with closed file")
818
def __exit__(self, exc, value, tb):
823
return self._file.__iter__()
828
"Unclosed file {!r}".format(self),
840
return self._file.closed
844
return self._file.encoding
848
return self._file.errors
852
return self._file.fileno()
858
return self._file.isatty()
863
return self._file.mode
864
except AttributeError:
865
return self._TemporaryFileArgs['mode']
870
return self._file.name
871
except AttributeError:
876
return self._file.newlines
879
return self._file.readable()
881
def read(self, *args):
882
1
1
return self._file.read(*args)
884
def read1(self, *args):
885
return self._file.read1(*args)
887
def readinto(self, b):
888
return self._file.readinto(b)
890
def readinto1(self, b):
891
return self._file.readinto1(b)
893
def readline(self, *args):
894
return self._file.readline(*args)
896
def readlines(self, *args):
897
return self._file.readlines(*args)
900
return self._file.seekable()
902
def seek(self, *args):
903
return self._file.seek(*args)
906
return self._file.tell()
908
def truncate(self, size=None):
910
return self._file.truncate()
912
if size > self._max_size:
914
return self._file.truncate(size)
917
return self._file.writable()
925
def writelines(self, iterable):
926
if self._max_size == 0 or self._rolled:
927
return self._file.writelines(iterable)
933
return self._file.writelines(it)
936
return self._file.detach()
939
class TemporaryDirectory:
940
"""Create and return a temporary directory. This has the same
941
behavior as mkdtemp but can be used as a context manager. For
944
with TemporaryDirectory() as tmpdir:
947
Upon exiting the context, the directory and everything contained
948
in it are removed (unless delete=False is passed or an exception
949
is raised during cleanup and ignore_cleanup_errors is not True).
952
suffix - A str suffix for the directory name. (see mkdtemp)
953
prefix - A str prefix for the directory name. (see mkdtemp)
954
dir - A directory to create this temp dir in. (see mkdtemp)
955
ignore_cleanup_errors - False; ignore exceptions during cleanup?
956
delete - True; whether the directory is automatically deleted.
959
def __init__(self, suffix=None, prefix=None, dir=None,
960
ignore_cleanup_errors=False, *, delete=True):
961
self.name = mkdtemp(suffix, prefix, dir)
962
self._ignore_cleanup_errors = ignore_cleanup_errors
963
self._delete = delete
964
self._finalizer = _weakref.finalize(
965
self, self._cleanup, self.name,
966
warn_message="Implicitly cleaning up {!r}".format(self),
967
ignore_errors=self._ignore_cleanup_errors, delete=self._delete)
970
def _rmtree(cls, name, ignore_errors=False, repeated=False, dir_fd=None,
975
def onexc(func, path, exc, direntry=None, dir_fd=None):
976
# On DragonFly BSD, UF_NOUNLINK removal fails with EISDIR, not EPERM.
977
if isinstance(exc, (PermissionError, IsADirectoryError)):
978
if repeated and path == name:
983
# fullpath is path as seen from the working directory
984
fullpath = fullname + path[len(name):]
985
# base is path relative to dir_fd, the directory rmtree()
986
# reached it through, or the whole path when there is none
987
if dir_fd is None or not _rmtree_use_dir_fd:
988
base, dir_fd = path, None
989
elif direntry is None:
996
# The parent directory of path is the one referred to
998
_resetperms_fd(dir_fd, _os.path.dirname(fullpath))
999
_resetperms_at(base, dir_fd, fullpath)
1002
_os.unlink(base, dir_fd=dir_fd)
1003
except IsADirectoryError:
1004
cls._rmtree(base, ignore_errors=ignore_errors,
1005
repeated=(path == name),
1006
dir_fd=dir_fd, fullname=fullpath)
1007
except PermissionError:
1008
# The PermissionError handler was originally added for
1009
# FreeBSD in directories, but it seems that it is raised
1011
# bpo-43153: Calling _rmtree again may
1012
# raise NotADirectoryError and mask the PermissionError.
1013
# So we must re-raise the current PermissionError if
1014
# path is not a directory.
1015
if (not _os.path.isdir(fullpath)
1016
or _os.path.isjunction(fullpath)):
1020
cls._rmtree(base, ignore_errors=ignore_errors,
1021
repeated=(path == name),
1022
dir_fd=dir_fd, fullname=fullpath)
1023
except FileNotFoundError:
1029
elif isinstance(exc, FileNotFoundError):
1032
if not ignore_errors:
1035
_shutil.rmtree(name, onexc=onexc, dir_fd=dir_fd, _onexc_kwargs=True)
1038
def _cleanup(cls, name, warn_message, ignore_errors=False, delete=True):
1040
cls._rmtree(name, ignore_errors=ignore_errors)
1041
_warnings.warn(warn_message, ResourceWarning)
1044
return "<{} {!r}>".format(self.__class__.__name__, self.name)
1046
def __enter__(self):
1049
def __exit__(self, exc, value, tb):
1054
if self._finalizer.detach() or _os.path.exists(self.name):
1055
self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
1057
__class_getitem__ = classmethod(_types.GenericAlias)