Home | History | Annotate | Download | only in python2.7
      1 """Temporary files.
      2 
      3 This module provides generic, low- and high-level interfaces for
      4 creating temporary files and directories.  The interfaces listed
      5 as "safe" just below can be used without fear of race conditions.
      6 Those listed as "unsafe" cannot, and are provided for backward
      7 compatibility only.
      8 
      9 This 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 
     32 import io as _io
     33 import os as _os
     34 import errno as _errno
     35 from random import Random as _Random
     36 
     37 try:
     38     from cStringIO import StringIO as _StringIO
     39 except ImportError:
     40     from StringIO import StringIO as _StringIO
     41 
     42 try:
     43     import fcntl as _fcntl
     44 except ImportError:
     45     def _set_cloexec(fd):
     46         pass
     47 else:
     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 
     59 try:
     60     import thread as _thread
     61 except 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
     66 if hasattr(_os, 'O_NOINHERIT'):
     67     _text_openflags |= _os.O_NOINHERIT
     68 if hasattr(_os, 'O_NOFOLLOW'):
     69     _text_openflags |= _os.O_NOFOLLOW
     70 
     71 _bin_openflags = _text_openflags
     72 if hasattr(_os, 'O_BINARY'):
     73     _bin_openflags |= _os.O_BINARY
     74 
     75 if hasattr(_os, 'TMP_MAX'):
     76     TMP_MAX = _os.TMP_MAX
     77 else:
     78     TMP_MAX = 10000
     79 
     80 template = "tmp"
     81 
     82 # Internal routines.
     83 
     84 _once_lock = _allocate_lock()
     85 
     86 if hasattr(_os, "lstat"):
     87     _stat = _os.lstat
     88 elif hasattr(_os, "stat"):
     89     _stat = _os.stat
     90 else:
     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 
    100 def _exists(fn):
    101     try:
    102         _stat(fn)
    103     except _os.error:
    104         return False
    105     else:
    106         return True
    107 
    108 class _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 
    148 def _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 
    176 def _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 
    216 def _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 
    230 def _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 
    252 def gettempprefix():
    253     """Accessor for tempdir.template."""
    254     return template
    255 
    256 tempdir = None
    257 
    258 def 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 
    270 def 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 
    307 def 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 
    338 def 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 
    368 class _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 
    430 def 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 
    462 if _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 
    467 else:
    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 
    497 class 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