temporary files this module provides generic low and highlevel interfaces for creating temporary files and directories all of the interfaces provided by this module can be used without fear of race conditions except for mktemp mktemp is subject to race conditions and should not be used it is provided for backward compatibility only the default path names are returned as str if you supply bytes as input all return values will be in bytes ex tempfile mkstemp 4 tmptmptpu9nin8 tempfile mkdtempsuffixb b tmptmppbi8f0hy this module also provides some data items to the user tmpmax maximum number of names that will be tried before giving up tempdir if this is set to a string before the first use of any routine from this module it will be considered as another candidate location to store temporary files imports this variable was unused for legacy reasons see issue 10354 but as of 3 5 we actually use it at runtime so changing it would have a possibly desirable side effect but we do not want to support that as an api it is undocumented on purpose do not depend on this internal routines look at the type of all args and divine their implied return type returntype none for arg in args if arg is none continue if isinstancearg os pathlike arg os fspatharg if isinstancearg bytes if returntype is str raise typeerrorcan t mix bytes and nonbytes in path components returntype bytes else if returntype is bytes raise typeerrorcan t mix bytes and nonbytes in path components returntype str if returntype is none if tempdir is none or isinstancetempdir str return str tempfile apis return a str by default else we could check for bytes but it ll fail later on anyway return bytes return returntype def sanitizeparamsprefix suffix dir an instance of randomnamesequence generates an endless sequence of unpredictable strings which can safely be incorporated into file names each string is eight characters long multiple threads can safely use the same instance at the same time randomnamesequence is an iterator characters abcdefghijklmnopqrstuvwxyz0123456789 property def rngself curpid os getpid if curpid getattrself rngpid none self rng random self rngpid curpid return self rng def iterself return self def nextself return joinself rng choicesself characters k8 def candidatetempdirlist first try the environment failing that try osspecific locations as a last resort the current directory calculate the default directory to use for temporary files this routine should be called exactly once we determine whether or not a candidate temp dir is usable by trying to create and write to a file in that directory if this is successful the test file is deleted to prevent denial of service the name of the test file must be randomized namer randomnamesequence dirlist candidatetempdirlist for dir in dirlist if dir os curdir dir os path abspathdir try only a few names per directory for seq in range100 name nextnamer filename os path joindir name try fd os openfilename binopenflags 0o600 try try os writefd b blat finally os closefd finally os unlinkfilename return dir except fileexistserror pass except permissionerror this exception is thrown when a directory with the chosen name already exists on windows if os name nt and os path isdirdir and os accessdir os wok continue break no point trying more names in this directory except oserror break no point trying more names in this directory raise filenotfounderrorerrno enoent no usable temporary directory found in s dirlist namesequence none def getcandidatenames code common to mkstemp temporaryfile and namedtemporaryfile dir os path abspathdir names getcandidatenames if outputtype is bytes names mapos fsencode names for seq in rangetmpmax name nextnames file os path joindir pre name suf sys audittempfile mkstemp file try fd os openfile flags 0o600 except fileexistserror continue try again except permissionerror this exception is thrown when a directory with the chosen name already exists on windows if os name nt and os path isdirdir and os accessdir os wok continue else raise return fd file raise fileexistserrorerrno eexist no usable temporary file name found user visible interfaces def gettempprefix the default prefix for temporary directories as bytes return os fsencodetemplate tempdir none def gettempdir returns tempfile tempdir as str return os fsdecodegettempdir def gettempdirb usercallable function to create and return a unique temporary file the return value is a pair fd name where fd is the file descriptor returned by os open and name is the filename if suffix is not none the file name will end with that suffix otherwise there will be no suffix if prefix is not none the file name will begin with that prefix otherwise a default prefix is used if dir is not none the file will be created in that directory otherwise a default directory is used if text is specified and true the file is opened in text mode else the default the file is opened in binary mode if any of suffix prefix and dir are not none they must be the same type if they are bytes the returned name will be bytes str otherwise the file is readable and writable only by the creating user id if the operating system uses permission bits to indicate whether a file is executable the file is executable by no one the file descriptor is not inherited by children of this process caller is responsible for deleting the file when done with it usercallable function to create and return a unique temporary directory the return value is the pathname of the directory arguments are as for mkstemp except that the text argument is not accepted the directory is readable writable and searchable only by the creating user caller is responsible for deleting the directory when done with it this exception is thrown when a directory with the chosen name already exists on windows usercallable function to return a unique temporary file name the file is not created arguments are similar to mkstemp except that the text argument is not accepted and suffixnone prefixnone and bytes file names are not supported this function is unsafe and should not be used the file name may refer to a file that did not exist at some point but by the time you get around to creating it someone else may have beaten you to the punch from warnings import warn as warn warnmktemp is a potential security risk to your program runtimewarning stacklevel2 a separate object allowing proper closing of a temporary file s underlying file object without adding a del method to the temporary file cleanupcalled false closecalled false def initself file name deletetrue deleteonclosetrue self file file self name name self delete delete self deleteonclose deleteonclose def cleanupself windowsos name nt unlinkos unlink if not self cleanupcalled self cleanupcalled true try if not self closecalled self closecalled true self file close finally windows provides deleteonclose as a primitive in which case the file was deleted by self file close if self delete and not windows and self deleteonclose try unlinkself name except filenotfounderror pass def closeself if not self closecalled self closecalled true try self file close finally if self delete and self deleteonclose self cleanup def delself self cleanup class temporaryfilewrapper def initself file name deletetrue deleteonclosetrue self file file self name name self closer temporaryfilecloserfile name delete deleteonclose def getattrself name attribute lookups are delegated to the underlying file and cached for nonnumeric results i e methods are cached closed and friends are not file self dict file a getattrfile name if hasattra call func a functools wrapsfunc def funcwrapperargs kwargs return funcargs kwargs avoid closing the file as long as the wrapper is alive see issue 18879 funcwrapper closer self closer a funcwrapper if not isinstancea int setattrself name a return a the underlying enter method returns the wrong object self file so override it to return the wrapper def enterself self file enter return self need to trap exit as well to ensure the file gets deleted when used in a with statement def exitself exc value tb result self file exitexc value tb self closer cleanup return result def closeself self closer close iter doesn t use getattr to find the iter method def iterself don t return iterself file but yield from it to avoid closing file as long as it s being used as iterator see issue 23700 we can t use yield from here because iterfile returns the file object itself which has a close method and thus the file would get closed when the generator is finalized due to pep380 semantics for line in self file yield line def namedtemporaryfilemode wb buffering1 encodingnone newlinenone suffixnone prefixnone dirnone deletetrue errorsnone deleteonclosetrue prefix suffix dir outputtype sanitizeparamsprefix suffix dir flags binopenflags setting otemporary in the flags causes the os to delete the file when it is closed this is only supported by windows if os name nt and delete and deleteonclose flags os otemporary if b not in mode encoding io textencodingencoding name none def openerargs nonlocal name fd name mkstempinnerdir prefix suffix flags outputtype return fd try file io opendir mode bufferingbuffering newlinenewline encodingencoding errorserrors openeropener try raw getattrfile buffer file raw getattrraw raw raw raw name name return temporaryfilewrapperfile name delete deleteonclose except file close raise except if name is not none and not os name nt and delete and deleteonclose os unlinkname raise if os name posix or sys platform cygwin on nonposix and cygwin systems assume that we cannot unlink a file while it is open temporaryfile namedtemporaryfile else is the otmpfile flag available and does it work the flag is set to false if os opendir os otmpfile raises an isadirectoryerror exception otmpfileworks hasattros otmpfile def temporaryfilemode wb buffering1 encodingnone newlinenone suffixnone prefixnone dirnone errorsnone global otmpfileworks if b not in mode encoding io textencodingencoding prefix suffix dir outputtype sanitizeparamsprefix suffix dir flags binopenflags if otmpfileworks fd none def openerargs nonlocal fd flags2 flags os otmpfile os ocreat fd os opendir flags2 0o600 return fd try file io opendir mode bufferingbuffering newlinenewline encodingencoding errorserrors openeropener raw getattrfile buffer file raw getattrraw raw raw raw name fd return file except isadirectoryerror linux kernel older than 3 11 ignores the otmpfile flag otmpfile is read as odirectory trying to open a directory with ordwrodirectory fails with isadirectoryerror a directory cannot be open to write set flag to false to not try again otmpfileworks false except oserror the filesystem of the directory does not support otmpfile for example oserror95 operation not supported on linux kernel older than 3 11 trying to open a regular file or a symbolic link to a regular file with otmpfile fails with notadirectoryerror because otmpfile is read as odirectory pass fallback to mkstempinner fd none def openerargs nonlocal fd fd name mkstempinnerdir prefix suffix flags outputtype try os unlinkname except baseexception as e os closefd raise return fd file io opendir mode bufferingbuffering newlinenewline encodingencoding errorserrors openeropener raw getattrfile buffer file raw getattrraw raw raw raw name fd return file class spooledtemporaryfileio iobase rolled false def initself maxsize0 mode wb buffering1 encodingnone newlinenone suffixnone prefixnone dirnone errorsnone if b in mode self file io bytesio else encoding io textencodingencoding self file io textiowrapperio bytesio encodingencoding errorserrors newlinenewline self maxsize maxsize self rolled false self temporaryfileargs mode mode buffering buffering suffix suffix prefix prefix encoding encoding newline newline dir dir errors errors classgetitem classmethodtypes genericalias def checkself file if self rolled return maxsize self maxsize if maxsize and file tell maxsize self rollover def rolloverself if self rolled return file self file newfile self file temporaryfileself temporaryfileargs del self temporaryfileargs pos file tell if hasattrnewfile buffer newfile buffer writefile detach getvalue else newfile writefile getvalue newfile seekpos 0 self rolled true the method caching trick from namedtemporaryfile won t work here because file may change from a bytesiostringio instance to a real file so we list all the methods directly context management protocol def enterself if self file closed raise valueerrorcannot enter context with closed file return self def exitself exc value tb self file close file protocol def iterself return self file iter def delself if not self closed warnings warn unclosed file r formatself resourcewarning stacklevel2 sourceself self close def closeself self file close property def closedself return self file closed property def encodingself return self file encoding property def errorsself return self file errors def filenoself self rollover return self file fileno def flushself self file flush def isattyself return self file isatty property def modeself try return self file mode except attributeerror return self temporaryfileargs mode property def nameself try return self file name except attributeerror return none property def newlinesself return self file newlines def readableself return self file readable def readself args return self file readargs def read1self args return self file read1args def readintoself b return self file readintob def readinto1self b return self file readinto1b def readlineself args return self file readlineargs def readlinesself args return self file readlinesargs def seekableself return self file seekable def seekself args return self file seekargs def tellself return self file tell def truncateself sizenone if size is none return self file truncate else if size self maxsize self rollover return self file truncatesize def writableself return self file writable def writeself s file self file rv file writes self checkfile return rv def writelinesself iterable file self file rv file writelinesiterable self checkfile return rv def detachself return self file detach class temporarydirectory def initself suffixnone prefixnone dirnone ignorecleanuperrorsfalse deletetrue self name mkdtempsuffix prefix dir self ignorecleanuperrors ignorecleanuperrors self delete delete self finalizer weakref finalize self self cleanup self name warnmessageimplicitly cleaning up r formatself ignoreerrorsself ignorecleanuperrors deleteself delete classmethod def rmtreecls name ignoreerrorsfalse def onexcfunc path exc if isinstanceexc permissionerror def resetpermspath try os chflagspath 0 except attributeerror pass os chmodpath 0o700 try if path name resetpermsos path dirnamepath resetpermspath try os unlinkpath permissionerror is raised on freebsd for directories except isadirectoryerror permissionerror cls rmtreepath ignoreerrorsignoreerrors except filenotfounderror pass elif isinstanceexc filenotfounderror pass else if not ignoreerrors raise shutil rmtreename onexconexc classmethod def cleanupcls name warnmessage ignoreerrorsfalse deletetrue if delete cls rmtreename ignoreerrorsignoreerrors warnings warnwarnmessage resourcewarning def reprself return r formatself class name self name def enterself return self name def exitself exc value tb if self delete self cleanup def cleanupself if self finalizer detach or os path existsself name self rmtreeself name ignoreerrorsself ignorecleanuperrors classgetitem classmethodtypes genericalias high level safe interfaces low level safe interfaces deprecated unsafe interface constants imports this variable _was_ unused for legacy reasons see issue 10354 but as of 3 5 we actually use it at runtime so changing it would have a possibly desirable side effect but we do not want to support that as an api it is undocumented on purpose do not depend on this internal routines look at the type of all args and divine their implied return type tempfile apis return a str by default we could check for bytes but it ll fail later on anyway common parameter processing for most apis in this module an instance of _randomnamesequence generates an endless sequence of unpredictable strings which can safely be incorporated into file names each string is eight characters long multiple threads can safely use the same instance at the same time _randomnamesequence is an iterator generate a list of candidate temporary directories which _get_default_tempdir will try first try the environment failing that try os specific locations as a last resort the current directory calculate the default directory to use for temporary files this routine should be called exactly once we determine whether or not a candidate temp dir is usable by trying to create and write to a file in that directory if this is successful the test file is deleted to prevent denial of service the name of the test file must be randomized try only a few names per directory this exception is thrown when a directory with the chosen name already exists on windows no point trying more names in this directory no point trying more names in this directory common setup sequence for all user callable interfaces code common to mkstemp temporaryfile and namedtemporaryfile try again this exception is thrown when a directory with the chosen name already exists on windows user visible interfaces the default prefix for temporary directories as string the default prefix for temporary directories as bytes private accessor for tempfile tempdir returns tempfile tempdir as str returns tempfile tempdir as bytes user callable function to create and return a unique temporary file the return value is a pair fd name where fd is the file descriptor returned by os open and name is the filename if suffix is not none the file name will end with that suffix otherwise there will be no suffix if prefix is not none the file name will begin with that prefix otherwise a default prefix is used if dir is not none the file will be created in that directory otherwise a default directory is used if text is specified and true the file is opened in text mode else the default the file is opened in binary mode if any of suffix prefix and dir are not none they must be the same type if they are bytes the returned name will be bytes str otherwise the file is readable and writable only by the creating user id if the operating system uses permission bits to indicate whether a file is executable the file is executable by no one the file descriptor is not inherited by children of this process caller is responsible for deleting the file when done with it user callable function to create and return a unique temporary directory the return value is the pathname of the directory arguments are as for mkstemp except that the text argument is not accepted the directory is readable writable and searchable only by the creating user caller is responsible for deleting the directory when done with it try again this exception is thrown when a directory with the chosen name already exists on windows user callable function to return a unique temporary file name the file is not created arguments are similar to mkstemp except that the text argument is not accepted and suffix none prefix none and bytes file names are not supported this function is unsafe and should not be used the file name may refer to a file that did not exist at some point but by the time you get around to creating it someone else may have beaten you to the punch from warnings import warn as _warn _warn mktemp is a potential security risk to your program runtimewarning stacklevel 2 a separate object allowing proper closing of a temporary file s underlying file object without adding a __del__ method to the temporary file windows provides delete on close as a primitive in which case the file was deleted by self file close temporary file wrapper this class provides a wrapper around files opened for temporary use in particular it seeks to automatically remove the file when it is no longer needed attribute lookups are delegated to the underlying file and cached for non numeric results i e methods are cached closed and friends are not avoid closing the file as long as the wrapper is alive see issue 18879 the underlying __enter__ method returns the wrong object self file so override it to return the wrapper need to trap __exit__ as well to ensure the file gets deleted when used in a with statement close the temporary file possibly deleting it iter doesn t use __getattr__ to find the __iter__ method don t return iter self file but yield from it to avoid closing file as long as it s being used as iterator see issue 23700 we can t use yield from here because iter file returns the file object itself which has a close method and thus the file would get closed when the generator is finalized due to pep380 semantics create and return a temporary file arguments prefix suffix dir as for mkstemp mode the mode argument to io open default w b buffering the buffer size argument to io open default 1 encoding the encoding argument to io open default none newline the newline argument to io open default none delete whether the file is automatically deleted default true delete_on_close if delete whether the file is deleted on close default true or otherwise either on context manager exit if context manager was used or on object finalization errors the errors argument to io open default none the file is created as mkstemp would do it returns an object with a file like interface the name of the file is accessible as its name attribute the file will be automatically deleted when it is closed unless the delete argument is set to false on posix namedtemporaryfiles cannot be automatically deleted if the creating process is terminated abruptly with a sigkill signal windows can delete the file even in this case setting o_temporary in the flags causes the os to delete the file when it is closed this is only supported by windows on non posix and cygwin systems assume that we cannot unlink a file while it is open is the o_tmpfile flag available and does it work the flag is set to false if os open dir os o_tmpfile raises an isadirectoryerror exception create and return a temporary file arguments prefix suffix dir as for mkstemp mode the mode argument to io open default w b buffering the buffer size argument to io open default 1 encoding the encoding argument to io open default none newline the newline argument to io open default none errors the errors argument to io open default none the file is created as mkstemp would do it returns an object with a file like interface the file has no name and will cease to exist when it is closed linux kernel older than 3 11 ignores the o_tmpfile flag o_tmpfile is read as o_directory trying to open a directory with o_rdwr o_directory fails with isadirectoryerror a directory cannot be open to write set flag to false to not try again the filesystem of the directory does not support o_tmpfile for example oserror 95 operation not supported on linux kernel older than 3 11 trying to open a regular file or a symbolic link to a regular file with o_tmpfile fails with notadirectoryerror because o_tmpfile is read as o_directory fallback to _mkstemp_inner temporary file wrapper specialized to switch from bytesio or stringio to a real file when it exceeds a certain size or when a fileno is needed the method caching trick from namedtemporaryfile won t work here because _file may change from a bytesio stringio instance to a real file so we list all the methods directly context management protocol file protocol create and return a temporary directory this has the same behavior as mkdtemp but can be used as a context manager for example with temporarydirectory as tmpdir upon exiting the context the directory and everything contained in it are removed unless delete false is passed or an exception is raised during cleanup and ignore_cleanup_errors is not true optional arguments suffix a str suffix for the directory name see mkdtemp prefix a str prefix for the directory name see mkdtemp dir a directory to create this temp dir in see mkdtemp ignore_cleanup_errors false ignore exceptions during cleanup delete true whether the directory is automatically deleted permissionerror is raised on freebsd for directories
__all__ = [
    "NamedTemporaryFile", "TemporaryFile", 
    "SpooledTemporaryFile", "TemporaryDirectory",
    "mkstemp", "mkdtemp",                  
    "mktemp",                              
    "TMP_MAX", "gettempprefix",            
    "tempdir", "gettempdir",
    "gettempprefixb", "gettempdirb",
   ]




import functools as _functools
import warnings as _warnings
import io as _io
import os as _os
import shutil as _shutil
import errno as _errno
from random import Random as _Random
import sys as _sys
import types as _types
import weakref as _weakref
import _thread
_allocate_lock = _thread.allocate_lock

_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
if hasattr(_os, 'O_NOFOLLOW'):
    _text_openflags |= _os.O_NOFOLLOW

_bin_openflags = _text_openflags
if hasattr(_os, 'O_BINARY'):
    _bin_openflags |= _os.O_BINARY

if hasattr(_os, 'TMP_MAX'):
    TMP_MAX = _os.TMP_MAX
else:
    TMP_MAX = 10000





template = "tmp"



_once_lock = _allocate_lock()


def _exists(fn):
    try:
        _os.lstat(fn)
    except OSError:
        return False
    else:
        return True


def _infer_return_type(*args):
    
    return_type = None
    for arg in args:
        if arg is None:
            continue

        if isinstance(arg, _os.PathLike):
            arg = _os.fspath(arg)

        if isinstance(arg, bytes):
            if return_type is str:
                raise TypeError("Can't mix bytes and non-bytes in "
                                "path components.")
            return_type = bytes
        else:
            if return_type is bytes:
                raise TypeError("Can't mix bytes and non-bytes in "
                                "path components.")
            return_type = str
    if return_type is None:
        if tempdir is None or isinstance(tempdir, str):
            return str  
        else:
            
            return bytes
    return return_type


def _sanitize_params(prefix, suffix, dir):
    
    output_type = _infer_return_type(prefix, suffix, dir)
    if suffix is None:
        suffix = output_type()
    if prefix is None:
        if output_type is str:
            prefix = template
        else:
            prefix = _os.fsencode(template)
    if dir is None:
        if output_type is str:
            dir = gettempdir()
        else:
            dir = gettempdirb()
    return prefix, suffix, dir, output_type


class _RandomNameSequence:
    

    characters = "abcdefghijklmnopqrstuvwxyz0123456789_"

    @property
    def rng(self):
        cur_pid = _os.getpid()
        if cur_pid != getattr(self, '_rng_pid', None):
            self._rng = _Random()
            self._rng_pid = cur_pid
        return self._rng

    def __iter__(self):
        return self

    def __next__(self):
        return ''.join(self.rng.choices(self.characters, k=8))

def _candidate_tempdir_list():
    

    dirlist = []

    
    for envname in 'TMPDIR', 'TEMP', 'TMP':
        dirname = _os.getenv(envname)
        if dirname: dirlist.append(dirname)

    
    if _os.name == 'nt':
        dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'),
                         _os.path.expandvars(r'%SYSTEMROOT%\Temp'),
                         r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
    else:
        dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])

    
    try:
        dirlist.append(_os.getcwd())
    except (AttributeError, OSError):
        dirlist.append(_os.curdir)

    return dirlist

def _get_default_tempdir():
    

    namer = _RandomNameSequence()
    dirlist = _candidate_tempdir_list()

    for dir in dirlist:
        if dir != _os.curdir:
            dir = _os.path.abspath(dir)
        
        for seq in range(100):
            name = next(namer)
            filename = _os.path.join(dir, name)
            try:
                fd = _os.open(filename, _bin_openflags, 0o600)
                try:
                    try:
                        _os.write(fd, b'blat')
                    finally:
                        _os.close(fd)
                finally:
                    _os.unlink(filename)
                return dir
            except FileExistsError:
                pass
            except PermissionError:
                
                
                if (_os.name == 'nt' and _os.path.isdir(dir) and
                    _os.access(dir, _os.W_OK)):
                    continue
                break   
            except OSError:
                break   
    raise FileNotFoundError(_errno.ENOENT,
                            "No usable temporary directory found in %s" %
                            dirlist)

_name_sequence = None

def _get_candidate_names():
    

    global _name_sequence
    if _name_sequence is None:
        _once_lock.acquire()
        try:
            if _name_sequence is None:
                _name_sequence = _RandomNameSequence()
        finally:
            _once_lock.release()
    return _name_sequence


def _mkstemp_inner(dir, pre, suf, flags, output_type):
    

    dir = _os.path.abspath(dir)
    names = _get_candidate_names()
    if output_type is bytes:
        names = map(_os.fsencode, names)

    for seq in range(TMP_MAX):
        name = next(names)
        file = _os.path.join(dir, pre + name + suf)
        _sys.audit("tempfile.mkstemp", file)
        try:
            fd = _os.open(file, flags, 0o600)
        except FileExistsError:
            continue    
        except PermissionError:
            
            
            if (_os.name == 'nt' and _os.path.isdir(dir) and
                _os.access(dir, _os.W_OK)):
                continue
            else:
                raise
        return fd, file

    raise FileExistsError(_errno.EEXIST,
                          "No usable temporary file name found")




def gettempprefix():
    
    return _os.fsdecode(template)

def gettempprefixb():
    
    return _os.fsencode(template)

tempdir = None

def _gettempdir():
    
    global tempdir
    if tempdir is None:
        _once_lock.acquire()
        try:
            if tempdir is None:
                tempdir = _get_default_tempdir()
        finally:
            _once_lock.release()
    return tempdir

def gettempdir():
    
    return _os.fsdecode(_gettempdir())

def gettempdirb():
    
    return _os.fsencode(_gettempdir())

def mkstemp(suffix=None, prefix=None, dir=None, text=False):
    

    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)

    if text:
        flags = _text_openflags
    else:
        flags = _bin_openflags

    return _mkstemp_inner(dir, prefix, suffix, flags, output_type)


def mkdtemp(suffix=None, prefix=None, dir=None):
    

    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)

    names = _get_candidate_names()
    if output_type is bytes:
        names = map(_os.fsencode, names)

    for seq in range(TMP_MAX):
        name = next(names)
        file = _os.path.join(dir, prefix + name + suffix)
        _sys.audit("tempfile.mkdtemp", file)
        try:
            _os.mkdir(file, 0o700)
        except FileExistsError:
            continue    
        except PermissionError:
            
            
            if (_os.name == 'nt' and _os.path.isdir(dir) and
                _os.access(dir, _os.W_OK)):
                continue
            else:
                raise
        return _os.path.abspath(file)

    raise FileExistsError(_errno.EEXIST,
                          "No usable temporary directory name found")

def mktemp(suffix="", prefix=template, dir=None):
    





    if dir is None:
        dir = gettempdir()

    names = _get_candidate_names()
    for seq in range(TMP_MAX):
        name = next(names)
        file = _os.path.join(dir, prefix + name + suffix)
        if not _exists(file):
            return file

    raise FileExistsError(_errno.EEXIST,
                          "No usable temporary filename found")


class _TemporaryFileCloser:
    

    cleanup_called = False
    close_called = False

    def __init__(self, file, name, delete=True, delete_on_close=True):
        self.file = file
        self.name = name
        self.delete = delete
        self.delete_on_close = delete_on_close

    def cleanup(self, windows=(_os.name == 'nt'), unlink=_os.unlink):
        if not self.cleanup_called:
            self.cleanup_called = True
            try:
                if not self.close_called:
                    self.close_called = True
                    self.file.close()
            finally:
                
                
                if self.delete and not (windows and self.delete_on_close):
                    try:
                        unlink(self.name)
                    except FileNotFoundError:
                        pass

    def close(self):
        if not self.close_called:
            self.close_called = True
            try:
                self.file.close()
            finally:
                if self.delete and self.delete_on_close:
                    self.cleanup()

    def __del__(self):
        self.cleanup()


class _TemporaryFileWrapper:
    

    def __init__(self, file, name, delete=True, delete_on_close=True):
        self.file = file
        self.name = name
        self._closer = _TemporaryFileCloser(file, name, delete,
                                            delete_on_close)

    def __getattr__(self, name):
        
        
        
        file = self.__dict__['file']
        a = getattr(file, name)
        if hasattr(a, '__call__'):
            func = a
            @_functools.wraps(func)
            def func_wrapper(*args, **kwargs):
                return func(*args, **kwargs)
            
            
            func_wrapper._closer = self._closer
            a = func_wrapper
        if not isinstance(a, int):
            setattr(self, name, a)
        return a

    
    
    def __enter__(self):
        self.file.__enter__()
        return self

    
    
    def __exit__(self, exc, value, tb):
        result = self.file.__exit__(exc, value, tb)
        self._closer.cleanup()
        return result

    def close(self):
        
        self._closer.close()

    
    def __iter__(self):
        
        
        
        
        
        for line in self.file:
            yield line

def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
                       newline=None, suffix=None, prefix=None,
                       dir=None, delete=True, *, errors=None,
                       delete_on_close=True):
    

    prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)

    flags = _bin_openflags

    
    
    if _os.name == 'nt' and delete and delete_on_close:
        flags |= _os.O_TEMPORARY

    if "b" not in mode:
        encoding = _io.text_encoding(encoding)

    name = None
    def opener(*args):
        nonlocal name
        fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
        return fd
    try:
        file = _io.open(dir, mode, buffering=buffering,
                        newline=newline, encoding=encoding, errors=errors,
                        opener=opener)
        try:
            raw = getattr(file, 'buffer', file)
            raw = getattr(raw, 'raw', raw)
            raw.name = name
            return _TemporaryFileWrapper(file, name, delete, delete_on_close)
        except:
            file.close()
            raise
    except:
        if name is not None and not (
            _os.name == 'nt' and delete and delete_on_close):
            _os.unlink(name)
        raise

if _os.name != 'posix' or _sys.platform == 'cygwin':
    
    
    TemporaryFile = NamedTemporaryFile

else:
    
    
    
    _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE')

    def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
                      newline=None, suffix=None, prefix=None,
                      dir=None, *, errors=None):
        
        global _O_TMPFILE_WORKS

        if "b" not in mode:
            encoding = _io.text_encoding(encoding)

        prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)

        flags = _bin_openflags
        if _O_TMPFILE_WORKS:
            fd = None
            def opener(*args):
                nonlocal fd
                flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT
                fd = _os.open(dir, flags2, 0o600)
                return fd
            try:
                file = _io.open(dir, mode, buffering=buffering,
                                newline=newline, encoding=encoding,
                                errors=errors, opener=opener)
                raw = getattr(file, 'buffer', file)
                raw = getattr(raw, 'raw', raw)
                raw.name = fd
                return file
            except IsADirectoryError:
                
                
                
                
                
                _O_TMPFILE_WORKS = False
            except OSError:
                
                
                
                
                
                
                
                pass
            

        fd = None
        def opener(*args):
            nonlocal fd
            fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
            try:
                _os.unlink(name)
            except BaseException as e:
                _os.close(fd)
                raise
            return fd
        file = _io.open(dir, mode, buffering=buffering,
                        newline=newline, encoding=encoding, errors=errors,
                        opener=opener)
        raw = getattr(file, 'buffer', file)
        raw = getattr(raw, 'raw', raw)
        raw.name = fd
        return file

class SpooledTemporaryFile(_io.IOBase):
    
    _rolled = False

    def __init__(self, max_size=0, mode='w+b', buffering=-1,
                 encoding=None, newline=None,
                 suffix=None, prefix=None, dir=None, *, errors=None):
        if 'b' in mode:
            self._file = _io.BytesIO()
        else:
            encoding = _io.text_encoding(encoding)
            self._file = _io.TextIOWrapper(_io.BytesIO(),
                            encoding=encoding, errors=errors,
                            newline=newline)
        self._max_size = max_size
        self._rolled = False
        self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
                                   'suffix': suffix, 'prefix': prefix,
                                   'encoding': encoding, 'newline': newline,
                                   'dir': dir, 'errors': errors}

    __class_getitem__ = classmethod(_types.GenericAlias)

    def _check(self, file):
        if self._rolled: return
        max_size = self._max_size
        if max_size and file.tell() > max_size:
            self.rollover()

    def rollover(self):
        if self._rolled: return
        file = self._file
        newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
        del self._TemporaryFileArgs

        pos = file.tell()
        if hasattr(newfile, 'buffer'):
            newfile.buffer.write(file.detach().getvalue())
        else:
            newfile.write(file.getvalue())
        newfile.seek(pos, 0)

        self._rolled = True

    
    
    
    

    
    def __enter__(self):
        if self._file.closed:
            raise ValueError("Cannot enter context with closed file")
        return self

    def __exit__(self, exc, value, tb):
        self._file.close()

    
    def __iter__(self):
        return self._file.__iter__()

    def __del__(self):
        if not self.closed:
            _warnings.warn(
                "Unclosed file {!r}".format(self),
                ResourceWarning,
                stacklevel=2,
                source=self
            )
            self.close()

    def close(self):
        self._file.close()

    @property
    def closed(self):
        return self._file.closed

    @property
    def encoding(self):
        return self._file.encoding

    @property
    def errors(self):
        return self._file.errors

    def fileno(self):
        self.rollover()
        return self._file.fileno()

    def flush(self):
        self._file.flush()

    def isatty(self):
        return self._file.isatty()

    @property
    def mode(self):
        try:
            return self._file.mode
        except AttributeError:
            return self._TemporaryFileArgs['mode']

    @property
    def name(self):
        try:
            return self._file.name
        except AttributeError:
            return None

    @property
    def newlines(self):
        return self._file.newlines

    def readable(self):
        return self._file.readable()

    def read(self, *args):
        return self._file.read(*args)

    def read1(self, *args):
        return self._file.read1(*args)

    def readinto(self, b):
        return self._file.readinto(b)

    def readinto1(self, b):
        return self._file.readinto1(b)

    def readline(self, *args):
        return self._file.readline(*args)

    def readlines(self, *args):
        return self._file.readlines(*args)

    def seekable(self):
        return self._file.seekable()

    def seek(self, *args):
        return self._file.seek(*args)

    def tell(self):
        return self._file.tell()

    def truncate(self, size=None):
        if size is None:
            return self._file.truncate()
        else:
            if size > self._max_size:
                self.rollover()
            return self._file.truncate(size)

    def writable(self):
        return self._file.writable()

    def write(self, s):
        file = self._file
        rv = file.write(s)
        self._check(file)
        return rv

    def writelines(self, iterable):
        file = self._file
        rv = file.writelines(iterable)
        self._check(file)
        return rv

    def detach(self):
        return self._file.detach()


class TemporaryDirectory:
    

    def __init__(self, suffix=None, prefix=None, dir=None,
                 ignore_cleanup_errors=False, *, delete=True):
        self.name = mkdtemp(suffix, prefix, dir)
        self._ignore_cleanup_errors = ignore_cleanup_errors
        self._delete = delete
        self._finalizer = _weakref.finalize(
            self, self._cleanup, self.name,
            warn_message="Implicitly cleaning up {!r}".format(self),
            ignore_errors=self._ignore_cleanup_errors, delete=self._delete)

    @classmethod
    def _rmtree(cls, name, ignore_errors=False):
        def onexc(func, path, exc):
            if isinstance(exc, PermissionError):
                def resetperms(path):
                    try:
                        _os.chflags(path, 0)
                    except AttributeError:
                        pass
                    _os.chmod(path, 0o700)

                try:
                    if path != name:
                        resetperms(_os.path.dirname(path))
                    resetperms(path)

                    try:
                        _os.unlink(path)
                    
                    except (IsADirectoryError, PermissionError):
                        cls._rmtree(path, ignore_errors=ignore_errors)
                except FileNotFoundError:
                    pass
            elif isinstance(exc, FileNotFoundError):
                pass
            else:
                if not ignore_errors:
                    raise

        _shutil.rmtree(name, onexc=onexc)

    @classmethod
    def _cleanup(cls, name, warn_message, ignore_errors=False, delete=True):
        if delete:
            cls._rmtree(name, ignore_errors=ignore_errors)
            _warnings.warn(warn_message, ResourceWarning)

    def __repr__(self):
        return "<{} {!r}>".format(self.__class__.__name__, self.name)

    def __enter__(self):
        return self.name

    def __exit__(self, exc, value, tb):
        if self._delete:
            self.cleanup()

    def cleanup(self):
        if self._finalizer.detach() or _os.path.exists(self.name):
            self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)

    __class_getitem__ = classmethod(_types.GenericAlias)