tempfile.py 17.4 KB
Newer Older
1
"""Temporary files.
2

3 4 5 6 7
This module provides generic, low- and high-level interfaces for
creating temporary files and directories.  The interfaces listed
as "safe" just below can be used without fear of race conditions.
Those listed as "unsafe" cannot, and are provided for backward
compatibility only.
Guido van Rossum's avatar
Guido van Rossum committed
8

9
This module also provides some data items to the user:
Guido van Rossum's avatar
Guido van Rossum committed
10

11 12 13 14 15 16 17 18 19 20 21
  TMP_MAX  - maximum number of names that will be tried before
             giving up.
  template - the default prefix for all temporary names.
             You may change this to control the default prefix.
  tempdir  - If this is set to a string before the first use of
             any routine from this module, it will be considered as
             another candidate location to store temporary files.
"""

__all__ = [
    "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
22
    "SpooledTemporaryFile",
23 24 25 26 27 28 29 30 31 32 33 34 35
    "mkstemp", "mkdtemp",                  # low level safe interfaces
    "mktemp",                              # deprecated unsafe interface
    "TMP_MAX", "gettempprefix",            # constants
    "tempdir", "gettempdir"
   ]


# Imports.

import os as _os
import errno as _errno
from random import Random as _Random

36
try:
37
    from cStringIO import StringIO as _StringIO
Skip Montanaro's avatar
Skip Montanaro committed
38
except ImportError:
39
    from StringIO import StringIO as _StringIO
40

41 42
try:
    import fcntl as _fcntl
43
except ImportError:
44 45 46
    def _set_cloexec(fd):
        pass
else:
47
    def _set_cloexec(fd):
48 49 50 51
        try:
            flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0)
        except IOError:
            pass
52
        else:
53 54 55
            # flags read successfully, modify
            flags |= _fcntl.FD_CLOEXEC
            _fcntl.fcntl(fd, _fcntl.F_SETFD, flags)
56

57 58 59

try:
    import thread as _thread
60 61 62
except ImportError:
    import dummy_thread as _thread
_allocate_lock = _thread.allocate_lock
63 64

_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
Tim Peters's avatar
Tim Peters committed
65 66 67 68
if hasattr(_os, 'O_NOINHERIT'):
    _text_openflags |= _os.O_NOINHERIT
if hasattr(_os, 'O_NOFOLLOW'):
    _text_openflags |= _os.O_NOFOLLOW
69 70

_bin_openflags = _text_openflags
Tim Peters's avatar
Tim Peters committed
71 72
if hasattr(_os, 'O_BINARY'):
    _bin_openflags |= _os.O_BINARY
73 74 75 76 77 78

if hasattr(_os, 'TMP_MAX'):
    TMP_MAX = _os.TMP_MAX
else:
    TMP_MAX = 10000

79
template = "tmp"
80

81 82 83 84
# Internal routines.

_once_lock = _allocate_lock()

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
if hasattr(_os, "lstat"):
    _stat = _os.lstat
elif hasattr(_os, "stat"):
    _stat = _os.stat
else:
    # Fallback.  All we need is something that raises os.error if the
    # file doesn't exist.
    def _stat(fn):
        try:
            f = open(fn)
        except IOError:
            raise _os.error
        f.close()

def _exists(fn):
    try:
        _stat(fn)
    except _os.error:
        return False
    else:
        return True

107 108 109 110 111 112 113 114
class _RandomNameSequence:
    """An instance of _RandomNameSequence generates an endless
    sequence of unpredictable strings which can safely be incorporated
    into file names.  Each string is six characters long.  Multiple
    threads can safely use the same instance at the same time.

    _RandomNameSequence is an iterator."""

115 116
    characters = ("abcdefghijklmnopqrstuvwxyz" +
                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
117
                  "0123456789_")
118 119 120 121 122

    def __init__(self):
        self.mutex = _allocate_lock()
        self.rng = _Random()
        self.normcase = _os.path.normcase
123

124 125 126 127 128 129
    def __iter__(self):
        return self

    def next(self):
        m = self.mutex
        c = self.characters
130
        choose = self.rng.choice
131

132
        m.acquire()
133
        try:
134
            letters = [choose(c) for dummy in "123456"]
135 136 137
        finally:
            m.release()

138
        return self.normcase(''.join(letters))
139 140 141 142 143 144 145 146

def _candidate_tempdir_list():
    """Generate a list of candidate temporary directories which
    _get_default_tempdir will try."""

    dirlist = []

    # First, try the environment.
147
    for envname in 'TMPDIR', 'TEMP', 'TMP':
148 149 150 151
        dirname = _os.getenv(envname)
        if dirname: dirlist.append(dirname)

    # Failing that, try OS-specific locations.
152
    if _os.name == 'riscos':
153 154 155 156 157 158 159 160 161 162 163 164 165 166
        dirname = _os.getenv('Wimp$ScrapDir')
        if dirname: dirlist.append(dirname)
    elif _os.name == 'nt':
        dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
    else:
        dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])

    # As a last resort, the current directory.
    try:
        dirlist.append(_os.getcwd())
    except (AttributeError, _os.error):
        dirlist.append(_os.curdir)

    return dirlist
Tim Peters's avatar
Tim Peters committed
167

168 169
def _get_default_tempdir():
    """Calculate the default directory to use for temporary files.
170
    This routine should be called exactly once.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190

    We determine whether or not a candidate temp dir is usable by
    trying to create and write to a file in that directory.  If this
    is successful, the test file is deleted.  To prevent denial of
    service, the name of the test file must be randomized."""

    namer = _RandomNameSequence()
    dirlist = _candidate_tempdir_list()
    flags = _text_openflags

    for dir in dirlist:
        if dir != _os.curdir:
            dir = _os.path.normcase(_os.path.abspath(dir))
        # Try only a few names per directory.
        for seq in xrange(100):
            name = namer.next()
            filename = _os.path.join(dir, name)
            try:
                fd = _os.open(filename, flags, 0600)
                fp = _os.fdopen(fd, 'w')
Tim Peters's avatar
Tim Peters committed
191 192
                fp.write('blat')
                fp.close()
193 194 195 196 197 198 199 200 201
                _os.unlink(filename)
                del fp, fd
                return dir
            except (OSError, IOError), e:
                if e[0] != _errno.EEXIST:
                    break # no point trying more names in this directory
                pass
    raise IOError, (_errno.ENOENT,
                    ("No usable temporary directory found in %s" % dirlist))
202

203 204
_name_sequence = None

205 206
def _get_candidate_names():
    """Common setup sequence for all user-callable interfaces."""
207

208 209 210 211 212 213 214 215
    global _name_sequence
    if _name_sequence is None:
        _once_lock.acquire()
        try:
            if _name_sequence is None:
                _name_sequence = _RandomNameSequence()
        finally:
            _once_lock.release()
216 217 218 219 220 221 222 223 224 225 226 227 228 229
    return _name_sequence


def _mkstemp_inner(dir, pre, suf, flags):
    """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""

    names = _get_candidate_names()

    for seq in xrange(TMP_MAX):
        name = names.next()
        file = _os.path.join(dir, pre + name + suf)
        try:
            fd = _os.open(file, flags, 0600)
            _set_cloexec(fd)
230
            return (fd, _os.path.abspath(file))
231 232 233 234 235 236
        except OSError, e:
            if e.errno == _errno.EEXIST:
                continue # try again
            raise

    raise IOError, (_errno.EEXIST, "No usable temporary file name found")
Tim Peters's avatar
Tim Peters committed
237

238 239

# User visible interfaces.
240

241
def gettempprefix():
242 243 244
    """Accessor for tempdir.template."""
    return template

245 246
tempdir = None

247
def gettempdir():
Skip Montanaro's avatar
Skip Montanaro committed
248
    """Accessor for tempfile.tempdir."""
249 250 251 252 253 254 255 256
    global tempdir
    if tempdir is None:
        _once_lock.acquire()
        try:
            if tempdir is None:
                tempdir = _get_default_tempdir()
        finally:
            _once_lock.release()
257 258
    return tempdir

259
def mkstemp(suffix="", prefix=template, dir=None, text=False):
Skip Montanaro's avatar
Skip Montanaro committed
260
    """User-callable function to create and return a unique temporary
261 262 263 264 265 266 267 268 269 270 271 272
    file.  The return value is a pair (fd, name) where fd is the
    file descriptor returned by os.open, and name is the filename.

    If 'suffix' is specified, the file name will end with that suffix,
    otherwise there will be no suffix.

    If 'prefix' is specified, the file name will begin with that prefix,
    otherwise a default prefix is used.

    If 'dir' is specified, the file will be created in that directory,
    otherwise a default directory is used.

273 274 275
    If 'text' is specified and true, the file is opened in text
    mode.  Else (the default) the file is opened in binary mode.  On
    some operating systems, this makes no difference.
276 277 278 279 280

    The file is readable and writable only by the creating user ID.
    If the operating system uses permission bits to indicate whether a
    file is executable, the file is executable by no one. The file
    descriptor is not inherited by children of this process.
281

282
    Caller is responsible for deleting the file when done with it.
283 284
    """

285 286 287
    if dir is None:
        dir = gettempdir()

288
    if text:
289
        flags = _text_openflags
290 291
    else:
        flags = _bin_openflags
292

293
    return _mkstemp_inner(dir, prefix, suffix, flags)
Guido van Rossum's avatar
Guido van Rossum committed
294

295

296
def mkdtemp(suffix="", prefix=template, dir=None):
Skip Montanaro's avatar
Skip Montanaro committed
297
    """User-callable function to create and return a unique temporary
298 299
    directory.  The return value is the pathname of the directory.

300
    Arguments are as for mkstemp, except that the 'text' argument is
301 302 303 304 305 306 307 308
    not accepted.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.
    """

309 310 311
    if dir is None:
        dir = gettempdir()

312
    names = _get_candidate_names()
Tim Peters's avatar
Tim Peters committed
313

314 315 316 317 318
    for seq in xrange(TMP_MAX):
        name = names.next()
        file = _os.path.join(dir, prefix + name + suffix)
        try:
            _os.mkdir(file, 0700)
319
            return file
320 321 322 323
        except OSError, e:
            if e.errno == _errno.EEXIST:
                continue # try again
            raise
324

325
    raise IOError, (_errno.EEXIST, "No usable temporary directory name found")
326

327
def mktemp(suffix="", prefix=template, dir=None):
Skip Montanaro's avatar
Skip Montanaro committed
328
    """User-callable function to return a unique temporary file name.  The
329
    file is not created.
330

331
    Arguments are as for mkstemp, except that the 'text' argument is
332 333 334 335 336 337
    not accepted.

    This function is unsafe and should not be used.  The file name
    refers to a file that did not exist at some point, but by the time
    you get around to creating it, someone else may have beaten you to
    the punch.
338
    """
339

340 341 342
##    from warnings import warn as _warn
##    _warn("mktemp is a potential security risk to your program",
##          RuntimeWarning, stacklevel=2)
343

344 345 346
    if dir is None:
        dir = gettempdir()

347 348 349 350
    names = _get_candidate_names()
    for seq in xrange(TMP_MAX):
        name = names.next()
        file = _os.path.join(dir, prefix + name + suffix)
351
        if not _exists(file):
352 353 354
            return file

    raise IOError, (_errno.EEXIST, "No usable temporary filename found")
355

356

357 358 359 360 361 362 363
class _TemporaryFileWrapper:
    """Temporary file wrapper

    This class provides a wrapper around files opened for
    temporary use.  In particular, it seeks to automatically
    remove the file when it is no longer needed.
    """
364

365
    def __init__(self, file, name, delete=True):
366 367
        self.file = file
        self.name = name
368
        self.close_called = False
369
        self.delete = delete
370 371

    def __getattr__(self, name):
372 373 374
        # Attribute lookups are delegated to the underlying file
        # and cached for non-numeric results
        # (i.e. methods are cached, closed and friends are not)
375 376
        file = self.__dict__['file']
        a = getattr(file, name)
377
        if not issubclass(type(a), type(0)):
378
            setattr(self, name, a)
379
        return a
380

381 382 383 384 385 386
    # The underlying __enter__ method returns the wrong object
    # (self.file) so override it to return the wrapper
    def __enter__(self):
        self.file.__enter__()
        return self

387 388 389 390 391 392 393 394 395 396 397 398 399
    # NT provides delete-on-close as a primitive, so we don't need
    # the wrapper to do anything special.  We still use it so that
    # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
    if _os.name != 'nt':
        # Cache the unlinker so we don't get spurious errors at
        # shutdown when the module-level "os" is None'd out.  Note
        # that this must be referenced as self.unlink, because the
        # name TemporaryFileWrapper may also get None'd out before
        # __del__ is called.
        unlink = _os.unlink

        def close(self):
            if not self.close_called:
400
                self.close_called = True
401
                self.file.close()
402 403
                if self.delete:
                    self.unlink(self.name)
404 405 406 407

        def __del__(self):
            self.close()

408 409 410 411 412 413 414 415
        # Need to trap __exit__ as well to ensure the file gets
        # deleted when used in a with statement
        def __exit__(self, exc, value, tb):
            result = self.file.__exit__(exc, value, tb)
            self.close()
            return result


416
def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="",
417
                       prefix=template, dir=None, delete=True):
418 419 420 421 422
    """Create and return a temporary file.
    Arguments:
    'prefix', 'suffix', 'dir' -- as for mkstemp.
    'mode' -- the mode argument to os.fdopen (default "w+b").
    'bufsize' -- the buffer size argument to os.fdopen (default -1).
423
    'delete' -- whether the file is deleted on close (default True).
424 425
    The file is created as mkstemp() would do it.

426 427
    Returns an object with a file-like interface; the name of the file
    is accessible as file.name.  The file will be automatically deleted
428
    when it is closed unless the 'delete' argument is set to False.
429
    """
430

431 432 433
    if dir is None:
        dir = gettempdir()

434 435 436 437
    if 'b' in mode:
        flags = _bin_openflags
    else:
        flags = _text_openflags
438

439 440
    # Setting O_TEMPORARY in the flags causes the OS to delete
    # the file when it is closed.  This is only supported by Windows.
441
    if _os.name == 'nt' and delete:
442
        flags |= _os.O_TEMPORARY
443

444 445
    (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
    file = _os.fdopen(fd, mode, bufsize)
446
    return _TemporaryFileWrapper(file, name, delete)
447

448 449 450
if _os.name != 'posix' or _os.sys.platform == 'cygwin':
    # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
    # while it is open.
451
    TemporaryFile = NamedTemporaryFile
452 453

else:
454
    def TemporaryFile(mode='w+b', bufsize=-1, suffix="",
455
                      prefix=template, dir=None):
456 457
        """Create and return a temporary file.
        Arguments:
458
        'prefix', 'suffix', 'dir' -- as for mkstemp.
459 460 461 462
        'mode' -- the mode argument to os.fdopen (default "w+b").
        'bufsize' -- the buffer size argument to os.fdopen (default -1).
        The file is created as mkstemp() would do it.

463 464
        Returns an object with a file-like interface.  The file has no
        name, and will cease to exist when it is closed.
465 466
        """

467 468 469
        if dir is None:
            dir = gettempdir()

470 471 472 473
        if 'b' in mode:
            flags = _bin_openflags
        else:
            flags = _text_openflags
474 475 476 477 478 479 480 481

        (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
        try:
            _os.unlink(name)
            return _os.fdopen(fd, mode, bufsize)
        except:
            _os.close(fd)
            raise
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512

class SpooledTemporaryFile:
    """Temporary file wrapper, specialized to switch from
    StringIO to a real file when it exceeds a certain size or
    when a fileno is needed.
    """
    _rolled = False

    def __init__(self, max_size=0, mode='w+b', bufsize=-1,
                 suffix="", prefix=template, dir=None):
        self._file = _StringIO()
        self._max_size = max_size
        self._rolled = False
        self._TemporaryFileArgs = (mode, bufsize, suffix, prefix, dir)

    def _check(self, file):
        if self._rolled: return
        max_size = self._max_size
        if max_size and file.tell() > max_size:
            self.rollover()

    def rollover(self):
        if self._rolled: return
        file = self._file
        newfile = self._file = TemporaryFile(*self._TemporaryFileArgs)
        del self._TemporaryFileArgs

        newfile.write(file.getvalue())
        newfile.seek(file.tell(), 0)

        self._rolled = True
513

514 515 516 517 518 519 520 521 522 523 524 525 526 527
    # The method caching trick from NamedTemporaryFile
    # won't work here, because _file may change from a
    # _StringIO instance to a real file. So we list
    # all the methods directly.

    # Context management protocol
    def __enter__(self):
        if self._file.closed:
            raise ValueError("Cannot enter context with closed file")
        return self

    def __exit__(self, exc, value, tb):
        self._file.close()

528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
    # file protocol
    def __iter__(self):
        return self._file.__iter__()

    def close(self):
        self._file.close()

    @property
    def closed(self):
        return self._file.closed

    @property
    def encoding(self):
        return self._file.encoding

    def fileno(self):
        self.rollover()
        return self._file.fileno()

    def flush(self):
        self._file.flush()

    def isatty(self):
        return self._file.isatty()

    @property
    def mode(self):
        return self._file.mode

    @property
    def name(self):
        return self._file.name

    @property
    def newlines(self):
        return self._file.newlines

    def next(self):
        return self._file.next

    def read(self, *args):
        return self._file.read(*args)

    def readline(self, *args):
        return self._file.readline(*args)

    def readlines(self, *args):
        return self._file.readlines(*args)

    def seek(self, *args):
        self._file.seek(*args)

    @property
    def softspace(self):
        return self._file.softspace

    def tell(self):
        return self._file.tell()

    def truncate(self):
        self._file.truncate()

    def write(self, s):
        file = self._file
        rv = file.write(s)
        self._check(file)
        return rv

    def writelines(self, iterable):
        file = self._file
        rv = file.writelines(iterable)
        self._check(file)
        return rv

    def xreadlines(self, *args):
        return self._file.xreadlines(*args)