Back to index

python3.2  3.2.2
tempfile.py
Go to the documentation of this file.
00001 """Temporary files.
00002 
00003 This module provides generic, low- and high-level interfaces for
00004 creating temporary files and directories.  The interfaces listed
00005 as "safe" just below can be used without fear of race conditions.
00006 Those listed as "unsafe" cannot, and are provided for backward
00007 compatibility only.
00008 
00009 This module also provides some data items to the user:
00010 
00011   TMP_MAX  - maximum number of names that will be tried before
00012              giving up.
00013   template - the default prefix for all temporary names.
00014              You may change this to control the default prefix.
00015   tempdir  - If this is set to a string before the first use of
00016              any routine from this module, it will be considered as
00017              another candidate location to store temporary files.
00018 """
00019 
00020 __all__ = [
00021     "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces
00022     "SpooledTemporaryFile", "TemporaryDirectory",
00023     "mkstemp", "mkdtemp",                  # low level safe interfaces
00024     "mktemp",                              # deprecated unsafe interface
00025     "TMP_MAX", "gettempprefix",            # constants
00026     "tempdir", "gettempdir"
00027    ]
00028 
00029 
00030 # Imports.
00031 
00032 import warnings as _warnings
00033 import sys as _sys
00034 import io as _io
00035 import os as _os
00036 import errno as _errno
00037 from random import Random as _Random
00038 
00039 try:
00040     import fcntl as _fcntl
00041 except ImportError:
00042     def _set_cloexec(fd):
00043         pass
00044 else:
00045     def _set_cloexec(fd):
00046         try:
00047             flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0)
00048         except IOError:
00049             pass
00050         else:
00051             # flags read successfully, modify
00052             flags |= _fcntl.FD_CLOEXEC
00053             _fcntl.fcntl(fd, _fcntl.F_SETFD, flags)
00054 
00055 
00056 try:
00057     import _thread
00058 except ImportError:
00059     import _dummy_thread as _thread
00060 _allocate_lock = _thread.allocate_lock
00061 
00062 _text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
00063 if hasattr(_os, 'O_NOINHERIT'):
00064     _text_openflags |= _os.O_NOINHERIT
00065 if hasattr(_os, 'O_NOFOLLOW'):
00066     _text_openflags |= _os.O_NOFOLLOW
00067 
00068 _bin_openflags = _text_openflags
00069 if hasattr(_os, 'O_BINARY'):
00070     _bin_openflags |= _os.O_BINARY
00071 
00072 if hasattr(_os, 'TMP_MAX'):
00073     TMP_MAX = _os.TMP_MAX
00074 else:
00075     TMP_MAX = 10000
00076 
00077 template = "tmp"
00078 
00079 # Internal routines.
00080 
00081 _once_lock = _allocate_lock()
00082 
00083 if hasattr(_os, "lstat"):
00084     _stat = _os.lstat
00085 elif hasattr(_os, "stat"):
00086     _stat = _os.stat
00087 else:
00088     # Fallback.  All we need is something that raises os.error if the
00089     # file doesn't exist.
00090     def _stat(fn):
00091         try:
00092             f = open(fn)
00093         except IOError:
00094             raise _os.error
00095         f.close()
00096 
00097 def _exists(fn):
00098     try:
00099         _stat(fn)
00100     except _os.error:
00101         return False
00102     else:
00103         return True
00104 
00105 class _RandomNameSequence:
00106     """An instance of _RandomNameSequence generates an endless
00107     sequence of unpredictable strings which can safely be incorporated
00108     into file names.  Each string is six characters long.  Multiple
00109     threads can safely use the same instance at the same time.
00110 
00111     _RandomNameSequence is an iterator."""
00112 
00113     characters = "abcdefghijklmnopqrstuvwxyz0123456789_"
00114 
00115     def __init__(self):
00116         self.rng = _Random()
00117 
00118     def __iter__(self):
00119         return self
00120 
00121     def __next__(self):
00122         c = self.characters
00123         choose = self.rng.choice
00124         letters = [choose(c) for dummy in "123456"]
00125         return ''.join(letters)
00126 
00127 def _candidate_tempdir_list():
00128     """Generate a list of candidate temporary directories which
00129     _get_default_tempdir will try."""
00130 
00131     dirlist = []
00132 
00133     # First, try the environment.
00134     for envname in 'TMPDIR', 'TEMP', 'TMP':
00135         dirname = _os.getenv(envname)
00136         if dirname: dirlist.append(dirname)
00137 
00138     # Failing that, try OS-specific locations.
00139     if _os.name == 'nt':
00140         dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ])
00141     else:
00142         dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ])
00143 
00144     # As a last resort, the current directory.
00145     try:
00146         dirlist.append(_os.getcwd())
00147     except (AttributeError, _os.error):
00148         dirlist.append(_os.curdir)
00149 
00150     return dirlist
00151 
00152 def _get_default_tempdir():
00153     """Calculate the default directory to use for temporary files.
00154     This routine should be called exactly once.
00155 
00156     We determine whether or not a candidate temp dir is usable by
00157     trying to create and write to a file in that directory.  If this
00158     is successful, the test file is deleted.  To prevent denial of
00159     service, the name of the test file must be randomized."""
00160 
00161     namer = _RandomNameSequence()
00162     dirlist = _candidate_tempdir_list()
00163 
00164     for dir in dirlist:
00165         if dir != _os.curdir:
00166             dir = _os.path.normcase(_os.path.abspath(dir))
00167         # Try only a few names per directory.
00168         for seq in range(100):
00169             name = next(namer)
00170             filename = _os.path.join(dir, name)
00171             try:
00172                 fd = _os.open(filename, _bin_openflags, 0o600)
00173                 fp = _io.open(fd, 'wb')
00174                 fp.write(b'blat')
00175                 fp.close()
00176                 _os.unlink(filename)
00177                 del fp, fd
00178                 return dir
00179             except (OSError, IOError) as e:
00180                 if e.args[0] != _errno.EEXIST:
00181                     break # no point trying more names in this directory
00182                 pass
00183     raise IOError(_errno.ENOENT,
00184                   "No usable temporary directory found in %s" % dirlist)
00185 
00186 _name_sequence = None
00187 
00188 def _get_candidate_names():
00189     """Common setup sequence for all user-callable interfaces."""
00190 
00191     global _name_sequence
00192     if _name_sequence is None:
00193         _once_lock.acquire()
00194         try:
00195             if _name_sequence is None:
00196                 _name_sequence = _RandomNameSequence()
00197         finally:
00198             _once_lock.release()
00199     return _name_sequence
00200 
00201 
00202 def _mkstemp_inner(dir, pre, suf, flags):
00203     """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile."""
00204 
00205     names = _get_candidate_names()
00206 
00207     for seq in range(TMP_MAX):
00208         name = next(names)
00209         file = _os.path.join(dir, pre + name + suf)
00210         try:
00211             fd = _os.open(file, flags, 0o600)
00212             _set_cloexec(fd)
00213             return (fd, _os.path.abspath(file))
00214         except OSError as e:
00215             if e.errno == _errno.EEXIST:
00216                 continue # try again
00217             raise
00218 
00219     raise IOError(_errno.EEXIST, "No usable temporary file name found")
00220 
00221 
00222 # User visible interfaces.
00223 
00224 def gettempprefix():
00225     """Accessor for tempdir.template."""
00226     return template
00227 
00228 tempdir = None
00229 
00230 def gettempdir():
00231     """Accessor for tempfile.tempdir."""
00232     global tempdir
00233     if tempdir is None:
00234         _once_lock.acquire()
00235         try:
00236             if tempdir is None:
00237                 tempdir = _get_default_tempdir()
00238         finally:
00239             _once_lock.release()
00240     return tempdir
00241 
00242 def mkstemp(suffix="", prefix=template, dir=None, text=False):
00243     """User-callable function to create and return a unique temporary
00244     file.  The return value is a pair (fd, name) where fd is the
00245     file descriptor returned by os.open, and name is the filename.
00246 
00247     If 'suffix' is specified, the file name will end with that suffix,
00248     otherwise there will be no suffix.
00249 
00250     If 'prefix' is specified, the file name will begin with that prefix,
00251     otherwise a default prefix is used.
00252 
00253     If 'dir' is specified, the file will be created in that directory,
00254     otherwise a default directory is used.
00255 
00256     If 'text' is specified and true, the file is opened in text
00257     mode.  Else (the default) the file is opened in binary mode.  On
00258     some operating systems, this makes no difference.
00259 
00260     The file is readable and writable only by the creating user ID.
00261     If the operating system uses permission bits to indicate whether a
00262     file is executable, the file is executable by no one. The file
00263     descriptor is not inherited by children of this process.
00264 
00265     Caller is responsible for deleting the file when done with it.
00266     """
00267 
00268     if dir is None:
00269         dir = gettempdir()
00270 
00271     if text:
00272         flags = _text_openflags
00273     else:
00274         flags = _bin_openflags
00275 
00276     return _mkstemp_inner(dir, prefix, suffix, flags)
00277 
00278 
00279 def mkdtemp(suffix="", prefix=template, dir=None):
00280     """User-callable function to create and return a unique temporary
00281     directory.  The return value is the pathname of the directory.
00282 
00283     Arguments are as for mkstemp, except that the 'text' argument is
00284     not accepted.
00285 
00286     The directory is readable, writable, and searchable only by the
00287     creating user.
00288 
00289     Caller is responsible for deleting the directory when done with it.
00290     """
00291 
00292     if dir is None:
00293         dir = gettempdir()
00294 
00295     names = _get_candidate_names()
00296 
00297     for seq in range(TMP_MAX):
00298         name = next(names)
00299         file = _os.path.join(dir, prefix + name + suffix)
00300         try:
00301             _os.mkdir(file, 0o700)
00302             return file
00303         except OSError as e:
00304             if e.errno == _errno.EEXIST:
00305                 continue # try again
00306             raise
00307 
00308     raise IOError(_errno.EEXIST, "No usable temporary directory name found")
00309 
00310 def mktemp(suffix="", prefix=template, dir=None):
00311     """User-callable function to return a unique temporary file name.  The
00312     file is not created.
00313 
00314     Arguments are as for mkstemp, except that the 'text' argument is
00315     not accepted.
00316 
00317     This function is unsafe and should not be used.  The file name
00318     refers to a file that did not exist at some point, but by the time
00319     you get around to creating it, someone else may have beaten you to
00320     the punch.
00321     """
00322 
00323 ##    from warnings import warn as _warn
00324 ##    _warn("mktemp is a potential security risk to your program",
00325 ##          RuntimeWarning, stacklevel=2)
00326 
00327     if dir is None:
00328         dir = gettempdir()
00329 
00330     names = _get_candidate_names()
00331     for seq in range(TMP_MAX):
00332         name = next(names)
00333         file = _os.path.join(dir, prefix + name + suffix)
00334         if not _exists(file):
00335             return file
00336 
00337     raise IOError(_errno.EEXIST, "No usable temporary filename found")
00338 
00339 
00340 class _TemporaryFileWrapper:
00341     """Temporary file wrapper
00342 
00343     This class provides a wrapper around files opened for
00344     temporary use.  In particular, it seeks to automatically
00345     remove the file when it is no longer needed.
00346     """
00347 
00348     def __init__(self, file, name, delete=True):
00349         self.file = file
00350         self.name = name
00351         self.close_called = False
00352         self.delete = delete
00353 
00354     def __getattr__(self, name):
00355         # Attribute lookups are delegated to the underlying file
00356         # and cached for non-numeric results
00357         # (i.e. methods are cached, closed and friends are not)
00358         file = self.__dict__['file']
00359         a = getattr(file, name)
00360         if not isinstance(a, int):
00361             setattr(self, name, a)
00362         return a
00363 
00364     # The underlying __enter__ method returns the wrong object
00365     # (self.file) so override it to return the wrapper
00366     def __enter__(self):
00367         self.file.__enter__()
00368         return self
00369 
00370     # iter() doesn't use __getattr__ to find the __iter__ method
00371     def __iter__(self):
00372         return iter(self.file)
00373 
00374     # NT provides delete-on-close as a primitive, so we don't need
00375     # the wrapper to do anything special.  We still use it so that
00376     # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
00377     if _os.name != 'nt':
00378         # Cache the unlinker so we don't get spurious errors at
00379         # shutdown when the module-level "os" is None'd out.  Note
00380         # that this must be referenced as self.unlink, because the
00381         # name TemporaryFileWrapper may also get None'd out before
00382         # __del__ is called.
00383         unlink = _os.unlink
00384 
00385         def close(self):
00386             if not self.close_called:
00387                 self.close_called = True
00388                 self.file.close()
00389                 if self.delete:
00390                     self.unlink(self.name)
00391 
00392         def __del__(self):
00393             self.close()
00394 
00395         # Need to trap __exit__ as well to ensure the file gets
00396         # deleted when used in a with statement
00397         def __exit__(self, exc, value, tb):
00398             result = self.file.__exit__(exc, value, tb)
00399             self.close()
00400             return result
00401     else:
00402         def __exit__(self, exc, value, tb):
00403             self.file.__exit__(exc, value, tb)
00404 
00405 
00406 def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
00407                        newline=None, suffix="", prefix=template,
00408                        dir=None, delete=True):
00409     """Create and return a temporary file.
00410     Arguments:
00411     'prefix', 'suffix', 'dir' -- as for mkstemp.
00412     'mode' -- the mode argument to io.open (default "w+b").
00413     'buffering' -- the buffer size argument to io.open (default -1).
00414     'encoding' -- the encoding argument to io.open (default None)
00415     'newline' -- the newline argument to io.open (default None)
00416     'delete' -- whether the file is deleted on close (default True).
00417     The file is created as mkstemp() would do it.
00418 
00419     Returns an object with a file-like interface; the name of the file
00420     is accessible as file.name.  The file will be automatically deleted
00421     when it is closed unless the 'delete' argument is set to False.
00422     """
00423 
00424     if dir is None:
00425         dir = gettempdir()
00426 
00427     flags = _bin_openflags
00428 
00429     # Setting O_TEMPORARY in the flags causes the OS to delete
00430     # the file when it is closed.  This is only supported by Windows.
00431     if _os.name == 'nt' and delete:
00432         flags |= _os.O_TEMPORARY
00433 
00434     (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
00435     file = _io.open(fd, mode, buffering=buffering,
00436                     newline=newline, encoding=encoding)
00437 
00438     return _TemporaryFileWrapper(file, name, delete)
00439 
00440 if _os.name != 'posix' or _os.sys.platform == 'cygwin':
00441     # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
00442     # while it is open.
00443     TemporaryFile = NamedTemporaryFile
00444 
00445 else:
00446     def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
00447                       newline=None, suffix="", prefix=template,
00448                       dir=None):
00449         """Create and return a temporary file.
00450         Arguments:
00451         'prefix', 'suffix', 'dir' -- as for mkstemp.
00452         'mode' -- the mode argument to io.open (default "w+b").
00453         'buffering' -- the buffer size argument to io.open (default -1).
00454         'encoding' -- the encoding argument to io.open (default None)
00455         'newline' -- the newline argument to io.open (default None)
00456         The file is created as mkstemp() would do it.
00457 
00458         Returns an object with a file-like interface.  The file has no
00459         name, and will cease to exist when it is closed.
00460         """
00461 
00462         if dir is None:
00463             dir = gettempdir()
00464 
00465         flags = _bin_openflags
00466 
00467         (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
00468         try:
00469             _os.unlink(name)
00470             return _io.open(fd, mode, buffering=buffering,
00471                             newline=newline, encoding=encoding)
00472         except:
00473             _os.close(fd)
00474             raise
00475 
00476 class SpooledTemporaryFile:
00477     """Temporary file wrapper, specialized to switch from
00478     StringIO to a real file when it exceeds a certain size or
00479     when a fileno is needed.
00480     """
00481     _rolled = False
00482 
00483     def __init__(self, max_size=0, mode='w+b', buffering=-1,
00484                  encoding=None, newline=None,
00485                  suffix="", prefix=template, dir=None):
00486         if 'b' in mode:
00487             self._file = _io.BytesIO()
00488         else:
00489             # Setting newline="\n" avoids newline translation;
00490             # this is important because otherwise on Windows we'd
00491             # hget double newline translation upon rollover().
00492             self._file = _io.StringIO(newline="\n")
00493         self._max_size = max_size
00494         self._rolled = False
00495         self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
00496                                    'suffix': suffix, 'prefix': prefix,
00497                                    'encoding': encoding, 'newline': newline,
00498                                    'dir': dir}
00499 
00500     def _check(self, file):
00501         if self._rolled: return
00502         max_size = self._max_size
00503         if max_size and file.tell() > max_size:
00504             self.rollover()
00505 
00506     def rollover(self):
00507         if self._rolled: return
00508         file = self._file
00509         newfile = self._file = TemporaryFile(**self._TemporaryFileArgs)
00510         del self._TemporaryFileArgs
00511 
00512         newfile.write(file.getvalue())
00513         newfile.seek(file.tell(), 0)
00514 
00515         self._rolled = True
00516 
00517     # The method caching trick from NamedTemporaryFile
00518     # won't work here, because _file may change from a
00519     # _StringIO instance to a real file. So we list
00520     # all the methods directly.
00521 
00522     # Context management protocol
00523     def __enter__(self):
00524         if self._file.closed:
00525             raise ValueError("Cannot enter context with closed file")
00526         return self
00527 
00528     def __exit__(self, exc, value, tb):
00529         self._file.close()
00530 
00531     # file protocol
00532     def __iter__(self):
00533         return self._file.__iter__()
00534 
00535     def close(self):
00536         self._file.close()
00537 
00538     @property
00539     def closed(self):
00540         return self._file.closed
00541 
00542     @property
00543     def encoding(self):
00544         return self._file.encoding
00545 
00546     def fileno(self):
00547         self.rollover()
00548         return self._file.fileno()
00549 
00550     def flush(self):
00551         self._file.flush()
00552 
00553     def isatty(self):
00554         return self._file.isatty()
00555 
00556     @property
00557     def mode(self):
00558         return self._file.mode
00559 
00560     @property
00561     def name(self):
00562         return self._file.name
00563 
00564     @property
00565     def newlines(self):
00566         return self._file.newlines
00567 
00568     def next(self):
00569         return self._file.next
00570 
00571     def read(self, *args):
00572         return self._file.read(*args)
00573 
00574     def readline(self, *args):
00575         return self._file.readline(*args)
00576 
00577     def readlines(self, *args):
00578         return self._file.readlines(*args)
00579 
00580     def seek(self, *args):
00581         self._file.seek(*args)
00582 
00583     @property
00584     def softspace(self):
00585         return self._file.softspace
00586 
00587     def tell(self):
00588         return self._file.tell()
00589 
00590     def truncate(self):
00591         self._file.truncate()
00592 
00593     def write(self, s):
00594         file = self._file
00595         rv = file.write(s)
00596         self._check(file)
00597         return rv
00598 
00599     def writelines(self, iterable):
00600         file = self._file
00601         rv = file.writelines(iterable)
00602         self._check(file)
00603         return rv
00604 
00605     def xreadlines(self, *args):
00606         return self._file.xreadlines(*args)
00607 
00608 
00609 class TemporaryDirectory(object):
00610     """Create and return a temporary directory.  This has the same
00611     behavior as mkdtemp but can be used as a context manager.  For
00612     example:
00613 
00614         with TemporaryDirectory() as tmpdir:
00615             ...
00616 
00617     Upon exiting the context, the directory and everthing contained
00618     in it are removed.
00619     """
00620 
00621     def __init__(self, suffix="", prefix=template, dir=None):
00622         self._closed = False
00623         self.name = None # Handle mkdtemp throwing an exception
00624         self.name = mkdtemp(suffix, prefix, dir)
00625 
00626     def __repr__(self):
00627         return "<{} {!r}>".format(self.__class__.__name__, self.name)
00628 
00629     def __enter__(self):
00630         return self.name
00631 
00632     def cleanup(self, _warn=False):
00633         if self.name and not self._closed:
00634             try:
00635                 self._rmtree(self.name)
00636             except (TypeError, AttributeError) as ex:
00637                 # Issue #10188: Emit a warning on stderr
00638                 # if the directory could not be cleaned
00639                 # up due to missing globals
00640                 if "None" not in str(ex):
00641                     raise
00642                 print("ERROR: {!r} while cleaning up {!r}".format(ex, self,),
00643                       file=_sys.stderr)
00644                 return
00645             self._closed = True
00646             if _warn:
00647                 self._warn("Implicitly cleaning up {!r}".format(self),
00648                            ResourceWarning)
00649 
00650     def __exit__(self, exc, value, tb):
00651         self.cleanup()
00652 
00653     def __del__(self):
00654         # Issue a ResourceWarning if implicit cleanup needed
00655         self.cleanup(_warn=True)
00656 
00657     # XXX (ncoghlan): The following code attempts to make
00658     # this class tolerant of the module nulling out process
00659     # that happens during CPython interpreter shutdown
00660     # Alas, it doesn't actually manage it. See issue #10188
00661     _listdir = staticmethod(_os.listdir)
00662     _path_join = staticmethod(_os.path.join)
00663     _isdir = staticmethod(_os.path.isdir)
00664     _islink = staticmethod(_os.path.islink)
00665     _remove = staticmethod(_os.remove)
00666     _rmdir = staticmethod(_os.rmdir)
00667     _os_error = _os.error
00668     _warn = _warnings.warn
00669 
00670     def _rmtree(self, path):
00671         # Essentially a stripped down version of shutil.rmtree.  We can't
00672         # use globals because they may be None'ed out at shutdown.
00673         for name in self._listdir(path):
00674             fullname = self._path_join(path, name)
00675             try:
00676                 isdir = self._isdir(fullname) and not self._islink(fullname)
00677             except self._os_error:
00678                 isdir = False
00679             if isdir:
00680                 self._rmtree(fullname)
00681             else:
00682                 try:
00683                     self._remove(fullname)
00684                 except self._os_error:
00685                     pass
00686         try:
00687             self._rmdir(path)
00688         except self._os_error:
00689             pass