xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/tempfile.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Temporary files.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerThis module provides generic, low- and high-level interfaces for
4*cda5da8dSAndroid Build Coastguard Workercreating temporary files and directories.  All of the interfaces
5*cda5da8dSAndroid Build Coastguard Workerprovided by this module can be used without fear of race conditions
6*cda5da8dSAndroid Build Coastguard Workerexcept for 'mktemp'.  'mktemp' is subject to race conditions and
7*cda5da8dSAndroid Build Coastguard Workershould not be used; it is provided for backward compatibility only.
8*cda5da8dSAndroid Build Coastguard Worker
9*cda5da8dSAndroid Build Coastguard WorkerThe default path names are returned as str.  If you supply bytes as
10*cda5da8dSAndroid Build Coastguard Workerinput, all return values will be in bytes.  Ex:
11*cda5da8dSAndroid Build Coastguard Worker
12*cda5da8dSAndroid Build Coastguard Worker    >>> tempfile.mkstemp()
13*cda5da8dSAndroid Build Coastguard Worker    (4, '/tmp/tmptpu9nin8')
14*cda5da8dSAndroid Build Coastguard Worker    >>> tempfile.mkdtemp(suffix=b'')
15*cda5da8dSAndroid Build Coastguard Worker    b'/tmp/tmppbi8f0hy'
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard WorkerThis module also provides some data items to the user:
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard Worker  TMP_MAX  - maximum number of names that will be tried before
20*cda5da8dSAndroid Build Coastguard Worker             giving up.
21*cda5da8dSAndroid Build Coastguard Worker  tempdir  - If this is set to a string before the first use of
22*cda5da8dSAndroid Build Coastguard Worker             any routine from this module, it will be considered as
23*cda5da8dSAndroid Build Coastguard Worker             another candidate location to store temporary files.
24*cda5da8dSAndroid Build Coastguard Worker"""
25*cda5da8dSAndroid Build Coastguard Worker
26*cda5da8dSAndroid Build Coastguard Worker__all__ = [
27*cda5da8dSAndroid Build Coastguard Worker    "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
28*cda5da8dSAndroid Build Coastguard Worker    "SpooledTemporaryFile", "TemporaryDirectory",
29*cda5da8dSAndroid Build Coastguard Worker    "mkstemp", "mkdtemp",                  # low level safe interfaces
30*cda5da8dSAndroid Build Coastguard Worker    "mktemp",                              # deprecated unsafe interface
31*cda5da8dSAndroid Build Coastguard Worker    "TMP_MAX", "gettempprefix",            # constants
32*cda5da8dSAndroid Build Coastguard Worker    "tempdir", "gettempdir",
33*cda5da8dSAndroid Build Coastguard Worker    "gettempprefixb", "gettempdirb",
34*cda5da8dSAndroid Build Coastguard Worker   ]
35*cda5da8dSAndroid Build Coastguard Worker
36*cda5da8dSAndroid Build Coastguard Worker
37*cda5da8dSAndroid Build Coastguard Worker# Imports.
38*cda5da8dSAndroid Build Coastguard Worker
39*cda5da8dSAndroid Build Coastguard Workerimport functools as _functools
40*cda5da8dSAndroid Build Coastguard Workerimport warnings as _warnings
41*cda5da8dSAndroid Build Coastguard Workerimport io as _io
42*cda5da8dSAndroid Build Coastguard Workerimport os as _os
43*cda5da8dSAndroid Build Coastguard Workerimport shutil as _shutil
44*cda5da8dSAndroid Build Coastguard Workerimport errno as _errno
45*cda5da8dSAndroid Build Coastguard Workerfrom random import Random as _Random
46*cda5da8dSAndroid Build Coastguard Workerimport sys as _sys
47*cda5da8dSAndroid Build Coastguard Workerimport types as _types
48*cda5da8dSAndroid Build Coastguard Workerimport weakref as _weakref
49*cda5da8dSAndroid Build Coastguard Workerimport _thread
50*cda5da8dSAndroid Build Coastguard Worker_allocate_lock = _thread.allocate_lock
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Worker_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
53*cda5da8dSAndroid Build Coastguard Workerif hasattr(_os, 'O_NOFOLLOW'):
54*cda5da8dSAndroid Build Coastguard Worker    _text_openflags |= _os.O_NOFOLLOW
55*cda5da8dSAndroid Build Coastguard Worker
56*cda5da8dSAndroid Build Coastguard Worker_bin_openflags = _text_openflags
57*cda5da8dSAndroid Build Coastguard Workerif hasattr(_os, 'O_BINARY'):
58*cda5da8dSAndroid Build Coastguard Worker    _bin_openflags |= _os.O_BINARY
59*cda5da8dSAndroid Build Coastguard Worker
60*cda5da8dSAndroid Build Coastguard Workerif hasattr(_os, 'TMP_MAX'):
61*cda5da8dSAndroid Build Coastguard Worker    TMP_MAX = _os.TMP_MAX
62*cda5da8dSAndroid Build Coastguard Workerelse:
63*cda5da8dSAndroid Build Coastguard Worker    TMP_MAX = 10000
64*cda5da8dSAndroid Build Coastguard Worker
65*cda5da8dSAndroid Build Coastguard Worker# This variable _was_ unused for legacy reasons, see issue 10354.
66*cda5da8dSAndroid Build Coastguard Worker# But as of 3.5 we actually use it at runtime so changing it would
67*cda5da8dSAndroid Build Coastguard Worker# have a possibly desirable side effect...  But we do not want to support
68*cda5da8dSAndroid Build Coastguard Worker# that as an API.  It is undocumented on purpose.  Do not depend on this.
69*cda5da8dSAndroid Build Coastguard Workertemplate = "tmp"
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Worker# Internal routines.
72*cda5da8dSAndroid Build Coastguard Worker
73*cda5da8dSAndroid Build Coastguard Worker_once_lock = _allocate_lock()
74*cda5da8dSAndroid Build Coastguard Worker
75*cda5da8dSAndroid Build Coastguard Worker
76*cda5da8dSAndroid Build Coastguard Workerdef _exists(fn):
77*cda5da8dSAndroid Build Coastguard Worker    try:
78*cda5da8dSAndroid Build Coastguard Worker        _os.lstat(fn)
79*cda5da8dSAndroid Build Coastguard Worker    except OSError:
80*cda5da8dSAndroid Build Coastguard Worker        return False
81*cda5da8dSAndroid Build Coastguard Worker    else:
82*cda5da8dSAndroid Build Coastguard Worker        return True
83*cda5da8dSAndroid Build Coastguard Worker
84*cda5da8dSAndroid Build Coastguard Worker
85*cda5da8dSAndroid Build Coastguard Workerdef _infer_return_type(*args):
86*cda5da8dSAndroid Build Coastguard Worker    """Look at the type of all args and divine their implied return type."""
87*cda5da8dSAndroid Build Coastguard Worker    return_type = None
88*cda5da8dSAndroid Build Coastguard Worker    for arg in args:
89*cda5da8dSAndroid Build Coastguard Worker        if arg is None:
90*cda5da8dSAndroid Build Coastguard Worker            continue
91*cda5da8dSAndroid Build Coastguard Worker
92*cda5da8dSAndroid Build Coastguard Worker        if isinstance(arg, _os.PathLike):
93*cda5da8dSAndroid Build Coastguard Worker            arg = _os.fspath(arg)
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker        if isinstance(arg, bytes):
96*cda5da8dSAndroid Build Coastguard Worker            if return_type is str:
97*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("Can't mix bytes and non-bytes in "
98*cda5da8dSAndroid Build Coastguard Worker                                "path components.")
99*cda5da8dSAndroid Build Coastguard Worker            return_type = bytes
100*cda5da8dSAndroid Build Coastguard Worker        else:
101*cda5da8dSAndroid Build Coastguard Worker            if return_type is bytes:
102*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("Can't mix bytes and non-bytes in "
103*cda5da8dSAndroid Build Coastguard Worker                                "path components.")
104*cda5da8dSAndroid Build Coastguard Worker            return_type = str
105*cda5da8dSAndroid Build Coastguard Worker    if return_type is None:
106*cda5da8dSAndroid Build Coastguard Worker        if tempdir is None or isinstance(tempdir, str):
107*cda5da8dSAndroid Build Coastguard Worker            return str  # tempfile APIs return a str by default.
108*cda5da8dSAndroid Build Coastguard Worker        else:
109*cda5da8dSAndroid Build Coastguard Worker            # we could check for bytes but it'll fail later on anyway
110*cda5da8dSAndroid Build Coastguard Worker            return bytes
111*cda5da8dSAndroid Build Coastguard Worker    return return_type
112*cda5da8dSAndroid Build Coastguard Worker
113*cda5da8dSAndroid Build Coastguard Worker
114*cda5da8dSAndroid Build Coastguard Workerdef _sanitize_params(prefix, suffix, dir):
115*cda5da8dSAndroid Build Coastguard Worker    """Common parameter processing for most APIs in this module."""
116*cda5da8dSAndroid Build Coastguard Worker    output_type = _infer_return_type(prefix, suffix, dir)
117*cda5da8dSAndroid Build Coastguard Worker    if suffix is None:
118*cda5da8dSAndroid Build Coastguard Worker        suffix = output_type()
119*cda5da8dSAndroid Build Coastguard Worker    if prefix is None:
120*cda5da8dSAndroid Build Coastguard Worker        if output_type is str:
121*cda5da8dSAndroid Build Coastguard Worker            prefix = template
122*cda5da8dSAndroid Build Coastguard Worker        else:
123*cda5da8dSAndroid Build Coastguard Worker            prefix = _os.fsencode(template)
124*cda5da8dSAndroid Build Coastguard Worker    if dir is None:
125*cda5da8dSAndroid Build Coastguard Worker        if output_type is str:
126*cda5da8dSAndroid Build Coastguard Worker            dir = gettempdir()
127*cda5da8dSAndroid Build Coastguard Worker        else:
128*cda5da8dSAndroid Build Coastguard Worker            dir = gettempdirb()
129*cda5da8dSAndroid Build Coastguard Worker    return prefix, suffix, dir, output_type
130*cda5da8dSAndroid Build Coastguard Worker
131*cda5da8dSAndroid Build Coastguard Worker
132*cda5da8dSAndroid Build Coastguard Workerclass _RandomNameSequence:
133*cda5da8dSAndroid Build Coastguard Worker    """An instance of _RandomNameSequence generates an endless
134*cda5da8dSAndroid Build Coastguard Worker    sequence of unpredictable strings which can safely be incorporated
135*cda5da8dSAndroid Build Coastguard Worker    into file names.  Each string is eight characters long.  Multiple
136*cda5da8dSAndroid Build Coastguard Worker    threads can safely use the same instance at the same time.
137*cda5da8dSAndroid Build Coastguard Worker
138*cda5da8dSAndroid Build Coastguard Worker    _RandomNameSequence is an iterator."""
139*cda5da8dSAndroid Build Coastguard Worker
140*cda5da8dSAndroid Build Coastguard Worker    characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
141*cda5da8dSAndroid Build Coastguard Worker
142*cda5da8dSAndroid Build Coastguard Worker    @property
143*cda5da8dSAndroid Build Coastguard Worker    def rng(self):
144*cda5da8dSAndroid Build Coastguard Worker        cur_pid = _os.getpid()
145*cda5da8dSAndroid Build Coastguard Worker        if cur_pid != getattr(self, '_rng_pid', None):
146*cda5da8dSAndroid Build Coastguard Worker            self._rng = _Random()
147*cda5da8dSAndroid Build Coastguard Worker            self._rng_pid = cur_pid
148*cda5da8dSAndroid Build Coastguard Worker        return self._rng
149*cda5da8dSAndroid Build Coastguard Worker
150*cda5da8dSAndroid Build Coastguard Worker    def __iter__(self):
151*cda5da8dSAndroid Build Coastguard Worker        return self
152*cda5da8dSAndroid Build Coastguard Worker
153*cda5da8dSAndroid Build Coastguard Worker    def __next__(self):
154*cda5da8dSAndroid Build Coastguard Worker        return ''.join(self.rng.choices(self.characters, k=8))
155*cda5da8dSAndroid Build Coastguard Worker
156*cda5da8dSAndroid Build Coastguard Workerdef _candidate_tempdir_list():
157*cda5da8dSAndroid Build Coastguard Worker    """Generate a list of candidate temporary directories which
158*cda5da8dSAndroid Build Coastguard Worker    _get_default_tempdir will try."""
159*cda5da8dSAndroid Build Coastguard Worker
160*cda5da8dSAndroid Build Coastguard Worker    dirlist = []
161*cda5da8dSAndroid Build Coastguard Worker
162*cda5da8dSAndroid Build Coastguard Worker    # First, try the environment.
163*cda5da8dSAndroid Build Coastguard Worker    for envname in 'TMPDIR', 'TEMP', 'TMP':
164*cda5da8dSAndroid Build Coastguard Worker        dirname = _os.getenv(envname)
165*cda5da8dSAndroid Build Coastguard Worker        if dirname: dirlist.append(dirname)
166*cda5da8dSAndroid Build Coastguard Worker
167*cda5da8dSAndroid Build Coastguard Worker    # Failing that, try OS-specific locations.
168*cda5da8dSAndroid Build Coastguard Worker    if _os.name == 'nt':
169*cda5da8dSAndroid Build Coastguard Worker        dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'),
170*cda5da8dSAndroid Build Coastguard Worker                         _os.path.expandvars(r'%SYSTEMROOT%\Temp'),
171*cda5da8dSAndroid Build Coastguard Worker                         r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
172*cda5da8dSAndroid Build Coastguard Worker    else:
173*cda5da8dSAndroid Build Coastguard Worker        dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])
174*cda5da8dSAndroid Build Coastguard Worker
175*cda5da8dSAndroid Build Coastguard Worker    # As a last resort, the current directory.
176*cda5da8dSAndroid Build Coastguard Worker    try:
177*cda5da8dSAndroid Build Coastguard Worker        dirlist.append(_os.getcwd())
178*cda5da8dSAndroid Build Coastguard Worker    except (AttributeError, OSError):
179*cda5da8dSAndroid Build Coastguard Worker        dirlist.append(_os.curdir)
180*cda5da8dSAndroid Build Coastguard Worker
181*cda5da8dSAndroid Build Coastguard Worker    return dirlist
182*cda5da8dSAndroid Build Coastguard Worker
183*cda5da8dSAndroid Build Coastguard Workerdef _get_default_tempdir():
184*cda5da8dSAndroid Build Coastguard Worker    """Calculate the default directory to use for temporary files.
185*cda5da8dSAndroid Build Coastguard Worker    This routine should be called exactly once.
186*cda5da8dSAndroid Build Coastguard Worker
187*cda5da8dSAndroid Build Coastguard Worker    We determine whether or not a candidate temp dir is usable by
188*cda5da8dSAndroid Build Coastguard Worker    trying to create and write to a file in that directory.  If this
189*cda5da8dSAndroid Build Coastguard Worker    is successful, the test file is deleted.  To prevent denial of
190*cda5da8dSAndroid Build Coastguard Worker    service, the name of the test file must be randomized."""
191*cda5da8dSAndroid Build Coastguard Worker
192*cda5da8dSAndroid Build Coastguard Worker    namer = _RandomNameSequence()
193*cda5da8dSAndroid Build Coastguard Worker    dirlist = _candidate_tempdir_list()
194*cda5da8dSAndroid Build Coastguard Worker
195*cda5da8dSAndroid Build Coastguard Worker    for dir in dirlist:
196*cda5da8dSAndroid Build Coastguard Worker        if dir != _os.curdir:
197*cda5da8dSAndroid Build Coastguard Worker            dir = _os.path.abspath(dir)
198*cda5da8dSAndroid Build Coastguard Worker        # Try only a few names per directory.
199*cda5da8dSAndroid Build Coastguard Worker        for seq in range(100):
200*cda5da8dSAndroid Build Coastguard Worker            name = next(namer)
201*cda5da8dSAndroid Build Coastguard Worker            filename = _os.path.join(dir, name)
202*cda5da8dSAndroid Build Coastguard Worker            try:
203*cda5da8dSAndroid Build Coastguard Worker                fd = _os.open(filename, _bin_openflags, 0o600)
204*cda5da8dSAndroid Build Coastguard Worker                try:
205*cda5da8dSAndroid Build Coastguard Worker                    try:
206*cda5da8dSAndroid Build Coastguard Worker                        _os.write(fd, b'blat')
207*cda5da8dSAndroid Build Coastguard Worker                    finally:
208*cda5da8dSAndroid Build Coastguard Worker                        _os.close(fd)
209*cda5da8dSAndroid Build Coastguard Worker                finally:
210*cda5da8dSAndroid Build Coastguard Worker                    _os.unlink(filename)
211*cda5da8dSAndroid Build Coastguard Worker                return dir
212*cda5da8dSAndroid Build Coastguard Worker            except FileExistsError:
213*cda5da8dSAndroid Build Coastguard Worker                pass
214*cda5da8dSAndroid Build Coastguard Worker            except PermissionError:
215*cda5da8dSAndroid Build Coastguard Worker                # This exception is thrown when a directory with the chosen name
216*cda5da8dSAndroid Build Coastguard Worker                # already exists on windows.
217*cda5da8dSAndroid Build Coastguard Worker                if (_os.name == 'nt' and _os.path.isdir(dir) and
218*cda5da8dSAndroid Build Coastguard Worker                    _os.access(dir, _os.W_OK)):
219*cda5da8dSAndroid Build Coastguard Worker                    continue
220*cda5da8dSAndroid Build Coastguard Worker                break   # no point trying more names in this directory
221*cda5da8dSAndroid Build Coastguard Worker            except OSError:
222*cda5da8dSAndroid Build Coastguard Worker                break   # no point trying more names in this directory
223*cda5da8dSAndroid Build Coastguard Worker    raise FileNotFoundError(_errno.ENOENT,
224*cda5da8dSAndroid Build Coastguard Worker                            "No usable temporary directory found in %s" %
225*cda5da8dSAndroid Build Coastguard Worker                            dirlist)
226*cda5da8dSAndroid Build Coastguard Worker
227*cda5da8dSAndroid Build Coastguard Worker_name_sequence = None
228*cda5da8dSAndroid Build Coastguard Worker
229*cda5da8dSAndroid Build Coastguard Workerdef _get_candidate_names():
230*cda5da8dSAndroid Build Coastguard Worker    """Common setup sequence for all user-callable interfaces."""
231*cda5da8dSAndroid Build Coastguard Worker
232*cda5da8dSAndroid Build Coastguard Worker    global _name_sequence
233*cda5da8dSAndroid Build Coastguard Worker    if _name_sequence is None:
234*cda5da8dSAndroid Build Coastguard Worker        _once_lock.acquire()
235*cda5da8dSAndroid Build Coastguard Worker        try:
236*cda5da8dSAndroid Build Coastguard Worker            if _name_sequence is None:
237*cda5da8dSAndroid Build Coastguard Worker                _name_sequence = _RandomNameSequence()
238*cda5da8dSAndroid Build Coastguard Worker        finally:
239*cda5da8dSAndroid Build Coastguard Worker            _once_lock.release()
240*cda5da8dSAndroid Build Coastguard Worker    return _name_sequence
241*cda5da8dSAndroid Build Coastguard Worker
242*cda5da8dSAndroid Build Coastguard Worker
243*cda5da8dSAndroid Build Coastguard Workerdef _mkstemp_inner(dir, pre, suf, flags, output_type):
244*cda5da8dSAndroid Build Coastguard Worker    """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
245*cda5da8dSAndroid Build Coastguard Worker
246*cda5da8dSAndroid Build Coastguard Worker    dir = _os.path.abspath(dir)
247*cda5da8dSAndroid Build Coastguard Worker    names = _get_candidate_names()
248*cda5da8dSAndroid Build Coastguard Worker    if output_type is bytes:
249*cda5da8dSAndroid Build Coastguard Worker        names = map(_os.fsencode, names)
250*cda5da8dSAndroid Build Coastguard Worker
251*cda5da8dSAndroid Build Coastguard Worker    for seq in range(TMP_MAX):
252*cda5da8dSAndroid Build Coastguard Worker        name = next(names)
253*cda5da8dSAndroid Build Coastguard Worker        file = _os.path.join(dir, pre + name + suf)
254*cda5da8dSAndroid Build Coastguard Worker        _sys.audit("tempfile.mkstemp", file)
255*cda5da8dSAndroid Build Coastguard Worker        try:
256*cda5da8dSAndroid Build Coastguard Worker            fd = _os.open(file, flags, 0o600)
257*cda5da8dSAndroid Build Coastguard Worker        except FileExistsError:
258*cda5da8dSAndroid Build Coastguard Worker            continue    # try again
259*cda5da8dSAndroid Build Coastguard Worker        except PermissionError:
260*cda5da8dSAndroid Build Coastguard Worker            # This exception is thrown when a directory with the chosen name
261*cda5da8dSAndroid Build Coastguard Worker            # already exists on windows.
262*cda5da8dSAndroid Build Coastguard Worker            if (_os.name == 'nt' and _os.path.isdir(dir) and
263*cda5da8dSAndroid Build Coastguard Worker                _os.access(dir, _os.W_OK)):
264*cda5da8dSAndroid Build Coastguard Worker                continue
265*cda5da8dSAndroid Build Coastguard Worker            else:
266*cda5da8dSAndroid Build Coastguard Worker                raise
267*cda5da8dSAndroid Build Coastguard Worker        return fd, file
268*cda5da8dSAndroid Build Coastguard Worker
269*cda5da8dSAndroid Build Coastguard Worker    raise FileExistsError(_errno.EEXIST,
270*cda5da8dSAndroid Build Coastguard Worker                          "No usable temporary file name found")
271*cda5da8dSAndroid Build Coastguard Worker
272*cda5da8dSAndroid Build Coastguard Worker
273*cda5da8dSAndroid Build Coastguard Worker# User visible interfaces.
274*cda5da8dSAndroid Build Coastguard Worker
275*cda5da8dSAndroid Build Coastguard Workerdef gettempprefix():
276*cda5da8dSAndroid Build Coastguard Worker    """The default prefix for temporary directories as string."""
277*cda5da8dSAndroid Build Coastguard Worker    return _os.fsdecode(template)
278*cda5da8dSAndroid Build Coastguard Worker
279*cda5da8dSAndroid Build Coastguard Workerdef gettempprefixb():
280*cda5da8dSAndroid Build Coastguard Worker    """The default prefix for temporary directories as bytes."""
281*cda5da8dSAndroid Build Coastguard Worker    return _os.fsencode(template)
282*cda5da8dSAndroid Build Coastguard Worker
283*cda5da8dSAndroid Build Coastguard Workertempdir = None
284*cda5da8dSAndroid Build Coastguard Worker
285*cda5da8dSAndroid Build Coastguard Workerdef _gettempdir():
286*cda5da8dSAndroid Build Coastguard Worker    """Private accessor for tempfile.tempdir."""
287*cda5da8dSAndroid Build Coastguard Worker    global tempdir
288*cda5da8dSAndroid Build Coastguard Worker    if tempdir is None:
289*cda5da8dSAndroid Build Coastguard Worker        _once_lock.acquire()
290*cda5da8dSAndroid Build Coastguard Worker        try:
291*cda5da8dSAndroid Build Coastguard Worker            if tempdir is None:
292*cda5da8dSAndroid Build Coastguard Worker                tempdir = _get_default_tempdir()
293*cda5da8dSAndroid Build Coastguard Worker        finally:
294*cda5da8dSAndroid Build Coastguard Worker            _once_lock.release()
295*cda5da8dSAndroid Build Coastguard Worker    return tempdir
296*cda5da8dSAndroid Build Coastguard Worker
297*cda5da8dSAndroid Build Coastguard Workerdef gettempdir():
298*cda5da8dSAndroid Build Coastguard Worker    """Returns tempfile.tempdir as str."""
299*cda5da8dSAndroid Build Coastguard Worker    return _os.fsdecode(_gettempdir())
300*cda5da8dSAndroid Build Coastguard Worker
301*cda5da8dSAndroid Build Coastguard Workerdef gettempdirb():
302*cda5da8dSAndroid Build Coastguard Worker    """Returns tempfile.tempdir as bytes."""
303*cda5da8dSAndroid Build Coastguard Worker    return _os.fsencode(_gettempdir())
304*cda5da8dSAndroid Build Coastguard Worker
305*cda5da8dSAndroid Build Coastguard Workerdef mkstemp(suffix=None, prefix=None, dir=None, text=False):
306*cda5da8dSAndroid Build Coastguard Worker    """User-callable function to create and return a unique temporary
307*cda5da8dSAndroid Build Coastguard Worker    file.  The return value is a pair (fd, name) where fd is the
308*cda5da8dSAndroid Build Coastguard Worker    file descriptor returned by os.open, and name is the filename.
309*cda5da8dSAndroid Build Coastguard Worker
310*cda5da8dSAndroid Build Coastguard Worker    If 'suffix' is not None, the file name will end with that suffix,
311*cda5da8dSAndroid Build Coastguard Worker    otherwise there will be no suffix.
312*cda5da8dSAndroid Build Coastguard Worker
313*cda5da8dSAndroid Build Coastguard Worker    If 'prefix' is not None, the file name will begin with that prefix,
314*cda5da8dSAndroid Build Coastguard Worker    otherwise a default prefix is used.
315*cda5da8dSAndroid Build Coastguard Worker
316*cda5da8dSAndroid Build Coastguard Worker    If 'dir' is not None, the file will be created in that directory,
317*cda5da8dSAndroid Build Coastguard Worker    otherwise a default directory is used.
318*cda5da8dSAndroid Build Coastguard Worker
319*cda5da8dSAndroid Build Coastguard Worker    If 'text' is specified and true, the file is opened in text
320*cda5da8dSAndroid Build Coastguard Worker    mode.  Else (the default) the file is opened in binary mode.
321*cda5da8dSAndroid Build Coastguard Worker
322*cda5da8dSAndroid Build Coastguard Worker    If any of 'suffix', 'prefix' and 'dir' are not None, they must be the
323*cda5da8dSAndroid Build Coastguard Worker    same type.  If they are bytes, the returned name will be bytes; str
324*cda5da8dSAndroid Build Coastguard Worker    otherwise.
325*cda5da8dSAndroid Build Coastguard Worker
326*cda5da8dSAndroid Build Coastguard Worker    The file is readable and writable only by the creating user ID.
327*cda5da8dSAndroid Build Coastguard Worker    If the operating system uses permission bits to indicate whether a
328*cda5da8dSAndroid Build Coastguard Worker    file is executable, the file is executable by no one. The file
329*cda5da8dSAndroid Build Coastguard Worker    descriptor is not inherited by children of this process.
330*cda5da8dSAndroid Build Coastguard Worker
331*cda5da8dSAndroid Build Coastguard Worker    Caller is responsible for deleting the file when done with it.
332*cda5da8dSAndroid Build Coastguard Worker    """
333*cda5da8dSAndroid Build Coastguard Worker
334*cda5da8dSAndroid Build Coastguard Worker    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
335*cda5da8dSAndroid Build Coastguard Worker
336*cda5da8dSAndroid Build Coastguard Worker    if text:
337*cda5da8dSAndroid Build Coastguard Worker        flags = _text_openflags
338*cda5da8dSAndroid Build Coastguard Worker    else:
339*cda5da8dSAndroid Build Coastguard Worker        flags = _bin_openflags
340*cda5da8dSAndroid Build Coastguard Worker
341*cda5da8dSAndroid Build Coastguard Worker    return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
342*cda5da8dSAndroid Build Coastguard Worker
343*cda5da8dSAndroid Build Coastguard Worker
344*cda5da8dSAndroid Build Coastguard Workerdef mkdtemp(suffix=None, prefix=None, dir=None):
345*cda5da8dSAndroid Build Coastguard Worker    """User-callable function to create and return a unique temporary
346*cda5da8dSAndroid Build Coastguard Worker    directory.  The return value is the pathname of the directory.
347*cda5da8dSAndroid Build Coastguard Worker
348*cda5da8dSAndroid Build Coastguard Worker    Arguments are as for mkstemp, except that the 'text' argument is
349*cda5da8dSAndroid Build Coastguard Worker    not accepted.
350*cda5da8dSAndroid Build Coastguard Worker
351*cda5da8dSAndroid Build Coastguard Worker    The directory is readable, writable, and searchable only by the
352*cda5da8dSAndroid Build Coastguard Worker    creating user.
353*cda5da8dSAndroid Build Coastguard Worker
354*cda5da8dSAndroid Build Coastguard Worker    Caller is responsible for deleting the directory when done with it.
355*cda5da8dSAndroid Build Coastguard Worker    """
356*cda5da8dSAndroid Build Coastguard Worker
357*cda5da8dSAndroid Build Coastguard Worker    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
358*cda5da8dSAndroid Build Coastguard Worker
359*cda5da8dSAndroid Build Coastguard Worker    names = _get_candidate_names()
360*cda5da8dSAndroid Build Coastguard Worker    if output_type is bytes:
361*cda5da8dSAndroid Build Coastguard Worker        names = map(_os.fsencode, names)
362*cda5da8dSAndroid Build Coastguard Worker
363*cda5da8dSAndroid Build Coastguard Worker    for seq in range(TMP_MAX):
364*cda5da8dSAndroid Build Coastguard Worker        name = next(names)
365*cda5da8dSAndroid Build Coastguard Worker        file = _os.path.join(dir, prefix + name + suffix)
366*cda5da8dSAndroid Build Coastguard Worker        _sys.audit("tempfile.mkdtemp", file)
367*cda5da8dSAndroid Build Coastguard Worker        try:
368*cda5da8dSAndroid Build Coastguard Worker            _os.mkdir(file, 0o700)
369*cda5da8dSAndroid Build Coastguard Worker        except FileExistsError:
370*cda5da8dSAndroid Build Coastguard Worker            continue    # try again
371*cda5da8dSAndroid Build Coastguard Worker        except PermissionError:
372*cda5da8dSAndroid Build Coastguard Worker            # This exception is thrown when a directory with the chosen name
373*cda5da8dSAndroid Build Coastguard Worker            # already exists on windows.
374*cda5da8dSAndroid Build Coastguard Worker            if (_os.name == 'nt' and _os.path.isdir(dir) and
375*cda5da8dSAndroid Build Coastguard Worker                _os.access(dir, _os.W_OK)):
376*cda5da8dSAndroid Build Coastguard Worker                continue
377*cda5da8dSAndroid Build Coastguard Worker            else:
378*cda5da8dSAndroid Build Coastguard Worker                raise
379*cda5da8dSAndroid Build Coastguard Worker        return file
380*cda5da8dSAndroid Build Coastguard Worker
381*cda5da8dSAndroid Build Coastguard Worker    raise FileExistsError(_errno.EEXIST,
382*cda5da8dSAndroid Build Coastguard Worker                          "No usable temporary directory name found")
383*cda5da8dSAndroid Build Coastguard Worker
384*cda5da8dSAndroid Build Coastguard Workerdef mktemp(suffix="", prefix=template, dir=None):
385*cda5da8dSAndroid Build Coastguard Worker    """User-callable function to return a unique temporary file name.  The
386*cda5da8dSAndroid Build Coastguard Worker    file is not created.
387*cda5da8dSAndroid Build Coastguard Worker
388*cda5da8dSAndroid Build Coastguard Worker    Arguments are similar to mkstemp, except that the 'text' argument is
389*cda5da8dSAndroid Build Coastguard Worker    not accepted, and suffix=None, prefix=None and bytes file names are not
390*cda5da8dSAndroid Build Coastguard Worker    supported.
391*cda5da8dSAndroid Build Coastguard Worker
392*cda5da8dSAndroid Build Coastguard Worker    THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED.  The file name may
393*cda5da8dSAndroid Build Coastguard Worker    refer to a file that did not exist at some point, but by the time
394*cda5da8dSAndroid Build Coastguard Worker    you get around to creating it, someone else may have beaten you to
395*cda5da8dSAndroid Build Coastguard Worker    the punch.
396*cda5da8dSAndroid Build Coastguard Worker    """
397*cda5da8dSAndroid Build Coastguard Worker
398*cda5da8dSAndroid Build Coastguard Worker##    from warnings import warn as _warn
399*cda5da8dSAndroid Build Coastguard Worker##    _warn("mktemp is a potential security risk to your program",
400*cda5da8dSAndroid Build Coastguard Worker##          RuntimeWarning, stacklevel=2)
401*cda5da8dSAndroid Build Coastguard Worker
402*cda5da8dSAndroid Build Coastguard Worker    if dir is None:
403*cda5da8dSAndroid Build Coastguard Worker        dir = gettempdir()
404*cda5da8dSAndroid Build Coastguard Worker
405*cda5da8dSAndroid Build Coastguard Worker    names = _get_candidate_names()
406*cda5da8dSAndroid Build Coastguard Worker    for seq in range(TMP_MAX):
407*cda5da8dSAndroid Build Coastguard Worker        name = next(names)
408*cda5da8dSAndroid Build Coastguard Worker        file = _os.path.join(dir, prefix + name + suffix)
409*cda5da8dSAndroid Build Coastguard Worker        if not _exists(file):
410*cda5da8dSAndroid Build Coastguard Worker            return file
411*cda5da8dSAndroid Build Coastguard Worker
412*cda5da8dSAndroid Build Coastguard Worker    raise FileExistsError(_errno.EEXIST,
413*cda5da8dSAndroid Build Coastguard Worker                          "No usable temporary filename found")
414*cda5da8dSAndroid Build Coastguard Worker
415*cda5da8dSAndroid Build Coastguard Worker
416*cda5da8dSAndroid Build Coastguard Workerclass _TemporaryFileCloser:
417*cda5da8dSAndroid Build Coastguard Worker    """A separate object allowing proper closing of a temporary file's
418*cda5da8dSAndroid Build Coastguard Worker    underlying file object, without adding a __del__ method to the
419*cda5da8dSAndroid Build Coastguard Worker    temporary file."""
420*cda5da8dSAndroid Build Coastguard Worker
421*cda5da8dSAndroid Build Coastguard Worker    file = None  # Set here since __del__ checks it
422*cda5da8dSAndroid Build Coastguard Worker    close_called = False
423*cda5da8dSAndroid Build Coastguard Worker
424*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, file, name, delete=True):
425*cda5da8dSAndroid Build Coastguard Worker        self.file = file
426*cda5da8dSAndroid Build Coastguard Worker        self.name = name
427*cda5da8dSAndroid Build Coastguard Worker        self.delete = delete
428*cda5da8dSAndroid Build Coastguard Worker
429*cda5da8dSAndroid Build Coastguard Worker    # NT provides delete-on-close as a primitive, so we don't need
430*cda5da8dSAndroid Build Coastguard Worker    # the wrapper to do anything special.  We still use it so that
431*cda5da8dSAndroid Build Coastguard Worker    # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
432*cda5da8dSAndroid Build Coastguard Worker    if _os.name != 'nt':
433*cda5da8dSAndroid Build Coastguard Worker        # Cache the unlinker so we don't get spurious errors at
434*cda5da8dSAndroid Build Coastguard Worker        # shutdown when the module-level "os" is None'd out.  Note
435*cda5da8dSAndroid Build Coastguard Worker        # that this must be referenced as self.unlink, because the
436*cda5da8dSAndroid Build Coastguard Worker        # name TemporaryFileWrapper may also get None'd out before
437*cda5da8dSAndroid Build Coastguard Worker        # __del__ is called.
438*cda5da8dSAndroid Build Coastguard Worker
439*cda5da8dSAndroid Build Coastguard Worker        def close(self, unlink=_os.unlink):
440*cda5da8dSAndroid Build Coastguard Worker            if not self.close_called and self.file is not None:
441*cda5da8dSAndroid Build Coastguard Worker                self.close_called = True
442*cda5da8dSAndroid Build Coastguard Worker                try:
443*cda5da8dSAndroid Build Coastguard Worker                    self.file.close()
444*cda5da8dSAndroid Build Coastguard Worker                finally:
445*cda5da8dSAndroid Build Coastguard Worker                    if self.delete:
446*cda5da8dSAndroid Build Coastguard Worker                        unlink(self.name)
447*cda5da8dSAndroid Build Coastguard Worker
448*cda5da8dSAndroid Build Coastguard Worker        # Need to ensure the file is deleted on __del__
449*cda5da8dSAndroid Build Coastguard Worker        def __del__(self):
450*cda5da8dSAndroid Build Coastguard Worker            self.close()
451*cda5da8dSAndroid Build Coastguard Worker
452*cda5da8dSAndroid Build Coastguard Worker    else:
453*cda5da8dSAndroid Build Coastguard Worker        def close(self):
454*cda5da8dSAndroid Build Coastguard Worker            if not self.close_called:
455*cda5da8dSAndroid Build Coastguard Worker                self.close_called = True
456*cda5da8dSAndroid Build Coastguard Worker                self.file.close()
457*cda5da8dSAndroid Build Coastguard Worker
458*cda5da8dSAndroid Build Coastguard Worker
459*cda5da8dSAndroid Build Coastguard Workerclass _TemporaryFileWrapper:
460*cda5da8dSAndroid Build Coastguard Worker    """Temporary file wrapper
461*cda5da8dSAndroid Build Coastguard Worker
462*cda5da8dSAndroid Build Coastguard Worker    This class provides a wrapper around files opened for
463*cda5da8dSAndroid Build Coastguard Worker    temporary use.  In particular, it seeks to automatically
464*cda5da8dSAndroid Build Coastguard Worker    remove the file when it is no longer needed.
465*cda5da8dSAndroid Build Coastguard Worker    """
466*cda5da8dSAndroid Build Coastguard Worker
467*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, file, name, delete=True):
468*cda5da8dSAndroid Build Coastguard Worker        self.file = file
469*cda5da8dSAndroid Build Coastguard Worker        self.name = name
470*cda5da8dSAndroid Build Coastguard Worker        self.delete = delete
471*cda5da8dSAndroid Build Coastguard Worker        self._closer = _TemporaryFileCloser(file, name, delete)
472*cda5da8dSAndroid Build Coastguard Worker
473*cda5da8dSAndroid Build Coastguard Worker    def __getattr__(self, name):
474*cda5da8dSAndroid Build Coastguard Worker        # Attribute lookups are delegated to the underlying file
475*cda5da8dSAndroid Build Coastguard Worker        # and cached for non-numeric results
476*cda5da8dSAndroid Build Coastguard Worker        # (i.e. methods are cached, closed and friends are not)
477*cda5da8dSAndroid Build Coastguard Worker        file = self.__dict__['file']
478*cda5da8dSAndroid Build Coastguard Worker        a = getattr(file, name)
479*cda5da8dSAndroid Build Coastguard Worker        if hasattr(a, '__call__'):
480*cda5da8dSAndroid Build Coastguard Worker            func = a
481*cda5da8dSAndroid Build Coastguard Worker            @_functools.wraps(func)
482*cda5da8dSAndroid Build Coastguard Worker            def func_wrapper(*args, **kwargs):
483*cda5da8dSAndroid Build Coastguard Worker                return func(*args, **kwargs)
484*cda5da8dSAndroid Build Coastguard Worker            # Avoid closing the file as long as the wrapper is alive,
485*cda5da8dSAndroid Build Coastguard Worker            # see issue #18879.
486*cda5da8dSAndroid Build Coastguard Worker            func_wrapper._closer = self._closer
487*cda5da8dSAndroid Build Coastguard Worker            a = func_wrapper
488*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(a, int):
489*cda5da8dSAndroid Build Coastguard Worker            setattr(self, name, a)
490*cda5da8dSAndroid Build Coastguard Worker        return a
491*cda5da8dSAndroid Build Coastguard Worker
492*cda5da8dSAndroid Build Coastguard Worker    # The underlying __enter__ method returns the wrong object
493*cda5da8dSAndroid Build Coastguard Worker    # (self.file) so override it to return the wrapper
494*cda5da8dSAndroid Build Coastguard Worker    def __enter__(self):
495*cda5da8dSAndroid Build Coastguard Worker        self.file.__enter__()
496*cda5da8dSAndroid Build Coastguard Worker        return self
497*cda5da8dSAndroid Build Coastguard Worker
498*cda5da8dSAndroid Build Coastguard Worker    # Need to trap __exit__ as well to ensure the file gets
499*cda5da8dSAndroid Build Coastguard Worker    # deleted when used in a with statement
500*cda5da8dSAndroid Build Coastguard Worker    def __exit__(self, exc, value, tb):
501*cda5da8dSAndroid Build Coastguard Worker        result = self.file.__exit__(exc, value, tb)
502*cda5da8dSAndroid Build Coastguard Worker        self.close()
503*cda5da8dSAndroid Build Coastguard Worker        return result
504*cda5da8dSAndroid Build Coastguard Worker
505*cda5da8dSAndroid Build Coastguard Worker    def close(self):
506*cda5da8dSAndroid Build Coastguard Worker        """
507*cda5da8dSAndroid Build Coastguard Worker        Close the temporary file, possibly deleting it.
508*cda5da8dSAndroid Build Coastguard Worker        """
509*cda5da8dSAndroid Build Coastguard Worker        self._closer.close()
510*cda5da8dSAndroid Build Coastguard Worker
511*cda5da8dSAndroid Build Coastguard Worker    # iter() doesn't use __getattr__ to find the __iter__ method
512*cda5da8dSAndroid Build Coastguard Worker    def __iter__(self):
513*cda5da8dSAndroid Build Coastguard Worker        # Don't return iter(self.file), but yield from it to avoid closing
514*cda5da8dSAndroid Build Coastguard Worker        # file as long as it's being used as iterator (see issue #23700).  We
515*cda5da8dSAndroid Build Coastguard Worker        # can't use 'yield from' here because iter(file) returns the file
516*cda5da8dSAndroid Build Coastguard Worker        # object itself, which has a close method, and thus the file would get
517*cda5da8dSAndroid Build Coastguard Worker        # closed when the generator is finalized, due to PEP380 semantics.
518*cda5da8dSAndroid Build Coastguard Worker        for line in self.file:
519*cda5da8dSAndroid Build Coastguard Worker            yield line
520*cda5da8dSAndroid Build Coastguard Worker
521*cda5da8dSAndroid Build Coastguard Worker
522*cda5da8dSAndroid Build Coastguard Workerdef NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
523*cda5da8dSAndroid Build Coastguard Worker                       newline=None, suffix=None, prefix=None,
524*cda5da8dSAndroid Build Coastguard Worker                       dir=None, delete=True, *, errors=None):
525*cda5da8dSAndroid Build Coastguard Worker    """Create and return a temporary file.
526*cda5da8dSAndroid Build Coastguard Worker    Arguments:
527*cda5da8dSAndroid Build Coastguard Worker    'prefix', 'suffix', 'dir' -- as for mkstemp.
528*cda5da8dSAndroid Build Coastguard Worker    'mode' -- the mode argument to io.open (default "w+b").
529*cda5da8dSAndroid Build Coastguard Worker    'buffering' -- the buffer size argument to io.open (default -1).
530*cda5da8dSAndroid Build Coastguard Worker    'encoding' -- the encoding argument to io.open (default None)
531*cda5da8dSAndroid Build Coastguard Worker    'newline' -- the newline argument to io.open (default None)
532*cda5da8dSAndroid Build Coastguard Worker    'delete' -- whether the file is deleted on close (default True).
533*cda5da8dSAndroid Build Coastguard Worker    'errors' -- the errors argument to io.open (default None)
534*cda5da8dSAndroid Build Coastguard Worker    The file is created as mkstemp() would do it.
535*cda5da8dSAndroid Build Coastguard Worker
536*cda5da8dSAndroid Build Coastguard Worker    Returns an object with a file-like interface; the name of the file
537*cda5da8dSAndroid Build Coastguard Worker    is accessible as its 'name' attribute.  The file will be automatically
538*cda5da8dSAndroid Build Coastguard Worker    deleted when it is closed unless the 'delete' argument is set to False.
539*cda5da8dSAndroid Build Coastguard Worker
540*cda5da8dSAndroid Build Coastguard Worker    On POSIX, NamedTemporaryFiles cannot be automatically deleted if
541*cda5da8dSAndroid Build Coastguard Worker    the creating process is terminated abruptly with a SIGKILL signal.
542*cda5da8dSAndroid Build Coastguard Worker    Windows can delete the file even in this case.
543*cda5da8dSAndroid Build Coastguard Worker    """
544*cda5da8dSAndroid Build Coastguard Worker
545*cda5da8dSAndroid Build Coastguard Worker    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
546*cda5da8dSAndroid Build Coastguard Worker
547*cda5da8dSAndroid Build Coastguard Worker    flags = _bin_openflags
548*cda5da8dSAndroid Build Coastguard Worker
549*cda5da8dSAndroid Build Coastguard Worker    # Setting O_TEMPORARY in the flags causes the OS to delete
550*cda5da8dSAndroid Build Coastguard Worker    # the file when it is closed.  This is only supported by Windows.
551*cda5da8dSAndroid Build Coastguard Worker    if _os.name == 'nt' and delete:
552*cda5da8dSAndroid Build Coastguard Worker        flags |= _os.O_TEMPORARY
553*cda5da8dSAndroid Build Coastguard Worker
554*cda5da8dSAndroid Build Coastguard Worker    if "b" not in mode:
555*cda5da8dSAndroid Build Coastguard Worker        encoding = _io.text_encoding(encoding)
556*cda5da8dSAndroid Build Coastguard Worker
557*cda5da8dSAndroid Build Coastguard Worker    name = None
558*cda5da8dSAndroid Build Coastguard Worker    def opener(*args):
559*cda5da8dSAndroid Build Coastguard Worker        nonlocal name
560*cda5da8dSAndroid Build Coastguard Worker        fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
561*cda5da8dSAndroid Build Coastguard Worker        return fd
562*cda5da8dSAndroid Build Coastguard Worker    try:
563*cda5da8dSAndroid Build Coastguard Worker        file = _io.open(dir, mode, buffering=buffering,
564*cda5da8dSAndroid Build Coastguard Worker                        newline=newline, encoding=encoding, errors=errors,
565*cda5da8dSAndroid Build Coastguard Worker                        opener=opener)
566*cda5da8dSAndroid Build Coastguard Worker        try:
567*cda5da8dSAndroid Build Coastguard Worker            raw = getattr(file, 'buffer', file)
568*cda5da8dSAndroid Build Coastguard Worker            raw = getattr(raw, 'raw', raw)
569*cda5da8dSAndroid Build Coastguard Worker            raw.name = name
570*cda5da8dSAndroid Build Coastguard Worker            return _TemporaryFileWrapper(file, name, delete)
571*cda5da8dSAndroid Build Coastguard Worker        except:
572*cda5da8dSAndroid Build Coastguard Worker            file.close()
573*cda5da8dSAndroid Build Coastguard Worker            raise
574*cda5da8dSAndroid Build Coastguard Worker    except:
575*cda5da8dSAndroid Build Coastguard Worker        if name is not None and not (_os.name == 'nt' and delete):
576*cda5da8dSAndroid Build Coastguard Worker            _os.unlink(name)
577*cda5da8dSAndroid Build Coastguard Worker        raise
578*cda5da8dSAndroid Build Coastguard Worker
579*cda5da8dSAndroid Build Coastguard Workerif _os.name != 'posix' or _sys.platform == 'cygwin':
580*cda5da8dSAndroid Build Coastguard Worker    # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
581*cda5da8dSAndroid Build Coastguard Worker    # while it is open.
582*cda5da8dSAndroid Build Coastguard Worker    TemporaryFile = NamedTemporaryFile
583*cda5da8dSAndroid Build Coastguard Worker
584*cda5da8dSAndroid Build Coastguard Workerelse:
585*cda5da8dSAndroid Build Coastguard Worker    # Is the O_TMPFILE flag available and does it work?
586*cda5da8dSAndroid Build Coastguard Worker    # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an
587*cda5da8dSAndroid Build Coastguard Worker    # IsADirectoryError exception
588*cda5da8dSAndroid Build Coastguard Worker    _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE')
589*cda5da8dSAndroid Build Coastguard Worker
590*cda5da8dSAndroid Build Coastguard Worker    def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
591*cda5da8dSAndroid Build Coastguard Worker                      newline=None, suffix=None, prefix=None,
592*cda5da8dSAndroid Build Coastguard Worker                      dir=None, *, errors=None):
593*cda5da8dSAndroid Build Coastguard Worker        """Create and return a temporary file.
594*cda5da8dSAndroid Build Coastguard Worker        Arguments:
595*cda5da8dSAndroid Build Coastguard Worker        'prefix', 'suffix', 'dir' -- as for mkstemp.
596*cda5da8dSAndroid Build Coastguard Worker        'mode' -- the mode argument to io.open (default "w+b").
597*cda5da8dSAndroid Build Coastguard Worker        'buffering' -- the buffer size argument to io.open (default -1).
598*cda5da8dSAndroid Build Coastguard Worker        'encoding' -- the encoding argument to io.open (default None)
599*cda5da8dSAndroid Build Coastguard Worker        'newline' -- the newline argument to io.open (default None)
600*cda5da8dSAndroid Build Coastguard Worker        'errors' -- the errors argument to io.open (default None)
601*cda5da8dSAndroid Build Coastguard Worker        The file is created as mkstemp() would do it.
602*cda5da8dSAndroid Build Coastguard Worker
603*cda5da8dSAndroid Build Coastguard Worker        Returns an object with a file-like interface.  The file has no
604*cda5da8dSAndroid Build Coastguard Worker        name, and will cease to exist when it is closed.
605*cda5da8dSAndroid Build Coastguard Worker        """
606*cda5da8dSAndroid Build Coastguard Worker        global _O_TMPFILE_WORKS
607*cda5da8dSAndroid Build Coastguard Worker
608*cda5da8dSAndroid Build Coastguard Worker        if "b" not in mode:
609*cda5da8dSAndroid Build Coastguard Worker            encoding = _io.text_encoding(encoding)
610*cda5da8dSAndroid Build Coastguard Worker
611*cda5da8dSAndroid Build Coastguard Worker        prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
612*cda5da8dSAndroid Build Coastguard Worker
613*cda5da8dSAndroid Build Coastguard Worker        flags = _bin_openflags
614*cda5da8dSAndroid Build Coastguard Worker        if _O_TMPFILE_WORKS:
615*cda5da8dSAndroid Build Coastguard Worker            fd = None
616*cda5da8dSAndroid Build Coastguard Worker            def opener(*args):
617*cda5da8dSAndroid Build Coastguard Worker                nonlocal fd
618*cda5da8dSAndroid Build Coastguard Worker                flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT
619*cda5da8dSAndroid Build Coastguard Worker                fd = _os.open(dir, flags2, 0o600)
620*cda5da8dSAndroid Build Coastguard Worker                return fd
621*cda5da8dSAndroid Build Coastguard Worker            try:
622*cda5da8dSAndroid Build Coastguard Worker                file = _io.open(dir, mode, buffering=buffering,
623*cda5da8dSAndroid Build Coastguard Worker                                newline=newline, encoding=encoding,
624*cda5da8dSAndroid Build Coastguard Worker                                errors=errors, opener=opener)
625*cda5da8dSAndroid Build Coastguard Worker                raw = getattr(file, 'buffer', file)
626*cda5da8dSAndroid Build Coastguard Worker                raw = getattr(raw, 'raw', raw)
627*cda5da8dSAndroid Build Coastguard Worker                raw.name = fd
628*cda5da8dSAndroid Build Coastguard Worker                return file
629*cda5da8dSAndroid Build Coastguard Worker            except IsADirectoryError:
630*cda5da8dSAndroid Build Coastguard Worker                # Linux kernel older than 3.11 ignores the O_TMPFILE flag:
631*cda5da8dSAndroid Build Coastguard Worker                # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory
632*cda5da8dSAndroid Build Coastguard Worker                # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a
633*cda5da8dSAndroid Build Coastguard Worker                # directory cannot be open to write. Set flag to False to not
634*cda5da8dSAndroid Build Coastguard Worker                # try again.
635*cda5da8dSAndroid Build Coastguard Worker                _O_TMPFILE_WORKS = False
636*cda5da8dSAndroid Build Coastguard Worker            except OSError:
637*cda5da8dSAndroid Build Coastguard Worker                # The filesystem of the directory does not support O_TMPFILE.
638*cda5da8dSAndroid Build Coastguard Worker                # For example, OSError(95, 'Operation not supported').
639*cda5da8dSAndroid Build Coastguard Worker                #
640*cda5da8dSAndroid Build Coastguard Worker                # On Linux kernel older than 3.11, trying to open a regular
641*cda5da8dSAndroid Build Coastguard Worker                # file (or a symbolic link to a regular file) with O_TMPFILE
642*cda5da8dSAndroid Build Coastguard Worker                # fails with NotADirectoryError, because O_TMPFILE is read as
643*cda5da8dSAndroid Build Coastguard Worker                # O_DIRECTORY.
644*cda5da8dSAndroid Build Coastguard Worker                pass
645*cda5da8dSAndroid Build Coastguard Worker            # Fallback to _mkstemp_inner().
646*cda5da8dSAndroid Build Coastguard Worker
647*cda5da8dSAndroid Build Coastguard Worker        fd = None
648*cda5da8dSAndroid Build Coastguard Worker        def opener(*args):
649*cda5da8dSAndroid Build Coastguard Worker            nonlocal fd
650*cda5da8dSAndroid Build Coastguard Worker            fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
651*cda5da8dSAndroid Build Coastguard Worker            try:
652*cda5da8dSAndroid Build Coastguard Worker                _os.unlink(name)
653*cda5da8dSAndroid Build Coastguard Worker            except BaseException as e:
654*cda5da8dSAndroid Build Coastguard Worker                _os.close(fd)
655*cda5da8dSAndroid Build Coastguard Worker                raise
656*cda5da8dSAndroid Build Coastguard Worker            return fd
657*cda5da8dSAndroid Build Coastguard Worker        file = _io.open(dir, mode, buffering=buffering,
658*cda5da8dSAndroid Build Coastguard Worker                        newline=newline, encoding=encoding, errors=errors,
659*cda5da8dSAndroid Build Coastguard Worker                        opener=opener)
660*cda5da8dSAndroid Build Coastguard Worker        raw = getattr(file, 'buffer', file)
661*cda5da8dSAndroid Build Coastguard Worker        raw = getattr(raw, 'raw', raw)
662*cda5da8dSAndroid Build Coastguard Worker        raw.name = fd
663*cda5da8dSAndroid Build Coastguard Worker        return file
664*cda5da8dSAndroid Build Coastguard Worker
665*cda5da8dSAndroid Build Coastguard Workerclass SpooledTemporaryFile(_io.IOBase):
666*cda5da8dSAndroid Build Coastguard Worker    """Temporary file wrapper, specialized to switch from BytesIO
667*cda5da8dSAndroid Build Coastguard Worker    or StringIO to a real file when it exceeds a certain size or
668*cda5da8dSAndroid Build Coastguard Worker    when a fileno is needed.
669*cda5da8dSAndroid Build Coastguard Worker    """
670*cda5da8dSAndroid Build Coastguard Worker    _rolled = False
671*cda5da8dSAndroid Build Coastguard Worker
672*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, max_size=0, mode='w+b', buffering=-1,
673*cda5da8dSAndroid Build Coastguard Worker                 encoding=None, newline=None,
674*cda5da8dSAndroid Build Coastguard Worker                 suffix=None, prefix=None, dir=None, *, errors=None):
675*cda5da8dSAndroid Build Coastguard Worker        if 'b' in mode:
676*cda5da8dSAndroid Build Coastguard Worker            self._file = _io.BytesIO()
677*cda5da8dSAndroid Build Coastguard Worker        else:
678*cda5da8dSAndroid Build Coastguard Worker            encoding = _io.text_encoding(encoding)
679*cda5da8dSAndroid Build Coastguard Worker            self._file = _io.TextIOWrapper(_io.BytesIO(),
680*cda5da8dSAndroid Build Coastguard Worker                            encoding=encoding, errors=errors,
681*cda5da8dSAndroid Build Coastguard Worker                            newline=newline)
682*cda5da8dSAndroid Build Coastguard Worker        self._max_size = max_size
683*cda5da8dSAndroid Build Coastguard Worker        self._rolled = False
684*cda5da8dSAndroid Build Coastguard Worker        self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
685*cda5da8dSAndroid Build Coastguard Worker                                   'suffix': suffix, 'prefix': prefix,
686*cda5da8dSAndroid Build Coastguard Worker                                   'encoding': encoding, 'newline': newline,
687*cda5da8dSAndroid Build Coastguard Worker                                   'dir': dir, 'errors': errors}
688*cda5da8dSAndroid Build Coastguard Worker
689*cda5da8dSAndroid Build Coastguard Worker    __class_getitem__ = classmethod(_types.GenericAlias)
690*cda5da8dSAndroid Build Coastguard Worker
691*cda5da8dSAndroid Build Coastguard Worker    def _check(self, file):
692*cda5da8dSAndroid Build Coastguard Worker        if self._rolled: return
693*cda5da8dSAndroid Build Coastguard Worker        max_size = self._max_size
694*cda5da8dSAndroid Build Coastguard Worker        if max_size and file.tell() > max_size:
695*cda5da8dSAndroid Build Coastguard Worker            self.rollover()
696*cda5da8dSAndroid Build Coastguard Worker
697*cda5da8dSAndroid Build Coastguard Worker    def rollover(self):
698*cda5da8dSAndroid Build Coastguard Worker        if self._rolled: return
699*cda5da8dSAndroid Build Coastguard Worker        file = self._file
700*cda5da8dSAndroid Build Coastguard Worker        newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
701*cda5da8dSAndroid Build Coastguard Worker        del self._TemporaryFileArgs
702*cda5da8dSAndroid Build Coastguard Worker
703*cda5da8dSAndroid Build Coastguard Worker        pos = file.tell()
704*cda5da8dSAndroid Build Coastguard Worker        if hasattr(newfile, 'buffer'):
705*cda5da8dSAndroid Build Coastguard Worker            newfile.buffer.write(file.detach().getvalue())
706*cda5da8dSAndroid Build Coastguard Worker        else:
707*cda5da8dSAndroid Build Coastguard Worker            newfile.write(file.getvalue())
708*cda5da8dSAndroid Build Coastguard Worker        newfile.seek(pos, 0)
709*cda5da8dSAndroid Build Coastguard Worker
710*cda5da8dSAndroid Build Coastguard Worker        self._rolled = True
711*cda5da8dSAndroid Build Coastguard Worker
712*cda5da8dSAndroid Build Coastguard Worker    # The method caching trick from NamedTemporaryFile
713*cda5da8dSAndroid Build Coastguard Worker    # won't work here, because _file may change from a
714*cda5da8dSAndroid Build Coastguard Worker    # BytesIO/StringIO instance to a real file. So we list
715*cda5da8dSAndroid Build Coastguard Worker    # all the methods directly.
716*cda5da8dSAndroid Build Coastguard Worker
717*cda5da8dSAndroid Build Coastguard Worker    # Context management protocol
718*cda5da8dSAndroid Build Coastguard Worker    def __enter__(self):
719*cda5da8dSAndroid Build Coastguard Worker        if self._file.closed:
720*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Cannot enter context with closed file")
721*cda5da8dSAndroid Build Coastguard Worker        return self
722*cda5da8dSAndroid Build Coastguard Worker
723*cda5da8dSAndroid Build Coastguard Worker    def __exit__(self, exc, value, tb):
724*cda5da8dSAndroid Build Coastguard Worker        self._file.close()
725*cda5da8dSAndroid Build Coastguard Worker
726*cda5da8dSAndroid Build Coastguard Worker    # file protocol
727*cda5da8dSAndroid Build Coastguard Worker    def __iter__(self):
728*cda5da8dSAndroid Build Coastguard Worker        return self._file.__iter__()
729*cda5da8dSAndroid Build Coastguard Worker
730*cda5da8dSAndroid Build Coastguard Worker    def __del__(self):
731*cda5da8dSAndroid Build Coastguard Worker        if not self.closed:
732*cda5da8dSAndroid Build Coastguard Worker            _warnings.warn(
733*cda5da8dSAndroid Build Coastguard Worker                "Unclosed file {!r}".format(self),
734*cda5da8dSAndroid Build Coastguard Worker                ResourceWarning,
735*cda5da8dSAndroid Build Coastguard Worker                stacklevel=2,
736*cda5da8dSAndroid Build Coastguard Worker                source=self
737*cda5da8dSAndroid Build Coastguard Worker            )
738*cda5da8dSAndroid Build Coastguard Worker            self.close()
739*cda5da8dSAndroid Build Coastguard Worker
740*cda5da8dSAndroid Build Coastguard Worker    def close(self):
741*cda5da8dSAndroid Build Coastguard Worker        self._file.close()
742*cda5da8dSAndroid Build Coastguard Worker
743*cda5da8dSAndroid Build Coastguard Worker    @property
744*cda5da8dSAndroid Build Coastguard Worker    def closed(self):
745*cda5da8dSAndroid Build Coastguard Worker        return self._file.closed
746*cda5da8dSAndroid Build Coastguard Worker
747*cda5da8dSAndroid Build Coastguard Worker    @property
748*cda5da8dSAndroid Build Coastguard Worker    def encoding(self):
749*cda5da8dSAndroid Build Coastguard Worker        return self._file.encoding
750*cda5da8dSAndroid Build Coastguard Worker
751*cda5da8dSAndroid Build Coastguard Worker    @property
752*cda5da8dSAndroid Build Coastguard Worker    def errors(self):
753*cda5da8dSAndroid Build Coastguard Worker        return self._file.errors
754*cda5da8dSAndroid Build Coastguard Worker
755*cda5da8dSAndroid Build Coastguard Worker    def fileno(self):
756*cda5da8dSAndroid Build Coastguard Worker        self.rollover()
757*cda5da8dSAndroid Build Coastguard Worker        return self._file.fileno()
758*cda5da8dSAndroid Build Coastguard Worker
759*cda5da8dSAndroid Build Coastguard Worker    def flush(self):
760*cda5da8dSAndroid Build Coastguard Worker        self._file.flush()
761*cda5da8dSAndroid Build Coastguard Worker
762*cda5da8dSAndroid Build Coastguard Worker    def isatty(self):
763*cda5da8dSAndroid Build Coastguard Worker        return self._file.isatty()
764*cda5da8dSAndroid Build Coastguard Worker
765*cda5da8dSAndroid Build Coastguard Worker    @property
766*cda5da8dSAndroid Build Coastguard Worker    def mode(self):
767*cda5da8dSAndroid Build Coastguard Worker        try:
768*cda5da8dSAndroid Build Coastguard Worker            return self._file.mode
769*cda5da8dSAndroid Build Coastguard Worker        except AttributeError:
770*cda5da8dSAndroid Build Coastguard Worker            return self._TemporaryFileArgs['mode']
771*cda5da8dSAndroid Build Coastguard Worker
772*cda5da8dSAndroid Build Coastguard Worker    @property
773*cda5da8dSAndroid Build Coastguard Worker    def name(self):
774*cda5da8dSAndroid Build Coastguard Worker        try:
775*cda5da8dSAndroid Build Coastguard Worker            return self._file.name
776*cda5da8dSAndroid Build Coastguard Worker        except AttributeError:
777*cda5da8dSAndroid Build Coastguard Worker            return None
778*cda5da8dSAndroid Build Coastguard Worker
779*cda5da8dSAndroid Build Coastguard Worker    @property
780*cda5da8dSAndroid Build Coastguard Worker    def newlines(self):
781*cda5da8dSAndroid Build Coastguard Worker        return self._file.newlines
782*cda5da8dSAndroid Build Coastguard Worker
783*cda5da8dSAndroid Build Coastguard Worker    def readable(self):
784*cda5da8dSAndroid Build Coastguard Worker        return self._file.readable()
785*cda5da8dSAndroid Build Coastguard Worker
786*cda5da8dSAndroid Build Coastguard Worker    def read(self, *args):
787*cda5da8dSAndroid Build Coastguard Worker        return self._file.read(*args)
788*cda5da8dSAndroid Build Coastguard Worker
789*cda5da8dSAndroid Build Coastguard Worker    def read1(self, *args):
790*cda5da8dSAndroid Build Coastguard Worker        return self._file.read1(*args)
791*cda5da8dSAndroid Build Coastguard Worker
792*cda5da8dSAndroid Build Coastguard Worker    def readinto(self, b):
793*cda5da8dSAndroid Build Coastguard Worker        return self._file.readinto(b)
794*cda5da8dSAndroid Build Coastguard Worker
795*cda5da8dSAndroid Build Coastguard Worker    def readinto1(self, b):
796*cda5da8dSAndroid Build Coastguard Worker        return self._file.readinto1(b)
797*cda5da8dSAndroid Build Coastguard Worker
798*cda5da8dSAndroid Build Coastguard Worker    def readline(self, *args):
799*cda5da8dSAndroid Build Coastguard Worker        return self._file.readline(*args)
800*cda5da8dSAndroid Build Coastguard Worker
801*cda5da8dSAndroid Build Coastguard Worker    def readlines(self, *args):
802*cda5da8dSAndroid Build Coastguard Worker        return self._file.readlines(*args)
803*cda5da8dSAndroid Build Coastguard Worker
804*cda5da8dSAndroid Build Coastguard Worker    def seekable(self):
805*cda5da8dSAndroid Build Coastguard Worker        return self._file.seekable()
806*cda5da8dSAndroid Build Coastguard Worker
807*cda5da8dSAndroid Build Coastguard Worker    def seek(self, *args):
808*cda5da8dSAndroid Build Coastguard Worker        return self._file.seek(*args)
809*cda5da8dSAndroid Build Coastguard Worker
810*cda5da8dSAndroid Build Coastguard Worker    def tell(self):
811*cda5da8dSAndroid Build Coastguard Worker        return self._file.tell()
812*cda5da8dSAndroid Build Coastguard Worker
813*cda5da8dSAndroid Build Coastguard Worker    def truncate(self, size=None):
814*cda5da8dSAndroid Build Coastguard Worker        if size is None:
815*cda5da8dSAndroid Build Coastguard Worker            return self._file.truncate()
816*cda5da8dSAndroid Build Coastguard Worker        else:
817*cda5da8dSAndroid Build Coastguard Worker            if size > self._max_size:
818*cda5da8dSAndroid Build Coastguard Worker                self.rollover()
819*cda5da8dSAndroid Build Coastguard Worker            return self._file.truncate(size)
820*cda5da8dSAndroid Build Coastguard Worker
821*cda5da8dSAndroid Build Coastguard Worker    def writable(self):
822*cda5da8dSAndroid Build Coastguard Worker        return self._file.writable()
823*cda5da8dSAndroid Build Coastguard Worker
824*cda5da8dSAndroid Build Coastguard Worker    def write(self, s):
825*cda5da8dSAndroid Build Coastguard Worker        file = self._file
826*cda5da8dSAndroid Build Coastguard Worker        rv = file.write(s)
827*cda5da8dSAndroid Build Coastguard Worker        self._check(file)
828*cda5da8dSAndroid Build Coastguard Worker        return rv
829*cda5da8dSAndroid Build Coastguard Worker
830*cda5da8dSAndroid Build Coastguard Worker    def writelines(self, iterable):
831*cda5da8dSAndroid Build Coastguard Worker        file = self._file
832*cda5da8dSAndroid Build Coastguard Worker        rv = file.writelines(iterable)
833*cda5da8dSAndroid Build Coastguard Worker        self._check(file)
834*cda5da8dSAndroid Build Coastguard Worker        return rv
835*cda5da8dSAndroid Build Coastguard Worker
836*cda5da8dSAndroid Build Coastguard Worker    def detach(self):
837*cda5da8dSAndroid Build Coastguard Worker        return self._file.detach()
838*cda5da8dSAndroid Build Coastguard Worker
839*cda5da8dSAndroid Build Coastguard Worker
840*cda5da8dSAndroid Build Coastguard Workerclass TemporaryDirectory:
841*cda5da8dSAndroid Build Coastguard Worker    """Create and return a temporary directory.  This has the same
842*cda5da8dSAndroid Build Coastguard Worker    behavior as mkdtemp but can be used as a context manager.  For
843*cda5da8dSAndroid Build Coastguard Worker    example:
844*cda5da8dSAndroid Build Coastguard Worker
845*cda5da8dSAndroid Build Coastguard Worker        with TemporaryDirectory() as tmpdir:
846*cda5da8dSAndroid Build Coastguard Worker            ...
847*cda5da8dSAndroid Build Coastguard Worker
848*cda5da8dSAndroid Build Coastguard Worker    Upon exiting the context, the directory and everything contained
849*cda5da8dSAndroid Build Coastguard Worker    in it are removed.
850*cda5da8dSAndroid Build Coastguard Worker    """
851*cda5da8dSAndroid Build Coastguard Worker
852*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, suffix=None, prefix=None, dir=None,
853*cda5da8dSAndroid Build Coastguard Worker                 ignore_cleanup_errors=False):
854*cda5da8dSAndroid Build Coastguard Worker        self.name = mkdtemp(suffix, prefix, dir)
855*cda5da8dSAndroid Build Coastguard Worker        self._ignore_cleanup_errors = ignore_cleanup_errors
856*cda5da8dSAndroid Build Coastguard Worker        self._finalizer = _weakref.finalize(
857*cda5da8dSAndroid Build Coastguard Worker            self, self._cleanup, self.name,
858*cda5da8dSAndroid Build Coastguard Worker            warn_message="Implicitly cleaning up {!r}".format(self),
859*cda5da8dSAndroid Build Coastguard Worker            ignore_errors=self._ignore_cleanup_errors)
860*cda5da8dSAndroid Build Coastguard Worker
861*cda5da8dSAndroid Build Coastguard Worker    @classmethod
862*cda5da8dSAndroid Build Coastguard Worker    def _rmtree(cls, name, ignore_errors=False):
863*cda5da8dSAndroid Build Coastguard Worker        def onerror(func, path, exc_info):
864*cda5da8dSAndroid Build Coastguard Worker            if issubclass(exc_info[0], PermissionError):
865*cda5da8dSAndroid Build Coastguard Worker                def resetperms(path):
866*cda5da8dSAndroid Build Coastguard Worker                    try:
867*cda5da8dSAndroid Build Coastguard Worker                        _os.chflags(path, 0)
868*cda5da8dSAndroid Build Coastguard Worker                    except AttributeError:
869*cda5da8dSAndroid Build Coastguard Worker                        pass
870*cda5da8dSAndroid Build Coastguard Worker                    _os.chmod(path, 0o700)
871*cda5da8dSAndroid Build Coastguard Worker
872*cda5da8dSAndroid Build Coastguard Worker                try:
873*cda5da8dSAndroid Build Coastguard Worker                    if path != name:
874*cda5da8dSAndroid Build Coastguard Worker                        resetperms(_os.path.dirname(path))
875*cda5da8dSAndroid Build Coastguard Worker                    resetperms(path)
876*cda5da8dSAndroid Build Coastguard Worker
877*cda5da8dSAndroid Build Coastguard Worker                    try:
878*cda5da8dSAndroid Build Coastguard Worker                        _os.unlink(path)
879*cda5da8dSAndroid Build Coastguard Worker                    # PermissionError is raised on FreeBSD for directories
880*cda5da8dSAndroid Build Coastguard Worker                    except (IsADirectoryError, PermissionError):
881*cda5da8dSAndroid Build Coastguard Worker                        cls._rmtree(path, ignore_errors=ignore_errors)
882*cda5da8dSAndroid Build Coastguard Worker                except FileNotFoundError:
883*cda5da8dSAndroid Build Coastguard Worker                    pass
884*cda5da8dSAndroid Build Coastguard Worker            elif issubclass(exc_info[0], FileNotFoundError):
885*cda5da8dSAndroid Build Coastguard Worker                pass
886*cda5da8dSAndroid Build Coastguard Worker            else:
887*cda5da8dSAndroid Build Coastguard Worker                if not ignore_errors:
888*cda5da8dSAndroid Build Coastguard Worker                    raise
889*cda5da8dSAndroid Build Coastguard Worker
890*cda5da8dSAndroid Build Coastguard Worker        _shutil.rmtree(name, onerror=onerror)
891*cda5da8dSAndroid Build Coastguard Worker
892*cda5da8dSAndroid Build Coastguard Worker    @classmethod
893*cda5da8dSAndroid Build Coastguard Worker    def _cleanup(cls, name, warn_message, ignore_errors=False):
894*cda5da8dSAndroid Build Coastguard Worker        cls._rmtree(name, ignore_errors=ignore_errors)
895*cda5da8dSAndroid Build Coastguard Worker        _warnings.warn(warn_message, ResourceWarning)
896*cda5da8dSAndroid Build Coastguard Worker
897*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
898*cda5da8dSAndroid Build Coastguard Worker        return "<{} {!r}>".format(self.__class__.__name__, self.name)
899*cda5da8dSAndroid Build Coastguard Worker
900*cda5da8dSAndroid Build Coastguard Worker    def __enter__(self):
901*cda5da8dSAndroid Build Coastguard Worker        return self.name
902*cda5da8dSAndroid Build Coastguard Worker
903*cda5da8dSAndroid Build Coastguard Worker    def __exit__(self, exc, value, tb):
904*cda5da8dSAndroid Build Coastguard Worker        self.cleanup()
905*cda5da8dSAndroid Build Coastguard Worker
906*cda5da8dSAndroid Build Coastguard Worker    def cleanup(self):
907*cda5da8dSAndroid Build Coastguard Worker        if self._finalizer.detach() or _os.path.exists(self.name):
908*cda5da8dSAndroid Build Coastguard Worker            self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
909*cda5da8dSAndroid Build Coastguard Worker
910*cda5da8dSAndroid Build Coastguard Worker    __class_getitem__ = classmethod(_types.GenericAlias)
911