17db96d56Sopenharmony_ci"""Temporary files.
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciThis module provides generic, low- and high-level interfaces for
47db96d56Sopenharmony_cicreating temporary files and directories.  All of the interfaces
57db96d56Sopenharmony_ciprovided by this module can be used without fear of race conditions
67db96d56Sopenharmony_ciexcept for 'mktemp'.  'mktemp' is subject to race conditions and
77db96d56Sopenharmony_cishould not be used; it is provided for backward compatibility only.
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ciThe default path names are returned as str.  If you supply bytes as
107db96d56Sopenharmony_ciinput, all return values will be in bytes.  Ex:
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ci    >>> tempfile.mkstemp()
137db96d56Sopenharmony_ci    (4, '/tmp/tmptpu9nin8')
147db96d56Sopenharmony_ci    >>> tempfile.mkdtemp(suffix=b'')
157db96d56Sopenharmony_ci    b'/tmp/tmppbi8f0hy'
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ciThis module also provides some data items to the user:
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci  TMP_MAX  - maximum number of names that will be tried before
207db96d56Sopenharmony_ci             giving up.
217db96d56Sopenharmony_ci  tempdir  - If this is set to a string before the first use of
227db96d56Sopenharmony_ci             any routine from this module, it will be considered as
237db96d56Sopenharmony_ci             another candidate location to store temporary files.
247db96d56Sopenharmony_ci"""
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci__all__ = [
277db96d56Sopenharmony_ci    "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
287db96d56Sopenharmony_ci    "SpooledTemporaryFile", "TemporaryDirectory",
297db96d56Sopenharmony_ci    "mkstemp", "mkdtemp",                  # low level safe interfaces
307db96d56Sopenharmony_ci    "mktemp",                              # deprecated unsafe interface
317db96d56Sopenharmony_ci    "TMP_MAX", "gettempprefix",            # constants
327db96d56Sopenharmony_ci    "tempdir", "gettempdir",
337db96d56Sopenharmony_ci    "gettempprefixb", "gettempdirb",
347db96d56Sopenharmony_ci   ]
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci# Imports.
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ciimport functools as _functools
407db96d56Sopenharmony_ciimport warnings as _warnings
417db96d56Sopenharmony_ciimport io as _io
427db96d56Sopenharmony_ciimport os as _os
437db96d56Sopenharmony_ciimport shutil as _shutil
447db96d56Sopenharmony_ciimport errno as _errno
457db96d56Sopenharmony_cifrom random import Random as _Random
467db96d56Sopenharmony_ciimport sys as _sys
477db96d56Sopenharmony_ciimport types as _types
487db96d56Sopenharmony_ciimport weakref as _weakref
497db96d56Sopenharmony_ciimport _thread
507db96d56Sopenharmony_ci_allocate_lock = _thread.allocate_lock
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
537db96d56Sopenharmony_ciif hasattr(_os, 'O_NOFOLLOW'):
547db96d56Sopenharmony_ci    _text_openflags |= _os.O_NOFOLLOW
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci_bin_openflags = _text_openflags
577db96d56Sopenharmony_ciif hasattr(_os, 'O_BINARY'):
587db96d56Sopenharmony_ci    _bin_openflags |= _os.O_BINARY
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ciif hasattr(_os, 'TMP_MAX'):
617db96d56Sopenharmony_ci    TMP_MAX = _os.TMP_MAX
627db96d56Sopenharmony_cielse:
637db96d56Sopenharmony_ci    TMP_MAX = 10000
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci# This variable _was_ unused for legacy reasons, see issue 10354.
667db96d56Sopenharmony_ci# But as of 3.5 we actually use it at runtime so changing it would
677db96d56Sopenharmony_ci# have a possibly desirable side effect...  But we do not want to support
687db96d56Sopenharmony_ci# that as an API.  It is undocumented on purpose.  Do not depend on this.
697db96d56Sopenharmony_citemplate = "tmp"
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci# Internal routines.
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci_once_lock = _allocate_lock()
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_cidef _exists(fn):
777db96d56Sopenharmony_ci    try:
787db96d56Sopenharmony_ci        _os.lstat(fn)
797db96d56Sopenharmony_ci    except OSError:
807db96d56Sopenharmony_ci        return False
817db96d56Sopenharmony_ci    else:
827db96d56Sopenharmony_ci        return True
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_cidef _infer_return_type(*args):
867db96d56Sopenharmony_ci    """Look at the type of all args and divine their implied return type."""
877db96d56Sopenharmony_ci    return_type = None
887db96d56Sopenharmony_ci    for arg in args:
897db96d56Sopenharmony_ci        if arg is None:
907db96d56Sopenharmony_ci            continue
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci        if isinstance(arg, _os.PathLike):
937db96d56Sopenharmony_ci            arg = _os.fspath(arg)
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci        if isinstance(arg, bytes):
967db96d56Sopenharmony_ci            if return_type is str:
977db96d56Sopenharmony_ci                raise TypeError("Can't mix bytes and non-bytes in "
987db96d56Sopenharmony_ci                                "path components.")
997db96d56Sopenharmony_ci            return_type = bytes
1007db96d56Sopenharmony_ci        else:
1017db96d56Sopenharmony_ci            if return_type is bytes:
1027db96d56Sopenharmony_ci                raise TypeError("Can't mix bytes and non-bytes in "
1037db96d56Sopenharmony_ci                                "path components.")
1047db96d56Sopenharmony_ci            return_type = str
1057db96d56Sopenharmony_ci    if return_type is None:
1067db96d56Sopenharmony_ci        if tempdir is None or isinstance(tempdir, str):
1077db96d56Sopenharmony_ci            return str  # tempfile APIs return a str by default.
1087db96d56Sopenharmony_ci        else:
1097db96d56Sopenharmony_ci            # we could check for bytes but it'll fail later on anyway
1107db96d56Sopenharmony_ci            return bytes
1117db96d56Sopenharmony_ci    return return_type
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_cidef _sanitize_params(prefix, suffix, dir):
1157db96d56Sopenharmony_ci    """Common parameter processing for most APIs in this module."""
1167db96d56Sopenharmony_ci    output_type = _infer_return_type(prefix, suffix, dir)
1177db96d56Sopenharmony_ci    if suffix is None:
1187db96d56Sopenharmony_ci        suffix = output_type()
1197db96d56Sopenharmony_ci    if prefix is None:
1207db96d56Sopenharmony_ci        if output_type is str:
1217db96d56Sopenharmony_ci            prefix = template
1227db96d56Sopenharmony_ci        else:
1237db96d56Sopenharmony_ci            prefix = _os.fsencode(template)
1247db96d56Sopenharmony_ci    if dir is None:
1257db96d56Sopenharmony_ci        if output_type is str:
1267db96d56Sopenharmony_ci            dir = gettempdir()
1277db96d56Sopenharmony_ci        else:
1287db96d56Sopenharmony_ci            dir = gettempdirb()
1297db96d56Sopenharmony_ci    return prefix, suffix, dir, output_type
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ciclass _RandomNameSequence:
1337db96d56Sopenharmony_ci    """An instance of _RandomNameSequence generates an endless
1347db96d56Sopenharmony_ci    sequence of unpredictable strings which can safely be incorporated
1357db96d56Sopenharmony_ci    into file names.  Each string is eight characters long.  Multiple
1367db96d56Sopenharmony_ci    threads can safely use the same instance at the same time.
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    _RandomNameSequence is an iterator."""
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ci    characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ci    @property
1437db96d56Sopenharmony_ci    def rng(self):
1447db96d56Sopenharmony_ci        cur_pid = _os.getpid()
1457db96d56Sopenharmony_ci        if cur_pid != getattr(self, '_rng_pid', None):
1467db96d56Sopenharmony_ci            self._rng = _Random()
1477db96d56Sopenharmony_ci            self._rng_pid = cur_pid
1487db96d56Sopenharmony_ci        return self._rng
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ci    def __iter__(self):
1517db96d56Sopenharmony_ci        return self
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci    def __next__(self):
1547db96d56Sopenharmony_ci        return ''.join(self.rng.choices(self.characters, k=8))
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_cidef _candidate_tempdir_list():
1577db96d56Sopenharmony_ci    """Generate a list of candidate temporary directories which
1587db96d56Sopenharmony_ci    _get_default_tempdir will try."""
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ci    dirlist = []
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci    # First, try the environment.
1637db96d56Sopenharmony_ci    for envname in 'TMPDIR', 'TEMP', 'TMP':
1647db96d56Sopenharmony_ci        dirname = _os.getenv(envname)
1657db96d56Sopenharmony_ci        if dirname: dirlist.append(dirname)
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ci    # Failing that, try OS-specific locations.
1687db96d56Sopenharmony_ci    if _os.name == 'nt':
1697db96d56Sopenharmony_ci        dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'),
1707db96d56Sopenharmony_ci                         _os.path.expandvars(r'%SYSTEMROOT%\Temp'),
1717db96d56Sopenharmony_ci                         r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
1727db96d56Sopenharmony_ci    else:
1737db96d56Sopenharmony_ci        dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])
1747db96d56Sopenharmony_ci
1757db96d56Sopenharmony_ci    # As a last resort, the current directory.
1767db96d56Sopenharmony_ci    try:
1777db96d56Sopenharmony_ci        dirlist.append(_os.getcwd())
1787db96d56Sopenharmony_ci    except (AttributeError, OSError):
1797db96d56Sopenharmony_ci        dirlist.append(_os.curdir)
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ci    return dirlist
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_cidef _get_default_tempdir():
1847db96d56Sopenharmony_ci    """Calculate the default directory to use for temporary files.
1857db96d56Sopenharmony_ci    This routine should be called exactly once.
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ci    We determine whether or not a candidate temp dir is usable by
1887db96d56Sopenharmony_ci    trying to create and write to a file in that directory.  If this
1897db96d56Sopenharmony_ci    is successful, the test file is deleted.  To prevent denial of
1907db96d56Sopenharmony_ci    service, the name of the test file must be randomized."""
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ci    namer = _RandomNameSequence()
1937db96d56Sopenharmony_ci    dirlist = _candidate_tempdir_list()
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci    for dir in dirlist:
1967db96d56Sopenharmony_ci        if dir != _os.curdir:
1977db96d56Sopenharmony_ci            dir = _os.path.abspath(dir)
1987db96d56Sopenharmony_ci        # Try only a few names per directory.
1997db96d56Sopenharmony_ci        for seq in range(100):
2007db96d56Sopenharmony_ci            name = next(namer)
2017db96d56Sopenharmony_ci            filename = _os.path.join(dir, name)
2027db96d56Sopenharmony_ci            try:
2037db96d56Sopenharmony_ci                fd = _os.open(filename, _bin_openflags, 0o600)
2047db96d56Sopenharmony_ci                try:
2057db96d56Sopenharmony_ci                    try:
2067db96d56Sopenharmony_ci                        _os.write(fd, b'blat')
2077db96d56Sopenharmony_ci                    finally:
2087db96d56Sopenharmony_ci                        _os.close(fd)
2097db96d56Sopenharmony_ci                finally:
2107db96d56Sopenharmony_ci                    _os.unlink(filename)
2117db96d56Sopenharmony_ci                return dir
2127db96d56Sopenharmony_ci            except FileExistsError:
2137db96d56Sopenharmony_ci                pass
2147db96d56Sopenharmony_ci            except PermissionError:
2157db96d56Sopenharmony_ci                # This exception is thrown when a directory with the chosen name
2167db96d56Sopenharmony_ci                # already exists on windows.
2177db96d56Sopenharmony_ci                if (_os.name == 'nt' and _os.path.isdir(dir) and
2187db96d56Sopenharmony_ci                    _os.access(dir, _os.W_OK)):
2197db96d56Sopenharmony_ci                    continue
2207db96d56Sopenharmony_ci                break   # no point trying more names in this directory
2217db96d56Sopenharmony_ci            except OSError:
2227db96d56Sopenharmony_ci                break   # no point trying more names in this directory
2237db96d56Sopenharmony_ci    raise FileNotFoundError(_errno.ENOENT,
2247db96d56Sopenharmony_ci                            "No usable temporary directory found in %s" %
2257db96d56Sopenharmony_ci                            dirlist)
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci_name_sequence = None
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_cidef _get_candidate_names():
2307db96d56Sopenharmony_ci    """Common setup sequence for all user-callable interfaces."""
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci    global _name_sequence
2337db96d56Sopenharmony_ci    if _name_sequence is None:
2347db96d56Sopenharmony_ci        _once_lock.acquire()
2357db96d56Sopenharmony_ci        try:
2367db96d56Sopenharmony_ci            if _name_sequence is None:
2377db96d56Sopenharmony_ci                _name_sequence = _RandomNameSequence()
2387db96d56Sopenharmony_ci        finally:
2397db96d56Sopenharmony_ci            _once_lock.release()
2407db96d56Sopenharmony_ci    return _name_sequence
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_cidef _mkstemp_inner(dir, pre, suf, flags, output_type):
2447db96d56Sopenharmony_ci    """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci    dir = _os.path.abspath(dir)
2477db96d56Sopenharmony_ci    names = _get_candidate_names()
2487db96d56Sopenharmony_ci    if output_type is bytes:
2497db96d56Sopenharmony_ci        names = map(_os.fsencode, names)
2507db96d56Sopenharmony_ci
2517db96d56Sopenharmony_ci    for seq in range(TMP_MAX):
2527db96d56Sopenharmony_ci        name = next(names)
2537db96d56Sopenharmony_ci        file = _os.path.join(dir, pre + name + suf)
2547db96d56Sopenharmony_ci        _sys.audit("tempfile.mkstemp", file)
2557db96d56Sopenharmony_ci        try:
2567db96d56Sopenharmony_ci            fd = _os.open(file, flags, 0o600)
2577db96d56Sopenharmony_ci        except FileExistsError:
2587db96d56Sopenharmony_ci            continue    # try again
2597db96d56Sopenharmony_ci        except PermissionError:
2607db96d56Sopenharmony_ci            # This exception is thrown when a directory with the chosen name
2617db96d56Sopenharmony_ci            # already exists on windows.
2627db96d56Sopenharmony_ci            if (_os.name == 'nt' and _os.path.isdir(dir) and
2637db96d56Sopenharmony_ci                _os.access(dir, _os.W_OK)):
2647db96d56Sopenharmony_ci                continue
2657db96d56Sopenharmony_ci            else:
2667db96d56Sopenharmony_ci                raise
2677db96d56Sopenharmony_ci        return fd, file
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ci    raise FileExistsError(_errno.EEXIST,
2707db96d56Sopenharmony_ci                          "No usable temporary file name found")
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_cidef _dont_follow_symlinks(func, path, *args):
2737db96d56Sopenharmony_ci    # Pass follow_symlinks=False, unless not supported on this platform.
2747db96d56Sopenharmony_ci    if func in _os.supports_follow_symlinks:
2757db96d56Sopenharmony_ci        func(path, *args, follow_symlinks=False)
2767db96d56Sopenharmony_ci    elif _os.name == 'nt' or not _os.path.islink(path):
2777db96d56Sopenharmony_ci        func(path, *args)
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_cidef _resetperms(path):
2807db96d56Sopenharmony_ci    try:
2817db96d56Sopenharmony_ci        chflags = _os.chflags
2827db96d56Sopenharmony_ci    except AttributeError:
2837db96d56Sopenharmony_ci        pass
2847db96d56Sopenharmony_ci    else:
2857db96d56Sopenharmony_ci        _dont_follow_symlinks(chflags, path, 0)
2867db96d56Sopenharmony_ci    _dont_follow_symlinks(_os.chmod, path, 0o700)
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci
2897db96d56Sopenharmony_ci# User visible interfaces.
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_cidef gettempprefix():
2927db96d56Sopenharmony_ci    """The default prefix for temporary directories as string."""
2937db96d56Sopenharmony_ci    return _os.fsdecode(template)
2947db96d56Sopenharmony_ci
2957db96d56Sopenharmony_cidef gettempprefixb():
2967db96d56Sopenharmony_ci    """The default prefix for temporary directories as bytes."""
2977db96d56Sopenharmony_ci    return _os.fsencode(template)
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_citempdir = None
3007db96d56Sopenharmony_ci
3017db96d56Sopenharmony_cidef _gettempdir():
3027db96d56Sopenharmony_ci    """Private accessor for tempfile.tempdir."""
3037db96d56Sopenharmony_ci    global tempdir
3047db96d56Sopenharmony_ci    if tempdir is None:
3057db96d56Sopenharmony_ci        _once_lock.acquire()
3067db96d56Sopenharmony_ci        try:
3077db96d56Sopenharmony_ci            if tempdir is None:
3087db96d56Sopenharmony_ci                tempdir = _get_default_tempdir()
3097db96d56Sopenharmony_ci        finally:
3107db96d56Sopenharmony_ci            _once_lock.release()
3117db96d56Sopenharmony_ci    return tempdir
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_cidef gettempdir():
3147db96d56Sopenharmony_ci    """Returns tempfile.tempdir as str."""
3157db96d56Sopenharmony_ci    return _os.fsdecode(_gettempdir())
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_cidef gettempdirb():
3187db96d56Sopenharmony_ci    """Returns tempfile.tempdir as bytes."""
3197db96d56Sopenharmony_ci    return _os.fsencode(_gettempdir())
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_cidef mkstemp(suffix=None, prefix=None, dir=None, text=False):
3227db96d56Sopenharmony_ci    """User-callable function to create and return a unique temporary
3237db96d56Sopenharmony_ci    file.  The return value is a pair (fd, name) where fd is the
3247db96d56Sopenharmony_ci    file descriptor returned by os.open, and name is the filename.
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci    If 'suffix' is not None, the file name will end with that suffix,
3277db96d56Sopenharmony_ci    otherwise there will be no suffix.
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci    If 'prefix' is not None, the file name will begin with that prefix,
3307db96d56Sopenharmony_ci    otherwise a default prefix is used.
3317db96d56Sopenharmony_ci
3327db96d56Sopenharmony_ci    If 'dir' is not None, the file will be created in that directory,
3337db96d56Sopenharmony_ci    otherwise a default directory is used.
3347db96d56Sopenharmony_ci
3357db96d56Sopenharmony_ci    If 'text' is specified and true, the file is opened in text
3367db96d56Sopenharmony_ci    mode.  Else (the default) the file is opened in binary mode.
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci    If any of 'suffix', 'prefix' and 'dir' are not None, they must be the
3397db96d56Sopenharmony_ci    same type.  If they are bytes, the returned name will be bytes; str
3407db96d56Sopenharmony_ci    otherwise.
3417db96d56Sopenharmony_ci
3427db96d56Sopenharmony_ci    The file is readable and writable only by the creating user ID.
3437db96d56Sopenharmony_ci    If the operating system uses permission bits to indicate whether a
3447db96d56Sopenharmony_ci    file is executable, the file is executable by no one. The file
3457db96d56Sopenharmony_ci    descriptor is not inherited by children of this process.
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ci    Caller is responsible for deleting the file when done with it.
3487db96d56Sopenharmony_ci    """
3497db96d56Sopenharmony_ci
3507db96d56Sopenharmony_ci    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci    if text:
3537db96d56Sopenharmony_ci        flags = _text_openflags
3547db96d56Sopenharmony_ci    else:
3557db96d56Sopenharmony_ci        flags = _bin_openflags
3567db96d56Sopenharmony_ci
3577db96d56Sopenharmony_ci    return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci
3607db96d56Sopenharmony_cidef mkdtemp(suffix=None, prefix=None, dir=None):
3617db96d56Sopenharmony_ci    """User-callable function to create and return a unique temporary
3627db96d56Sopenharmony_ci    directory.  The return value is the pathname of the directory.
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci    Arguments are as for mkstemp, except that the 'text' argument is
3657db96d56Sopenharmony_ci    not accepted.
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci    The directory is readable, writable, and searchable only by the
3687db96d56Sopenharmony_ci    creating user.
3697db96d56Sopenharmony_ci
3707db96d56Sopenharmony_ci    Caller is responsible for deleting the directory when done with it.
3717db96d56Sopenharmony_ci    """
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_ci    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_ci    names = _get_candidate_names()
3767db96d56Sopenharmony_ci    if output_type is bytes:
3777db96d56Sopenharmony_ci        names = map(_os.fsencode, names)
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci    for seq in range(TMP_MAX):
3807db96d56Sopenharmony_ci        name = next(names)
3817db96d56Sopenharmony_ci        file = _os.path.join(dir, prefix + name + suffix)
3827db96d56Sopenharmony_ci        _sys.audit("tempfile.mkdtemp", file)
3837db96d56Sopenharmony_ci        try:
3847db96d56Sopenharmony_ci            _os.mkdir(file, 0o700)
3857db96d56Sopenharmony_ci        except FileExistsError:
3867db96d56Sopenharmony_ci            continue    # try again
3877db96d56Sopenharmony_ci        except PermissionError:
3887db96d56Sopenharmony_ci            # This exception is thrown when a directory with the chosen name
3897db96d56Sopenharmony_ci            # already exists on windows.
3907db96d56Sopenharmony_ci            if (_os.name == 'nt' and _os.path.isdir(dir) and
3917db96d56Sopenharmony_ci                _os.access(dir, _os.W_OK)):
3927db96d56Sopenharmony_ci                continue
3937db96d56Sopenharmony_ci            else:
3947db96d56Sopenharmony_ci                raise
3957db96d56Sopenharmony_ci        return file
3967db96d56Sopenharmony_ci
3977db96d56Sopenharmony_ci    raise FileExistsError(_errno.EEXIST,
3987db96d56Sopenharmony_ci                          "No usable temporary directory name found")
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_cidef mktemp(suffix="", prefix=template, dir=None):
4017db96d56Sopenharmony_ci    """User-callable function to return a unique temporary file name.  The
4027db96d56Sopenharmony_ci    file is not created.
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci    Arguments are similar to mkstemp, except that the 'text' argument is
4057db96d56Sopenharmony_ci    not accepted, and suffix=None, prefix=None and bytes file names are not
4067db96d56Sopenharmony_ci    supported.
4077db96d56Sopenharmony_ci
4087db96d56Sopenharmony_ci    THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED.  The file name may
4097db96d56Sopenharmony_ci    refer to a file that did not exist at some point, but by the time
4107db96d56Sopenharmony_ci    you get around to creating it, someone else may have beaten you to
4117db96d56Sopenharmony_ci    the punch.
4127db96d56Sopenharmony_ci    """
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci##    from warnings import warn as _warn
4157db96d56Sopenharmony_ci##    _warn("mktemp is a potential security risk to your program",
4167db96d56Sopenharmony_ci##          RuntimeWarning, stacklevel=2)
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci    if dir is None:
4197db96d56Sopenharmony_ci        dir = gettempdir()
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci    names = _get_candidate_names()
4227db96d56Sopenharmony_ci    for seq in range(TMP_MAX):
4237db96d56Sopenharmony_ci        name = next(names)
4247db96d56Sopenharmony_ci        file = _os.path.join(dir, prefix + name + suffix)
4257db96d56Sopenharmony_ci        if not _exists(file):
4267db96d56Sopenharmony_ci            return file
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci    raise FileExistsError(_errno.EEXIST,
4297db96d56Sopenharmony_ci                          "No usable temporary filename found")
4307db96d56Sopenharmony_ci
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ciclass _TemporaryFileCloser:
4337db96d56Sopenharmony_ci    """A separate object allowing proper closing of a temporary file's
4347db96d56Sopenharmony_ci    underlying file object, without adding a __del__ method to the
4357db96d56Sopenharmony_ci    temporary file."""
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci    file = None  # Set here since __del__ checks it
4387db96d56Sopenharmony_ci    close_called = False
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ci    def __init__(self, file, name, delete=True):
4417db96d56Sopenharmony_ci        self.file = file
4427db96d56Sopenharmony_ci        self.name = name
4437db96d56Sopenharmony_ci        self.delete = delete
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci    # NT provides delete-on-close as a primitive, so we don't need
4467db96d56Sopenharmony_ci    # the wrapper to do anything special.  We still use it so that
4477db96d56Sopenharmony_ci    # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
4487db96d56Sopenharmony_ci    if _os.name != 'nt':
4497db96d56Sopenharmony_ci        # Cache the unlinker so we don't get spurious errors at
4507db96d56Sopenharmony_ci        # shutdown when the module-level "os" is None'd out.  Note
4517db96d56Sopenharmony_ci        # that this must be referenced as self.unlink, because the
4527db96d56Sopenharmony_ci        # name TemporaryFileWrapper may also get None'd out before
4537db96d56Sopenharmony_ci        # __del__ is called.
4547db96d56Sopenharmony_ci
4557db96d56Sopenharmony_ci        def close(self, unlink=_os.unlink):
4567db96d56Sopenharmony_ci            if not self.close_called and self.file is not None:
4577db96d56Sopenharmony_ci                self.close_called = True
4587db96d56Sopenharmony_ci                try:
4597db96d56Sopenharmony_ci                    self.file.close()
4607db96d56Sopenharmony_ci                finally:
4617db96d56Sopenharmony_ci                    if self.delete:
4627db96d56Sopenharmony_ci                        unlink(self.name)
4637db96d56Sopenharmony_ci
4647db96d56Sopenharmony_ci        # Need to ensure the file is deleted on __del__
4657db96d56Sopenharmony_ci        def __del__(self):
4667db96d56Sopenharmony_ci            self.close()
4677db96d56Sopenharmony_ci
4687db96d56Sopenharmony_ci    else:
4697db96d56Sopenharmony_ci        def close(self):
4707db96d56Sopenharmony_ci            if not self.close_called:
4717db96d56Sopenharmony_ci                self.close_called = True
4727db96d56Sopenharmony_ci                self.file.close()
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci
4757db96d56Sopenharmony_ciclass _TemporaryFileWrapper:
4767db96d56Sopenharmony_ci    """Temporary file wrapper
4777db96d56Sopenharmony_ci
4787db96d56Sopenharmony_ci    This class provides a wrapper around files opened for
4797db96d56Sopenharmony_ci    temporary use.  In particular, it seeks to automatically
4807db96d56Sopenharmony_ci    remove the file when it is no longer needed.
4817db96d56Sopenharmony_ci    """
4827db96d56Sopenharmony_ci
4837db96d56Sopenharmony_ci    def __init__(self, file, name, delete=True):
4847db96d56Sopenharmony_ci        self.file = file
4857db96d56Sopenharmony_ci        self.name = name
4867db96d56Sopenharmony_ci        self.delete = delete
4877db96d56Sopenharmony_ci        self._closer = _TemporaryFileCloser(file, name, delete)
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci    def __getattr__(self, name):
4907db96d56Sopenharmony_ci        # Attribute lookups are delegated to the underlying file
4917db96d56Sopenharmony_ci        # and cached for non-numeric results
4927db96d56Sopenharmony_ci        # (i.e. methods are cached, closed and friends are not)
4937db96d56Sopenharmony_ci        file = self.__dict__['file']
4947db96d56Sopenharmony_ci        a = getattr(file, name)
4957db96d56Sopenharmony_ci        if hasattr(a, '__call__'):
4967db96d56Sopenharmony_ci            func = a
4977db96d56Sopenharmony_ci            @_functools.wraps(func)
4987db96d56Sopenharmony_ci            def func_wrapper(*args, **kwargs):
4997db96d56Sopenharmony_ci                return func(*args, **kwargs)
5007db96d56Sopenharmony_ci            # Avoid closing the file as long as the wrapper is alive,
5017db96d56Sopenharmony_ci            # see issue #18879.
5027db96d56Sopenharmony_ci            func_wrapper._closer = self._closer
5037db96d56Sopenharmony_ci            a = func_wrapper
5047db96d56Sopenharmony_ci        if not isinstance(a, int):
5057db96d56Sopenharmony_ci            setattr(self, name, a)
5067db96d56Sopenharmony_ci        return a
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci    # The underlying __enter__ method returns the wrong object
5097db96d56Sopenharmony_ci    # (self.file) so override it to return the wrapper
5107db96d56Sopenharmony_ci    def __enter__(self):
5117db96d56Sopenharmony_ci        self.file.__enter__()
5127db96d56Sopenharmony_ci        return self
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ci    # Need to trap __exit__ as well to ensure the file gets
5157db96d56Sopenharmony_ci    # deleted when used in a with statement
5167db96d56Sopenharmony_ci    def __exit__(self, exc, value, tb):
5177db96d56Sopenharmony_ci        result = self.file.__exit__(exc, value, tb)
5187db96d56Sopenharmony_ci        self.close()
5197db96d56Sopenharmony_ci        return result
5207db96d56Sopenharmony_ci
5217db96d56Sopenharmony_ci    def close(self):
5227db96d56Sopenharmony_ci        """
5237db96d56Sopenharmony_ci        Close the temporary file, possibly deleting it.
5247db96d56Sopenharmony_ci        """
5257db96d56Sopenharmony_ci        self._closer.close()
5267db96d56Sopenharmony_ci
5277db96d56Sopenharmony_ci    # iter() doesn't use __getattr__ to find the __iter__ method
5287db96d56Sopenharmony_ci    def __iter__(self):
5297db96d56Sopenharmony_ci        # Don't return iter(self.file), but yield from it to avoid closing
5307db96d56Sopenharmony_ci        # file as long as it's being used as iterator (see issue #23700).  We
5317db96d56Sopenharmony_ci        # can't use 'yield from' here because iter(file) returns the file
5327db96d56Sopenharmony_ci        # object itself, which has a close method, and thus the file would get
5337db96d56Sopenharmony_ci        # closed when the generator is finalized, due to PEP380 semantics.
5347db96d56Sopenharmony_ci        for line in self.file:
5357db96d56Sopenharmony_ci            yield line
5367db96d56Sopenharmony_ci
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_cidef NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
5397db96d56Sopenharmony_ci                       newline=None, suffix=None, prefix=None,
5407db96d56Sopenharmony_ci                       dir=None, delete=True, *, errors=None):
5417db96d56Sopenharmony_ci    """Create and return a temporary file.
5427db96d56Sopenharmony_ci    Arguments:
5437db96d56Sopenharmony_ci    'prefix', 'suffix', 'dir' -- as for mkstemp.
5447db96d56Sopenharmony_ci    'mode' -- the mode argument to io.open (default "w+b").
5457db96d56Sopenharmony_ci    'buffering' -- the buffer size argument to io.open (default -1).
5467db96d56Sopenharmony_ci    'encoding' -- the encoding argument to io.open (default None)
5477db96d56Sopenharmony_ci    'newline' -- the newline argument to io.open (default None)
5487db96d56Sopenharmony_ci    'delete' -- whether the file is deleted on close (default True).
5497db96d56Sopenharmony_ci    'errors' -- the errors argument to io.open (default None)
5507db96d56Sopenharmony_ci    The file is created as mkstemp() would do it.
5517db96d56Sopenharmony_ci
5527db96d56Sopenharmony_ci    Returns an object with a file-like interface; the name of the file
5537db96d56Sopenharmony_ci    is accessible as its 'name' attribute.  The file will be automatically
5547db96d56Sopenharmony_ci    deleted when it is closed unless the 'delete' argument is set to False.
5557db96d56Sopenharmony_ci
5567db96d56Sopenharmony_ci    On POSIX, NamedTemporaryFiles cannot be automatically deleted if
5577db96d56Sopenharmony_ci    the creating process is terminated abruptly with a SIGKILL signal.
5587db96d56Sopenharmony_ci    Windows can delete the file even in this case.
5597db96d56Sopenharmony_ci    """
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
5627db96d56Sopenharmony_ci
5637db96d56Sopenharmony_ci    flags = _bin_openflags
5647db96d56Sopenharmony_ci
5657db96d56Sopenharmony_ci    # Setting O_TEMPORARY in the flags causes the OS to delete
5667db96d56Sopenharmony_ci    # the file when it is closed.  This is only supported by Windows.
5677db96d56Sopenharmony_ci    if _os.name == 'nt' and delete:
5687db96d56Sopenharmony_ci        flags |= _os.O_TEMPORARY
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ci    if "b" not in mode:
5717db96d56Sopenharmony_ci        encoding = _io.text_encoding(encoding)
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_ci    name = None
5747db96d56Sopenharmony_ci    def opener(*args):
5757db96d56Sopenharmony_ci        nonlocal name
5767db96d56Sopenharmony_ci        fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
5777db96d56Sopenharmony_ci        return fd
5787db96d56Sopenharmony_ci    try:
5797db96d56Sopenharmony_ci        file = _io.open(dir, mode, buffering=buffering,
5807db96d56Sopenharmony_ci                        newline=newline, encoding=encoding, errors=errors,
5817db96d56Sopenharmony_ci                        opener=opener)
5827db96d56Sopenharmony_ci        try:
5837db96d56Sopenharmony_ci            raw = getattr(file, 'buffer', file)
5847db96d56Sopenharmony_ci            raw = getattr(raw, 'raw', raw)
5857db96d56Sopenharmony_ci            raw.name = name
5867db96d56Sopenharmony_ci            return _TemporaryFileWrapper(file, name, delete)
5877db96d56Sopenharmony_ci        except:
5887db96d56Sopenharmony_ci            file.close()
5897db96d56Sopenharmony_ci            raise
5907db96d56Sopenharmony_ci    except:
5917db96d56Sopenharmony_ci        if name is not None and not (_os.name == 'nt' and delete):
5927db96d56Sopenharmony_ci            _os.unlink(name)
5937db96d56Sopenharmony_ci        raise
5947db96d56Sopenharmony_ci
5957db96d56Sopenharmony_ciif _os.name != 'posix' or _sys.platform == 'cygwin':
5967db96d56Sopenharmony_ci    # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
5977db96d56Sopenharmony_ci    # while it is open.
5987db96d56Sopenharmony_ci    TemporaryFile = NamedTemporaryFile
5997db96d56Sopenharmony_ci
6007db96d56Sopenharmony_cielse:
6017db96d56Sopenharmony_ci    # Is the O_TMPFILE flag available and does it work?
6027db96d56Sopenharmony_ci    # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an
6037db96d56Sopenharmony_ci    # IsADirectoryError exception
6047db96d56Sopenharmony_ci    _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE')
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci    def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
6077db96d56Sopenharmony_ci                      newline=None, suffix=None, prefix=None,
6087db96d56Sopenharmony_ci                      dir=None, *, errors=None):
6097db96d56Sopenharmony_ci        """Create and return a temporary file.
6107db96d56Sopenharmony_ci        Arguments:
6117db96d56Sopenharmony_ci        'prefix', 'suffix', 'dir' -- as for mkstemp.
6127db96d56Sopenharmony_ci        'mode' -- the mode argument to io.open (default "w+b").
6137db96d56Sopenharmony_ci        'buffering' -- the buffer size argument to io.open (default -1).
6147db96d56Sopenharmony_ci        'encoding' -- the encoding argument to io.open (default None)
6157db96d56Sopenharmony_ci        'newline' -- the newline argument to io.open (default None)
6167db96d56Sopenharmony_ci        'errors' -- the errors argument to io.open (default None)
6177db96d56Sopenharmony_ci        The file is created as mkstemp() would do it.
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_ci        Returns an object with a file-like interface.  The file has no
6207db96d56Sopenharmony_ci        name, and will cease to exist when it is closed.
6217db96d56Sopenharmony_ci        """
6227db96d56Sopenharmony_ci        global _O_TMPFILE_WORKS
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_ci        if "b" not in mode:
6257db96d56Sopenharmony_ci            encoding = _io.text_encoding(encoding)
6267db96d56Sopenharmony_ci
6277db96d56Sopenharmony_ci        prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci        flags = _bin_openflags
6307db96d56Sopenharmony_ci        if _O_TMPFILE_WORKS:
6317db96d56Sopenharmony_ci            fd = None
6327db96d56Sopenharmony_ci            def opener(*args):
6337db96d56Sopenharmony_ci                nonlocal fd
6347db96d56Sopenharmony_ci                flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT
6357db96d56Sopenharmony_ci                fd = _os.open(dir, flags2, 0o600)
6367db96d56Sopenharmony_ci                return fd
6377db96d56Sopenharmony_ci            try:
6387db96d56Sopenharmony_ci                file = _io.open(dir, mode, buffering=buffering,
6397db96d56Sopenharmony_ci                                newline=newline, encoding=encoding,
6407db96d56Sopenharmony_ci                                errors=errors, opener=opener)
6417db96d56Sopenharmony_ci                raw = getattr(file, 'buffer', file)
6427db96d56Sopenharmony_ci                raw = getattr(raw, 'raw', raw)
6437db96d56Sopenharmony_ci                raw.name = fd
6447db96d56Sopenharmony_ci                return file
6457db96d56Sopenharmony_ci            except IsADirectoryError:
6467db96d56Sopenharmony_ci                # Linux kernel older than 3.11 ignores the O_TMPFILE flag:
6477db96d56Sopenharmony_ci                # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory
6487db96d56Sopenharmony_ci                # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a
6497db96d56Sopenharmony_ci                # directory cannot be open to write. Set flag to False to not
6507db96d56Sopenharmony_ci                # try again.
6517db96d56Sopenharmony_ci                _O_TMPFILE_WORKS = False
6527db96d56Sopenharmony_ci            except OSError:
6537db96d56Sopenharmony_ci                # The filesystem of the directory does not support O_TMPFILE.
6547db96d56Sopenharmony_ci                # For example, OSError(95, 'Operation not supported').
6557db96d56Sopenharmony_ci                #
6567db96d56Sopenharmony_ci                # On Linux kernel older than 3.11, trying to open a regular
6577db96d56Sopenharmony_ci                # file (or a symbolic link to a regular file) with O_TMPFILE
6587db96d56Sopenharmony_ci                # fails with NotADirectoryError, because O_TMPFILE is read as
6597db96d56Sopenharmony_ci                # O_DIRECTORY.
6607db96d56Sopenharmony_ci                pass
6617db96d56Sopenharmony_ci            # Fallback to _mkstemp_inner().
6627db96d56Sopenharmony_ci
6637db96d56Sopenharmony_ci        fd = None
6647db96d56Sopenharmony_ci        def opener(*args):
6657db96d56Sopenharmony_ci            nonlocal fd
6667db96d56Sopenharmony_ci            fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
6677db96d56Sopenharmony_ci            try:
6687db96d56Sopenharmony_ci                _os.unlink(name)
6697db96d56Sopenharmony_ci            except BaseException as e:
6707db96d56Sopenharmony_ci                _os.close(fd)
6717db96d56Sopenharmony_ci                raise
6727db96d56Sopenharmony_ci            return fd
6737db96d56Sopenharmony_ci        file = _io.open(dir, mode, buffering=buffering,
6747db96d56Sopenharmony_ci                        newline=newline, encoding=encoding, errors=errors,
6757db96d56Sopenharmony_ci                        opener=opener)
6767db96d56Sopenharmony_ci        raw = getattr(file, 'buffer', file)
6777db96d56Sopenharmony_ci        raw = getattr(raw, 'raw', raw)
6787db96d56Sopenharmony_ci        raw.name = fd
6797db96d56Sopenharmony_ci        return file
6807db96d56Sopenharmony_ci
6817db96d56Sopenharmony_ciclass SpooledTemporaryFile(_io.IOBase):
6827db96d56Sopenharmony_ci    """Temporary file wrapper, specialized to switch from BytesIO
6837db96d56Sopenharmony_ci    or StringIO to a real file when it exceeds a certain size or
6847db96d56Sopenharmony_ci    when a fileno is needed.
6857db96d56Sopenharmony_ci    """
6867db96d56Sopenharmony_ci    _rolled = False
6877db96d56Sopenharmony_ci
6887db96d56Sopenharmony_ci    def __init__(self, max_size=0, mode='w+b', buffering=-1,
6897db96d56Sopenharmony_ci                 encoding=None, newline=None,
6907db96d56Sopenharmony_ci                 suffix=None, prefix=None, dir=None, *, errors=None):
6917db96d56Sopenharmony_ci        if 'b' in mode:
6927db96d56Sopenharmony_ci            self._file = _io.BytesIO()
6937db96d56Sopenharmony_ci        else:
6947db96d56Sopenharmony_ci            encoding = _io.text_encoding(encoding)
6957db96d56Sopenharmony_ci            self._file = _io.TextIOWrapper(_io.BytesIO(),
6967db96d56Sopenharmony_ci                            encoding=encoding, errors=errors,
6977db96d56Sopenharmony_ci                            newline=newline)
6987db96d56Sopenharmony_ci        self._max_size = max_size
6997db96d56Sopenharmony_ci        self._rolled = False
7007db96d56Sopenharmony_ci        self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
7017db96d56Sopenharmony_ci                                   'suffix': suffix, 'prefix': prefix,
7027db96d56Sopenharmony_ci                                   'encoding': encoding, 'newline': newline,
7037db96d56Sopenharmony_ci                                   'dir': dir, 'errors': errors}
7047db96d56Sopenharmony_ci
7057db96d56Sopenharmony_ci    __class_getitem__ = classmethod(_types.GenericAlias)
7067db96d56Sopenharmony_ci
7077db96d56Sopenharmony_ci    def _check(self, file):
7087db96d56Sopenharmony_ci        if self._rolled: return
7097db96d56Sopenharmony_ci        max_size = self._max_size
7107db96d56Sopenharmony_ci        if max_size and file.tell() > max_size:
7117db96d56Sopenharmony_ci            self.rollover()
7127db96d56Sopenharmony_ci
7137db96d56Sopenharmony_ci    def rollover(self):
7147db96d56Sopenharmony_ci        if self._rolled: return
7157db96d56Sopenharmony_ci        file = self._file
7167db96d56Sopenharmony_ci        newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
7177db96d56Sopenharmony_ci        del self._TemporaryFileArgs
7187db96d56Sopenharmony_ci
7197db96d56Sopenharmony_ci        pos = file.tell()
7207db96d56Sopenharmony_ci        if hasattr(newfile, 'buffer'):
7217db96d56Sopenharmony_ci            newfile.buffer.write(file.detach().getvalue())
7227db96d56Sopenharmony_ci        else:
7237db96d56Sopenharmony_ci            newfile.write(file.getvalue())
7247db96d56Sopenharmony_ci        newfile.seek(pos, 0)
7257db96d56Sopenharmony_ci
7267db96d56Sopenharmony_ci        self._rolled = True
7277db96d56Sopenharmony_ci
7287db96d56Sopenharmony_ci    # The method caching trick from NamedTemporaryFile
7297db96d56Sopenharmony_ci    # won't work here, because _file may change from a
7307db96d56Sopenharmony_ci    # BytesIO/StringIO instance to a real file. So we list
7317db96d56Sopenharmony_ci    # all the methods directly.
7327db96d56Sopenharmony_ci
7337db96d56Sopenharmony_ci    # Context management protocol
7347db96d56Sopenharmony_ci    def __enter__(self):
7357db96d56Sopenharmony_ci        if self._file.closed:
7367db96d56Sopenharmony_ci            raise ValueError("Cannot enter context with closed file")
7377db96d56Sopenharmony_ci        return self
7387db96d56Sopenharmony_ci
7397db96d56Sopenharmony_ci    def __exit__(self, exc, value, tb):
7407db96d56Sopenharmony_ci        self._file.close()
7417db96d56Sopenharmony_ci
7427db96d56Sopenharmony_ci    # file protocol
7437db96d56Sopenharmony_ci    def __iter__(self):
7447db96d56Sopenharmony_ci        return self._file.__iter__()
7457db96d56Sopenharmony_ci
7467db96d56Sopenharmony_ci    def __del__(self):
7477db96d56Sopenharmony_ci        if not self.closed:
7487db96d56Sopenharmony_ci            _warnings.warn(
7497db96d56Sopenharmony_ci                "Unclosed file {!r}".format(self),
7507db96d56Sopenharmony_ci                ResourceWarning,
7517db96d56Sopenharmony_ci                stacklevel=2,
7527db96d56Sopenharmony_ci                source=self
7537db96d56Sopenharmony_ci            )
7547db96d56Sopenharmony_ci            self.close()
7557db96d56Sopenharmony_ci
7567db96d56Sopenharmony_ci    def close(self):
7577db96d56Sopenharmony_ci        self._file.close()
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci    @property
7607db96d56Sopenharmony_ci    def closed(self):
7617db96d56Sopenharmony_ci        return self._file.closed
7627db96d56Sopenharmony_ci
7637db96d56Sopenharmony_ci    @property
7647db96d56Sopenharmony_ci    def encoding(self):
7657db96d56Sopenharmony_ci        return self._file.encoding
7667db96d56Sopenharmony_ci
7677db96d56Sopenharmony_ci    @property
7687db96d56Sopenharmony_ci    def errors(self):
7697db96d56Sopenharmony_ci        return self._file.errors
7707db96d56Sopenharmony_ci
7717db96d56Sopenharmony_ci    def fileno(self):
7727db96d56Sopenharmony_ci        self.rollover()
7737db96d56Sopenharmony_ci        return self._file.fileno()
7747db96d56Sopenharmony_ci
7757db96d56Sopenharmony_ci    def flush(self):
7767db96d56Sopenharmony_ci        self._file.flush()
7777db96d56Sopenharmony_ci
7787db96d56Sopenharmony_ci    def isatty(self):
7797db96d56Sopenharmony_ci        return self._file.isatty()
7807db96d56Sopenharmony_ci
7817db96d56Sopenharmony_ci    @property
7827db96d56Sopenharmony_ci    def mode(self):
7837db96d56Sopenharmony_ci        try:
7847db96d56Sopenharmony_ci            return self._file.mode
7857db96d56Sopenharmony_ci        except AttributeError:
7867db96d56Sopenharmony_ci            return self._TemporaryFileArgs['mode']
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_ci    @property
7897db96d56Sopenharmony_ci    def name(self):
7907db96d56Sopenharmony_ci        try:
7917db96d56Sopenharmony_ci            return self._file.name
7927db96d56Sopenharmony_ci        except AttributeError:
7937db96d56Sopenharmony_ci            return None
7947db96d56Sopenharmony_ci
7957db96d56Sopenharmony_ci    @property
7967db96d56Sopenharmony_ci    def newlines(self):
7977db96d56Sopenharmony_ci        return self._file.newlines
7987db96d56Sopenharmony_ci
7997db96d56Sopenharmony_ci    def readable(self):
8007db96d56Sopenharmony_ci        return self._file.readable()
8017db96d56Sopenharmony_ci
8027db96d56Sopenharmony_ci    def read(self, *args):
8037db96d56Sopenharmony_ci        return self._file.read(*args)
8047db96d56Sopenharmony_ci
8057db96d56Sopenharmony_ci    def read1(self, *args):
8067db96d56Sopenharmony_ci        return self._file.read1(*args)
8077db96d56Sopenharmony_ci
8087db96d56Sopenharmony_ci    def readinto(self, b):
8097db96d56Sopenharmony_ci        return self._file.readinto(b)
8107db96d56Sopenharmony_ci
8117db96d56Sopenharmony_ci    def readinto1(self, b):
8127db96d56Sopenharmony_ci        return self._file.readinto1(b)
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci    def readline(self, *args):
8157db96d56Sopenharmony_ci        return self._file.readline(*args)
8167db96d56Sopenharmony_ci
8177db96d56Sopenharmony_ci    def readlines(self, *args):
8187db96d56Sopenharmony_ci        return self._file.readlines(*args)
8197db96d56Sopenharmony_ci
8207db96d56Sopenharmony_ci    def seekable(self):
8217db96d56Sopenharmony_ci        return self._file.seekable()
8227db96d56Sopenharmony_ci
8237db96d56Sopenharmony_ci    def seek(self, *args):
8247db96d56Sopenharmony_ci        return self._file.seek(*args)
8257db96d56Sopenharmony_ci
8267db96d56Sopenharmony_ci    def tell(self):
8277db96d56Sopenharmony_ci        return self._file.tell()
8287db96d56Sopenharmony_ci
8297db96d56Sopenharmony_ci    def truncate(self, size=None):
8307db96d56Sopenharmony_ci        if size is None:
8317db96d56Sopenharmony_ci            return self._file.truncate()
8327db96d56Sopenharmony_ci        else:
8337db96d56Sopenharmony_ci            if size > self._max_size:
8347db96d56Sopenharmony_ci                self.rollover()
8357db96d56Sopenharmony_ci            return self._file.truncate(size)
8367db96d56Sopenharmony_ci
8377db96d56Sopenharmony_ci    def writable(self):
8387db96d56Sopenharmony_ci        return self._file.writable()
8397db96d56Sopenharmony_ci
8407db96d56Sopenharmony_ci    def write(self, s):
8417db96d56Sopenharmony_ci        file = self._file
8427db96d56Sopenharmony_ci        rv = file.write(s)
8437db96d56Sopenharmony_ci        self._check(file)
8447db96d56Sopenharmony_ci        return rv
8457db96d56Sopenharmony_ci
8467db96d56Sopenharmony_ci    def writelines(self, iterable):
8477db96d56Sopenharmony_ci        file = self._file
8487db96d56Sopenharmony_ci        rv = file.writelines(iterable)
8497db96d56Sopenharmony_ci        self._check(file)
8507db96d56Sopenharmony_ci        return rv
8517db96d56Sopenharmony_ci
8527db96d56Sopenharmony_ci    def detach(self):
8537db96d56Sopenharmony_ci        return self._file.detach()
8547db96d56Sopenharmony_ci
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_ciclass TemporaryDirectory:
8577db96d56Sopenharmony_ci    """Create and return a temporary directory.  This has the same
8587db96d56Sopenharmony_ci    behavior as mkdtemp but can be used as a context manager.  For
8597db96d56Sopenharmony_ci    example:
8607db96d56Sopenharmony_ci
8617db96d56Sopenharmony_ci        with TemporaryDirectory() as tmpdir:
8627db96d56Sopenharmony_ci            ...
8637db96d56Sopenharmony_ci
8647db96d56Sopenharmony_ci    Upon exiting the context, the directory and everything contained
8657db96d56Sopenharmony_ci    in it are removed.
8667db96d56Sopenharmony_ci    """
8677db96d56Sopenharmony_ci
8687db96d56Sopenharmony_ci    def __init__(self, suffix=None, prefix=None, dir=None,
8697db96d56Sopenharmony_ci                 ignore_cleanup_errors=False):
8707db96d56Sopenharmony_ci        self.name = mkdtemp(suffix, prefix, dir)
8717db96d56Sopenharmony_ci        self._ignore_cleanup_errors = ignore_cleanup_errors
8727db96d56Sopenharmony_ci        self._finalizer = _weakref.finalize(
8737db96d56Sopenharmony_ci            self, self._cleanup, self.name,
8747db96d56Sopenharmony_ci            warn_message="Implicitly cleaning up {!r}".format(self),
8757db96d56Sopenharmony_ci            ignore_errors=self._ignore_cleanup_errors)
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_ci    @classmethod
8787db96d56Sopenharmony_ci    def _rmtree(cls, name, ignore_errors=False):
8797db96d56Sopenharmony_ci        def onerror(func, path, exc_info):
8807db96d56Sopenharmony_ci            if issubclass(exc_info[0], PermissionError):
8817db96d56Sopenharmony_ci                try:
8827db96d56Sopenharmony_ci                    if path != name:
8837db96d56Sopenharmony_ci                        _resetperms(_os.path.dirname(path))
8847db96d56Sopenharmony_ci                    _resetperms(path)
8857db96d56Sopenharmony_ci
8867db96d56Sopenharmony_ci                    try:
8877db96d56Sopenharmony_ci                        _os.unlink(path)
8887db96d56Sopenharmony_ci                    # PermissionError is raised on FreeBSD for directories
8897db96d56Sopenharmony_ci                    except (IsADirectoryError, PermissionError):
8907db96d56Sopenharmony_ci                        cls._rmtree(path, ignore_errors=ignore_errors)
8917db96d56Sopenharmony_ci                except FileNotFoundError:
8927db96d56Sopenharmony_ci                    pass
8937db96d56Sopenharmony_ci            elif issubclass(exc_info[0], FileNotFoundError):
8947db96d56Sopenharmony_ci                pass
8957db96d56Sopenharmony_ci            else:
8967db96d56Sopenharmony_ci                if not ignore_errors:
8977db96d56Sopenharmony_ci                    raise
8987db96d56Sopenharmony_ci
8997db96d56Sopenharmony_ci        _shutil.rmtree(name, onerror=onerror)
9007db96d56Sopenharmony_ci
9017db96d56Sopenharmony_ci    @classmethod
9027db96d56Sopenharmony_ci    def _cleanup(cls, name, warn_message, ignore_errors=False):
9037db96d56Sopenharmony_ci        cls._rmtree(name, ignore_errors=ignore_errors)
9047db96d56Sopenharmony_ci        _warnings.warn(warn_message, ResourceWarning)
9057db96d56Sopenharmony_ci
9067db96d56Sopenharmony_ci    def __repr__(self):
9077db96d56Sopenharmony_ci        return "<{} {!r}>".format(self.__class__.__name__, self.name)
9087db96d56Sopenharmony_ci
9097db96d56Sopenharmony_ci    def __enter__(self):
9107db96d56Sopenharmony_ci        return self.name
9117db96d56Sopenharmony_ci
9127db96d56Sopenharmony_ci    def __exit__(self, exc, value, tb):
9137db96d56Sopenharmony_ci        self.cleanup()
9147db96d56Sopenharmony_ci
9157db96d56Sopenharmony_ci    def cleanup(self):
9167db96d56Sopenharmony_ci        if self._finalizer.detach() or _os.path.exists(self.name):
9177db96d56Sopenharmony_ci            self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
9187db96d56Sopenharmony_ci
9197db96d56Sopenharmony_ci    __class_getitem__ = classmethod(_types.GenericAlias)
920