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