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