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