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