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