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 272 273# User visible interfaces. 274 275def gettempprefix(): 276 """The default prefix for temporary directories as string.""" 277 return _os.fsdecode(template) 278 279def gettempprefixb(): 280 """The default prefix for temporary directories as bytes.""" 281 return _os.fsencode(template) 282 283tempdir = None 284 285def _gettempdir(): 286 """Private accessor for tempfile.tempdir.""" 287 global tempdir 288 if tempdir is None: 289 _once_lock.acquire() 290 try: 291 if tempdir is None: 292 tempdir = _get_default_tempdir() 293 finally: 294 _once_lock.release() 295 return tempdir 296 297def gettempdir(): 298 """Returns tempfile.tempdir as str.""" 299 return _os.fsdecode(_gettempdir()) 300 301def gettempdirb(): 302 """Returns tempfile.tempdir as bytes.""" 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. 321 322 If any of 'suffix', 'prefix' and 'dir' are not None, they must be the 323 same type. If they are bytes, the returned name will be bytes; str 324 otherwise. 325 326 The file is readable and writable only by the creating user ID. 327 If the operating system uses permission bits to indicate whether a 328 file is executable, the file is executable by no one. The file 329 descriptor is not inherited by children of this process. 330 331 Caller is responsible for deleting the file when done with it. 332 """ 333 334 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 335 336 if text: 337 flags = _text_openflags 338 else: 339 flags = _bin_openflags 340 341 return _mkstemp_inner(dir, prefix, suffix, flags, output_type) 342 343 344def mkdtemp(suffix=None, prefix=None, dir=None): 345 """User-callable function to create and return a unique temporary 346 directory. The return value is the pathname of the directory. 347 348 Arguments are as for mkstemp, except that the 'text' argument is 349 not accepted. 350 351 The directory is readable, writable, and searchable only by the 352 creating user. 353 354 Caller is responsible for deleting the directory when done with it. 355 """ 356 357 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 358 359 names = _get_candidate_names() 360 if output_type is bytes: 361 names = map(_os.fsencode, names) 362 363 for seq in range(TMP_MAX): 364 name = next(names) 365 file = _os.path.join(dir, prefix + name + suffix) 366 _sys.audit("tempfile.mkdtemp", file) 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, *, errors=None): 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 'errors' -- the errors argument to io.open (default None) 534 The file is created as mkstemp() would do it. 535 536 Returns an object with a file-like interface; the name of the file 537 is accessible as its 'name' attribute. The file will be automatically 538 deleted when it is closed unless the 'delete' argument is set to False. 539 540 On POSIX, NamedTemporaryFiles cannot be automatically deleted if 541 the creating process is terminated abruptly with a SIGKILL signal. 542 Windows can delete the file even in this case. 543 """ 544 545 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 546 547 flags = _bin_openflags 548 549 # Setting O_TEMPORARY in the flags causes the OS to delete 550 # the file when it is closed. This is only supported by Windows. 551 if _os.name == 'nt' and delete: 552 flags |= _os.O_TEMPORARY 553 554 if "b" not in mode: 555 encoding = _io.text_encoding(encoding) 556 557 name = None 558 def opener(*args): 559 nonlocal name 560 fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type) 561 return fd 562 try: 563 file = _io.open(dir, mode, buffering=buffering, 564 newline=newline, encoding=encoding, errors=errors, 565 opener=opener) 566 try: 567 raw = getattr(file, 'buffer', file) 568 raw = getattr(raw, 'raw', raw) 569 raw.name = name 570 return _TemporaryFileWrapper(file, name, delete) 571 except: 572 file.close() 573 raise 574 except: 575 if name is not None and not (_os.name == 'nt' and delete): 576 _os.unlink(name) 577 raise 578 579if _os.name != 'posix' or _sys.platform == 'cygwin': 580 # On non-POSIX and Cygwin systems, assume that we cannot unlink a file 581 # while it is open. 582 TemporaryFile = NamedTemporaryFile 583 584else: 585 # Is the O_TMPFILE flag available and does it work? 586 # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an 587 # IsADirectoryError exception 588 _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') 589 590 def TemporaryFile(mode='w+b', buffering=-1, encoding=None, 591 newline=None, suffix=None, prefix=None, 592 dir=None, *, errors=None): 593 """Create and return a temporary file. 594 Arguments: 595 'prefix', 'suffix', 'dir' -- as for mkstemp. 596 'mode' -- the mode argument to io.open (default "w+b"). 597 'buffering' -- the buffer size argument to io.open (default -1). 598 'encoding' -- the encoding argument to io.open (default None) 599 'newline' -- the newline argument to io.open (default None) 600 'errors' -- the errors argument to io.open (default None) 601 The file is created as mkstemp() would do it. 602 603 Returns an object with a file-like interface. The file has no 604 name, and will cease to exist when it is closed. 605 """ 606 global _O_TMPFILE_WORKS 607 608 if "b" not in mode: 609 encoding = _io.text_encoding(encoding) 610 611 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 612 613 flags = _bin_openflags 614 if _O_TMPFILE_WORKS: 615 fd = None 616 def opener(*args): 617 nonlocal fd 618 flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT 619 fd = _os.open(dir, flags2, 0o600) 620 return fd 621 try: 622 file = _io.open(dir, mode, buffering=buffering, 623 newline=newline, encoding=encoding, 624 errors=errors, opener=opener) 625 raw = getattr(file, 'buffer', file) 626 raw = getattr(raw, 'raw', raw) 627 raw.name = fd 628 return file 629 except IsADirectoryError: 630 # Linux kernel older than 3.11 ignores the O_TMPFILE flag: 631 # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory 632 # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a 633 # directory cannot be open to write. Set flag to False to not 634 # try again. 635 _O_TMPFILE_WORKS = False 636 except OSError: 637 # The filesystem of the directory does not support O_TMPFILE. 638 # For example, OSError(95, 'Operation not supported'). 639 # 640 # On Linux kernel older than 3.11, trying to open a regular 641 # file (or a symbolic link to a regular file) with O_TMPFILE 642 # fails with NotADirectoryError, because O_TMPFILE is read as 643 # O_DIRECTORY. 644 pass 645 # Fallback to _mkstemp_inner(). 646 647 fd = None 648 def opener(*args): 649 nonlocal fd 650 fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type) 651 try: 652 _os.unlink(name) 653 except BaseException as e: 654 _os.close(fd) 655 raise 656 return fd 657 file = _io.open(dir, mode, buffering=buffering, 658 newline=newline, encoding=encoding, errors=errors, 659 opener=opener) 660 raw = getattr(file, 'buffer', file) 661 raw = getattr(raw, 'raw', raw) 662 raw.name = fd 663 return file 664 665class SpooledTemporaryFile(_io.IOBase): 666 """Temporary file wrapper, specialized to switch from BytesIO 667 or StringIO to a real file when it exceeds a certain size or 668 when a fileno is needed. 669 """ 670 _rolled = False 671 672 def __init__(self, max_size=0, mode='w+b', buffering=-1, 673 encoding=None, newline=None, 674 suffix=None, prefix=None, dir=None, *, errors=None): 675 if 'b' in mode: 676 self._file = _io.BytesIO() 677 else: 678 encoding = _io.text_encoding(encoding) 679 self._file = _io.TextIOWrapper(_io.BytesIO(), 680 encoding=encoding, errors=errors, 681 newline=newline) 682 self._max_size = max_size 683 self._rolled = False 684 self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, 685 'suffix': suffix, 'prefix': prefix, 686 'encoding': encoding, 'newline': newline, 687 'dir': dir, 'errors': errors} 688 689 __class_getitem__ = classmethod(_types.GenericAlias) 690 691 def _check(self, file): 692 if self._rolled: return 693 max_size = self._max_size 694 if max_size and file.tell() > max_size: 695 self.rollover() 696 697 def rollover(self): 698 if self._rolled: return 699 file = self._file 700 newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) 701 del self._TemporaryFileArgs 702 703 pos = file.tell() 704 if hasattr(newfile, 'buffer'): 705 newfile.buffer.write(file.detach().getvalue()) 706 else: 707 newfile.write(file.getvalue()) 708 newfile.seek(pos, 0) 709 710 self._rolled = True 711 712 # The method caching trick from NamedTemporaryFile 713 # won't work here, because _file may change from a 714 # BytesIO/StringIO instance to a real file. So we list 715 # all the methods directly. 716 717 # Context management protocol 718 def __enter__(self): 719 if self._file.closed: 720 raise ValueError("Cannot enter context with closed file") 721 return self 722 723 def __exit__(self, exc, value, tb): 724 self._file.close() 725 726 # file protocol 727 def __iter__(self): 728 return self._file.__iter__() 729 730 def __del__(self): 731 if not self.closed: 732 _warnings.warn( 733 "Unclosed file {!r}".format(self), 734 ResourceWarning, 735 stacklevel=2, 736 source=self 737 ) 738 self.close() 739 740 def close(self): 741 self._file.close() 742 743 @property 744 def closed(self): 745 return self._file.closed 746 747 @property 748 def encoding(self): 749 return self._file.encoding 750 751 @property 752 def errors(self): 753 return self._file.errors 754 755 def fileno(self): 756 self.rollover() 757 return self._file.fileno() 758 759 def flush(self): 760 self._file.flush() 761 762 def isatty(self): 763 return self._file.isatty() 764 765 @property 766 def mode(self): 767 try: 768 return self._file.mode 769 except AttributeError: 770 return self._TemporaryFileArgs['mode'] 771 772 @property 773 def name(self): 774 try: 775 return self._file.name 776 except AttributeError: 777 return None 778 779 @property 780 def newlines(self): 781 return self._file.newlines 782 783 def readable(self): 784 return self._file.readable() 785 786 def read(self, *args): 787 return self._file.read(*args) 788 789 def read1(self, *args): 790 return self._file.read1(*args) 791 792 def readinto(self, b): 793 return self._file.readinto(b) 794 795 def readinto1(self, b): 796 return self._file.readinto1(b) 797 798 def readline(self, *args): 799 return self._file.readline(*args) 800 801 def readlines(self, *args): 802 return self._file.readlines(*args) 803 804 def seekable(self): 805 return self._file.seekable() 806 807 def seek(self, *args): 808 return self._file.seek(*args) 809 810 def tell(self): 811 return self._file.tell() 812 813 def truncate(self, size=None): 814 if size is None: 815 return self._file.truncate() 816 else: 817 if size > self._max_size: 818 self.rollover() 819 return self._file.truncate(size) 820 821 def writable(self): 822 return self._file.writable() 823 824 def write(self, s): 825 file = self._file 826 rv = file.write(s) 827 self._check(file) 828 return rv 829 830 def writelines(self, iterable): 831 file = self._file 832 rv = file.writelines(iterable) 833 self._check(file) 834 return rv 835 836 def detach(self): 837 return self._file.detach() 838 839 840class TemporaryDirectory: 841 """Create and return a temporary directory. This has the same 842 behavior as mkdtemp but can be used as a context manager. For 843 example: 844 845 with TemporaryDirectory() as tmpdir: 846 ... 847 848 Upon exiting the context, the directory and everything contained 849 in it are removed. 850 """ 851 852 def __init__(self, suffix=None, prefix=None, dir=None, 853 ignore_cleanup_errors=False): 854 self.name = mkdtemp(suffix, prefix, dir) 855 self._ignore_cleanup_errors = ignore_cleanup_errors 856 self._finalizer = _weakref.finalize( 857 self, self._cleanup, self.name, 858 warn_message="Implicitly cleaning up {!r}".format(self), 859 ignore_errors=self._ignore_cleanup_errors) 860 861 @classmethod 862 def _rmtree(cls, name, ignore_errors=False): 863 def onerror(func, path, exc_info): 864 if issubclass(exc_info[0], PermissionError): 865 def resetperms(path): 866 try: 867 _os.chflags(path, 0) 868 except AttributeError: 869 pass 870 _os.chmod(path, 0o700) 871 872 try: 873 if path != name: 874 resetperms(_os.path.dirname(path)) 875 resetperms(path) 876 877 try: 878 _os.unlink(path) 879 # PermissionError is raised on FreeBSD for directories 880 except (IsADirectoryError, PermissionError): 881 cls._rmtree(path, ignore_errors=ignore_errors) 882 except FileNotFoundError: 883 pass 884 elif issubclass(exc_info[0], FileNotFoundError): 885 pass 886 else: 887 if not ignore_errors: 888 raise 889 890 _shutil.rmtree(name, onerror=onerror) 891 892 @classmethod 893 def _cleanup(cls, name, warn_message, ignore_errors=False): 894 cls._rmtree(name, ignore_errors=ignore_errors) 895 _warnings.warn(warn_message, ResourceWarning) 896 897 def __repr__(self): 898 return "<{} {!r}>".format(self.__class__.__name__, self.name) 899 900 def __enter__(self): 901 return self.name 902 903 def __exit__(self, exc, value, tb): 904 self.cleanup() 905 906 def cleanup(self): 907 if self._finalizer.detach() or _os.path.exists(self.name): 908 self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors) 909 910 __class_getitem__ = classmethod(_types.GenericAlias) 911