1"""Temporary files. 2 3This module provides generic, low- and high-level interfaces for 4creating temporary files and directories. The interfaces listed 5as "safe" just below can be used without fear of race conditions. 6Those listed as "unsafe" cannot, and are provided for backward 7compatibility only. 8 9This module also provides some data items to the user: 10 11 TMP_MAX - maximum number of names that will be tried before 12 giving up. 13 template - the default prefix for all temporary names. 14 You may change this to control the default prefix. 15 tempdir - If this is set to a string before the first use of 16 any routine from this module, it will be considered as 17 another candidate location to store temporary files. 18""" 19 20__all__ = [ 21 "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces 22 "SpooledTemporaryFile", 23 "mkstemp", "mkdtemp", # low level safe interfaces 24 "mktemp", # deprecated unsafe interface 25 "TMP_MAX", "gettempprefix", # constants 26 "tempdir", "gettempdir" 27 ] 28 29 30# Imports. 31 32import io as _io 33import os as _os 34import errno as _errno 35from random import Random as _Random 36 37try: 38 from cStringIO import StringIO as _StringIO 39except ImportError: 40 from StringIO import StringIO as _StringIO 41 42try: 43 import fcntl as _fcntl 44except ImportError: 45 def _set_cloexec(fd): 46 pass 47else: 48 def _set_cloexec(fd): 49 try: 50 flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0) 51 except IOError: 52 pass 53 else: 54 # flags read successfully, modify 55 flags |= _fcntl.FD_CLOEXEC 56 _fcntl.fcntl(fd, _fcntl.F_SETFD, flags) 57 58 59try: 60 import thread as _thread 61except ImportError: 62 import dummy_thread as _thread 63_allocate_lock = _thread.allocate_lock 64 65_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL 66if hasattr(_os, 'O_NOINHERIT'): 67 _text_openflags |= _os.O_NOINHERIT 68if hasattr(_os, 'O_NOFOLLOW'): 69 _text_openflags |= _os.O_NOFOLLOW 70 71_bin_openflags = _text_openflags 72if hasattr(_os, 'O_BINARY'): 73 _bin_openflags |= _os.O_BINARY 74 75if hasattr(_os, 'TMP_MAX'): 76 TMP_MAX = _os.TMP_MAX 77else: 78 TMP_MAX = 10000 79 80template = "tmp" 81 82# Internal routines. 83 84_once_lock = _allocate_lock() 85 86if hasattr(_os, "lstat"): 87 _stat = _os.lstat 88elif hasattr(_os, "stat"): 89 _stat = _os.stat 90else: 91 # Fallback. All we need is something that raises os.error if the 92 # file doesn't exist. 93 def _stat(fn): 94 try: 95 f = open(fn) 96 except IOError: 97 raise _os.error 98 f.close() 99 100def _exists(fn): 101 try: 102 _stat(fn) 103 except _os.error: 104 return False 105 else: 106 return True 107 108class _RandomNameSequence: 109 """An instance of _RandomNameSequence generates an endless 110 sequence of unpredictable strings which can safely be incorporated 111 into file names. Each string is six characters long. Multiple 112 threads can safely use the same instance at the same time. 113 114 _RandomNameSequence is an iterator.""" 115 116 characters = ("abcdefghijklmnopqrstuvwxyz" + 117 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 118 "0123456789_") 119 120 def __init__(self): 121 self.mutex = _allocate_lock() 122 self.normcase = _os.path.normcase 123 124 @property 125 def rng(self): 126 cur_pid = _os.getpid() 127 if cur_pid != getattr(self, '_rng_pid', None): 128 self._rng = _Random() 129 self._rng_pid = cur_pid 130 return self._rng 131 132 def __iter__(self): 133 return self 134 135 def next(self): 136 m = self.mutex 137 c = self.characters 138 choose = self.rng.choice 139 140 m.acquire() 141 try: 142 letters = [choose(c) for dummy in "123456"] 143 finally: 144 m.release() 145 146 return self.normcase(''.join(letters)) 147 148def _candidate_tempdir_list(): 149 """Generate a list of candidate temporary directories which 150 _get_default_tempdir will try.""" 151 152 dirlist = [] 153 154 # First, try the environment. 155 for envname in 'TMPDIR', 'TEMP', 'TMP': 156 dirname = _os.getenv(envname) 157 if dirname: dirlist.append(dirname) 158 159 # Failing that, try OS-specific locations. 160 if _os.name == 'riscos': 161 dirname = _os.getenv('Wimp$ScrapDir') 162 if dirname: dirlist.append(dirname) 163 elif _os.name == 'nt': 164 dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) 165 else: 166 dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) 167 168 # As a last resort, the current directory. 169 try: 170 dirlist.append(_os.getcwd()) 171 except (AttributeError, _os.error): 172 dirlist.append(_os.curdir) 173 174 return dirlist 175 176def _get_default_tempdir(): 177 """Calculate the default directory to use for temporary files. 178 This routine should be called exactly once. 179 180 We determine whether or not a candidate temp dir is usable by 181 trying to create and write to a file in that directory. If this 182 is successful, the test file is deleted. To prevent denial of 183 service, the name of the test file must be randomized.""" 184 185 namer = _RandomNameSequence() 186 dirlist = _candidate_tempdir_list() 187 flags = _text_openflags 188 189 for dir in dirlist: 190 if dir != _os.curdir: 191 dir = _os.path.normcase(_os.path.abspath(dir)) 192 # Try only a few names per directory. 193 for seq in xrange(100): 194 name = namer.next() 195 filename = _os.path.join(dir, name) 196 try: 197 fd = _os.open(filename, flags, 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 (OSError, IOError) as e: 208 if e.args[0] != _errno.EEXIST: 209 break # no point trying more names in this directory 210 pass 211 raise IOError, (_errno.ENOENT, 212 ("No usable temporary directory found in %s" % dirlist)) 213 214_name_sequence = None 215 216def _get_candidate_names(): 217 """Common setup sequence for all user-callable interfaces.""" 218 219 global _name_sequence 220 if _name_sequence is None: 221 _once_lock.acquire() 222 try: 223 if _name_sequence is None: 224 _name_sequence = _RandomNameSequence() 225 finally: 226 _once_lock.release() 227 return _name_sequence 228 229 230def _mkstemp_inner(dir, pre, suf, flags): 231 """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" 232 233 names = _get_candidate_names() 234 235 for seq in xrange(TMP_MAX): 236 name = names.next() 237 file = _os.path.join(dir, pre + name + suf) 238 try: 239 fd = _os.open(file, flags, 0600) 240 _set_cloexec(fd) 241 return (fd, _os.path.abspath(file)) 242 except OSError, e: 243 if e.errno == _errno.EEXIST: 244 continue # try again 245 raise 246 247 raise IOError, (_errno.EEXIST, "No usable temporary file name found") 248 249 250# User visible interfaces. 251 252def gettempprefix(): 253 """Accessor for tempdir.template.""" 254 return template 255 256tempdir = None 257 258def gettempdir(): 259 """Accessor for tempfile.tempdir.""" 260 global tempdir 261 if tempdir is None: 262 _once_lock.acquire() 263 try: 264 if tempdir is None: 265 tempdir = _get_default_tempdir() 266 finally: 267 _once_lock.release() 268 return tempdir 269 270def mkstemp(suffix="", prefix=template, dir=None, text=False): 271 """User-callable function to create and return a unique temporary 272 file. The return value is a pair (fd, name) where fd is the 273 file descriptor returned by os.open, and name is the filename. 274 275 If 'suffix' is specified, the file name will end with that suffix, 276 otherwise there will be no suffix. 277 278 If 'prefix' is specified, the file name will begin with that prefix, 279 otherwise a default prefix is used. 280 281 If 'dir' is specified, the file will be created in that directory, 282 otherwise a default directory is used. 283 284 If 'text' is specified and true, the file is opened in text 285 mode. Else (the default) the file is opened in binary mode. On 286 some operating systems, this makes no difference. 287 288 The file is readable and writable only by the creating user ID. 289 If the operating system uses permission bits to indicate whether a 290 file is executable, the file is executable by no one. The file 291 descriptor is not inherited by children of this process. 292 293 Caller is responsible for deleting the file when done with it. 294 """ 295 296 if dir is None: 297 dir = gettempdir() 298 299 if text: 300 flags = _text_openflags 301 else: 302 flags = _bin_openflags 303 304 return _mkstemp_inner(dir, prefix, suffix, flags) 305 306 307def mkdtemp(suffix="", prefix=template, dir=None): 308 """User-callable function to create and return a unique temporary 309 directory. The return value is the pathname of the directory. 310 311 Arguments are as for mkstemp, except that the 'text' argument is 312 not accepted. 313 314 The directory is readable, writable, and searchable only by the 315 creating user. 316 317 Caller is responsible for deleting the directory when done with it. 318 """ 319 320 if dir is None: 321 dir = gettempdir() 322 323 names = _get_candidate_names() 324 325 for seq in xrange(TMP_MAX): 326 name = names.next() 327 file = _os.path.join(dir, prefix + name + suffix) 328 try: 329 _os.mkdir(file, 0700) 330 return file 331 except OSError, e: 332 if e.errno == _errno.EEXIST: 333 continue # try again 334 raise 335 336 raise IOError, (_errno.EEXIST, "No usable temporary directory name found") 337 338def mktemp(suffix="", prefix=template, dir=None): 339 """User-callable function to return a unique temporary file name. The 340 file is not created. 341 342 Arguments are as for mkstemp, except that the 'text' argument is 343 not accepted. 344 345 This function is unsafe and should not be used. The file name 346 refers to a file that did not exist at some point, but by the time 347 you get around to creating it, someone else may have beaten you to 348 the punch. 349 """ 350 351## from warnings import warn as _warn 352## _warn("mktemp is a potential security risk to your program", 353## RuntimeWarning, stacklevel=2) 354 355 if dir is None: 356 dir = gettempdir() 357 358 names = _get_candidate_names() 359 for seq in xrange(TMP_MAX): 360 name = names.next() 361 file = _os.path.join(dir, prefix + name + suffix) 362 if not _exists(file): 363 return file 364 365 raise IOError, (_errno.EEXIST, "No usable temporary filename found") 366 367 368class _TemporaryFileWrapper: 369 """Temporary file wrapper 370 371 This class provides a wrapper around files opened for 372 temporary use. In particular, it seeks to automatically 373 remove the file when it is no longer needed. 374 """ 375 376 def __init__(self, file, name, delete=True): 377 self.file = file 378 self.name = name 379 self.close_called = False 380 self.delete = delete 381 382 def __getattr__(self, name): 383 # Attribute lookups are delegated to the underlying file 384 # and cached for non-numeric results 385 # (i.e. methods are cached, closed and friends are not) 386 file = self.__dict__['file'] 387 a = getattr(file, name) 388 if not issubclass(type(a), type(0)): 389 setattr(self, name, a) 390 return a 391 392 # The underlying __enter__ method returns the wrong object 393 # (self.file) so override it to return the wrapper 394 def __enter__(self): 395 self.file.__enter__() 396 return self 397 398 # NT provides delete-on-close as a primitive, so we don't need 399 # the wrapper to do anything special. We still use it so that 400 # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. 401 if _os.name != 'nt': 402 # Cache the unlinker so we don't get spurious errors at 403 # shutdown when the module-level "os" is None'd out. Note 404 # that this must be referenced as self.unlink, because the 405 # name TemporaryFileWrapper may also get None'd out before 406 # __del__ is called. 407 unlink = _os.unlink 408 409 def close(self): 410 if not self.close_called: 411 self.close_called = True 412 self.file.close() 413 if self.delete: 414 self.unlink(self.name) 415 416 def __del__(self): 417 self.close() 418 419 # Need to trap __exit__ as well to ensure the file gets 420 # deleted when used in a with statement 421 def __exit__(self, exc, value, tb): 422 result = self.file.__exit__(exc, value, tb) 423 self.close() 424 return result 425 else: 426 def __exit__(self, exc, value, tb): 427 self.file.__exit__(exc, value, tb) 428 429 430def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="", 431 prefix=template, dir=None, delete=True): 432 """Create and return a temporary file. 433 Arguments: 434 'prefix', 'suffix', 'dir' -- as for mkstemp. 435 'mode' -- the mode argument to os.fdopen (default "w+b"). 436 'bufsize' -- the buffer size argument to os.fdopen (default -1). 437 'delete' -- whether the file is deleted on close (default True). 438 The file is created as mkstemp() would do it. 439 440 Returns an object with a file-like interface; the name of the file 441 is accessible as file.name. The file will be automatically deleted 442 when it is closed unless the 'delete' argument is set to False. 443 """ 444 445 if dir is None: 446 dir = gettempdir() 447 448 if 'b' in mode: 449 flags = _bin_openflags 450 else: 451 flags = _text_openflags 452 453 # Setting O_TEMPORARY in the flags causes the OS to delete 454 # the file when it is closed. This is only supported by Windows. 455 if _os.name == 'nt' and delete: 456 flags |= _os.O_TEMPORARY 457 458 (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) 459 file = _os.fdopen(fd, mode, bufsize) 460 return _TemporaryFileWrapper(file, name, delete) 461 462if _os.name != 'posix' or _os.sys.platform == 'cygwin': 463 # On non-POSIX and Cygwin systems, assume that we cannot unlink a file 464 # while it is open. 465 TemporaryFile = NamedTemporaryFile 466 467else: 468 def TemporaryFile(mode='w+b', bufsize=-1, suffix="", 469 prefix=template, dir=None): 470 """Create and return a temporary file. 471 Arguments: 472 'prefix', 'suffix', 'dir' -- as for mkstemp. 473 'mode' -- the mode argument to os.fdopen (default "w+b"). 474 'bufsize' -- the buffer size argument to os.fdopen (default -1). 475 The file is created as mkstemp() would do it. 476 477 Returns an object with a file-like interface. The file has no 478 name, and will cease to exist when it is closed. 479 """ 480 481 if dir is None: 482 dir = gettempdir() 483 484 if 'b' in mode: 485 flags = _bin_openflags 486 else: 487 flags = _text_openflags 488 489 (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) 490 try: 491 _os.unlink(name) 492 return _os.fdopen(fd, mode, bufsize) 493 except: 494 _os.close(fd) 495 raise 496 497class SpooledTemporaryFile: 498 """Temporary file wrapper, specialized to switch from 499 StringIO to a real file when it exceeds a certain size or 500 when a fileno is needed. 501 """ 502 _rolled = False 503 504 def __init__(self, max_size=0, mode='w+b', bufsize=-1, 505 suffix="", prefix=template, dir=None): 506 self._file = _StringIO() 507 self._max_size = max_size 508 self._rolled = False 509 self._TemporaryFileArgs = (mode, bufsize, suffix, prefix, dir) 510 511 def _check(self, file): 512 if self._rolled: return 513 max_size = self._max_size 514 if max_size and file.tell() > max_size: 515 self.rollover() 516 517 def rollover(self): 518 if self._rolled: return 519 file = self._file 520 newfile = self._file = TemporaryFile(*self._TemporaryFileArgs) 521 del self._TemporaryFileArgs 522 523 newfile.write(file.getvalue()) 524 newfile.seek(file.tell(), 0) 525 526 self._rolled = True 527 528 # The method caching trick from NamedTemporaryFile 529 # won't work here, because _file may change from a 530 # _StringIO instance to a real file. So we list 531 # all the methods directly. 532 533 # Context management protocol 534 def __enter__(self): 535 if self._file.closed: 536 raise ValueError("Cannot enter context with closed file") 537 return self 538 539 def __exit__(self, exc, value, tb): 540 self._file.close() 541 542 # file protocol 543 def __iter__(self): 544 return self._file.__iter__() 545 546 def close(self): 547 self._file.close() 548 549 @property 550 def closed(self): 551 return self._file.closed 552 553 def fileno(self): 554 self.rollover() 555 return self._file.fileno() 556 557 def flush(self): 558 self._file.flush() 559 560 def isatty(self): 561 return self._file.isatty() 562 563 @property 564 def mode(self): 565 try: 566 return self._file.mode 567 except AttributeError: 568 return self._TemporaryFileArgs[0] 569 570 @property 571 def name(self): 572 try: 573 return self._file.name 574 except AttributeError: 575 return None 576 577 def next(self): 578 return self._file.next 579 580 def read(self, *args): 581 return self._file.read(*args) 582 583 def readline(self, *args): 584 return self._file.readline(*args) 585 586 def readlines(self, *args): 587 return self._file.readlines(*args) 588 589 def seek(self, *args): 590 self._file.seek(*args) 591 592 @property 593 def softspace(self): 594 return self._file.softspace 595 596 def tell(self): 597 return self._file.tell() 598 599 def truncate(self): 600 self._file.truncate() 601 602 def write(self, s): 603 file = self._file 604 rv = file.write(s) 605 self._check(file) 606 return rv 607 608 def writelines(self, iterable): 609 file = self._file 610 rv = file.writelines(iterable) 611 self._check(file) 612 return rv 613 614 def xreadlines(self, *args): 615 try: 616 return self._file.xreadlines(*args) 617 except AttributeError: 618 return iter(self._file.readlines(*args)) 619