1 """Temporary files. 2 3 This module provides generic, low- and high-level interfaces for 4 creating temporary files and directories. All of the interfaces 5 provided by this module can be used without fear of race conditions 6 except for 'mktemp'. 'mktemp' is subject to race conditions and 7 should not be used; it is provided for backward compatibility only. 8 9 The default path names are returned as str. If you supply bytes as 10 input, 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 17 This 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 39 import functools as _functools 40 import warnings as _warnings 41 import io as _io 42 import os as _os 43 import shutil as _shutil 44 import errno as _errno 45 from random import Random as _Random 46 import weakref as _weakref 47 48 try: 49 import _thread 50 except 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 55 if hasattr(_os, 'O_NOFOLLOW'): 56 _text_openflags |= _os.O_NOFOLLOW 57 58 _bin_openflags = _text_openflags 59 if hasattr(_os, 'O_BINARY'): 60 _bin_openflags |= _os.O_BINARY 61 62 if hasattr(_os, 'TMP_MAX'): 63 TMP_MAX = _os.TMP_MAX 64 else: 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. 71 template = "tmp" 72 73 # Internal routines. 74 75 _once_lock = _allocate_lock() 76 77 if hasattr(_os, "lstat"): 78 _stat = _os.lstat 79 elif hasattr(_os, "stat"): 80 _stat = _os.stat 81 else: 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 88 def _exists(fn): 89 try: 90 _stat(fn) 91 except OSError: 92 return False 93 else: 94 return True 95 96 97 def _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 118 def _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 136 class _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 163 def _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 188 def _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 235 def _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 249 def _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 279 def gettempprefix(): 280 """The default prefix for temporary directories.""" 281 return template 282 283 def gettempprefixb(): 284 """The default prefix for temporary directories as bytes.""" 285 return _os.fsencode(gettempprefix()) 286 287 tempdir = None 288 289 def 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 301 def gettempdirb(): 302 """A bytes version of tempfile.gettempdir().""" 303 return _os.fsencode(gettempdir()) 304 305 def 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 345 def 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 384 def 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 416 class _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 459 class _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 522 def 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 560 if _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 565 else: 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 629 class 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 777 class 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