Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/tempfile.py: 10%

417 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

1"""Temporary files. 

2 

3This module provides generic, low- and high-level interfaces for 

4creating temporary files and directories. All of the interfaces 

5provided by this module can be used without fear of race conditions 

6except for 'mktemp'. 'mktemp' is subject to race conditions and 

7should not be used; it is provided for backward compatibility only. 

8 

9The default path names are returned as str. If you supply bytes as 

10input, all return values will be in bytes. Ex: 

11 

12 >>> tempfile.mkstemp() 

13 (4, '/tmp/tmptpu9nin8') 

14 >>> tempfile.mkdtemp(suffix=b'') 

15 b'/tmp/tmppbi8f0hy' 

16 

17This module also provides some data items to the user: 

18 

19 TMP_MAX - maximum number of names that will be tried before 

20 giving up. 

21 tempdir - If this is set to a string before the first use of 

22 any routine from this module, it will be considered as 

23 another candidate location to store temporary files. 

24""" 

25 

26__all__ = [ 

27 "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces 

28 "SpooledTemporaryFile", "TemporaryDirectory", 

29 "mkstemp", "mkdtemp", # low level safe interfaces 

30 "mktemp", # deprecated unsafe interface 

31 "TMP_MAX", "gettempprefix", # constants 

32 "tempdir", "gettempdir", 

33 "gettempprefixb", "gettempdirb", 

34 ] 

35 

36 

37# Imports. 

38 

39import functools as _functools 

40import warnings as _warnings 

41import io as _io 

42import os as _os 

43import shutil as _shutil 

44import errno as _errno 

45from random import Random as _Random 

46import sys as _sys 

47import weakref as _weakref 

48import _thread 

49_allocate_lock = _thread.allocate_lock 

50 

51_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL 

52if hasattr(_os, 'O_NOFOLLOW'): 

53 _text_openflags |= _os.O_NOFOLLOW 

54 

55_bin_openflags = _text_openflags 

56if hasattr(_os, 'O_BINARY'): 

57 _bin_openflags |= _os.O_BINARY 

58 

59if hasattr(_os, 'TMP_MAX'): 

60 TMP_MAX = _os.TMP_MAX 

61else: 

62 TMP_MAX = 10000 

63 

64# This variable _was_ unused for legacy reasons, see issue 10354. 

65# But as of 3.5 we actually use it at runtime so changing it would 

66# have a possibly desirable side effect... But we do not want to support 

67# that as an API. It is undocumented on purpose. Do not depend on this. 

68template = "tmp" 

69 

70# Internal routines. 

71 

72_once_lock = _allocate_lock() 

73 

74 

75def _exists(fn): 

76 try: 

77 _os.lstat(fn) 

78 except OSError: 

79 return False 

80 else: 

81 return True 

82 

83 

84def _infer_return_type(*args): 

85 """Look at the type of all args and divine their implied return type.""" 

86 return_type = None 

87 for arg in args: 

88 if arg is None: 

89 continue 

90 if isinstance(arg, bytes): 

91 if return_type is str: 

92 raise TypeError("Can't mix bytes and non-bytes in " 

93 "path components.") 

94 return_type = bytes 

95 else: 

96 if return_type is bytes: 

97 raise TypeError("Can't mix bytes and non-bytes in " 

98 "path components.") 

99 return_type = str 

100 if return_type is None: 

101 return str # tempfile APIs return a str by default. 

102 return return_type 

103 

104 

105def _sanitize_params(prefix, suffix, dir): 

106 """Common parameter processing for most APIs in this module.""" 

107 output_type = _infer_return_type(prefix, suffix, dir) 

108 if suffix is None: 

109 suffix = output_type() 

110 if prefix is None: 

111 if output_type is str: 

112 prefix = template 

113 else: 

114 prefix = _os.fsencode(template) 

115 if dir is None: 

116 if output_type is str: 

117 dir = gettempdir() 

118 else: 

119 dir = gettempdirb() 

120 return prefix, suffix, dir, output_type 

121 

122 

123class _RandomNameSequence: 

124 """An instance of _RandomNameSequence generates an endless 

125 sequence of unpredictable strings which can safely be incorporated 

126 into file names. Each string is eight characters long. Multiple 

127 threads can safely use the same instance at the same time. 

128 

129 _RandomNameSequence is an iterator.""" 

130 

131 characters = "abcdefghijklmnopqrstuvwxyz0123456789_" 

132 

133 @property 

134 def rng(self): 

135 cur_pid = _os.getpid() 

136 if cur_pid != getattr(self, '_rng_pid', None): 

137 self._rng = _Random() 

138 self._rng_pid = cur_pid 

139 return self._rng 

140 

141 def __iter__(self): 

142 return self 

143 

144 def __next__(self): 

145 c = self.characters 

146 choose = self.rng.choice 

147 letters = [choose(c) for dummy in range(8)] 

148 return ''.join(letters) 

149 

150def _candidate_tempdir_list(): 

151 """Generate a list of candidate temporary directories which 

152 _get_default_tempdir will try.""" 

153 

154 dirlist = [] 

155 

156 # First, try the environment. 

157 for envname in 'TMPDIR', 'TEMP', 'TMP': 

158 dirname = _os.getenv(envname) 

159 if dirname: dirlist.append(dirname) 

160 

161 # Failing that, try OS-specific locations. 

162 if _os.name == 'nt': 

163 dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'), 

164 _os.path.expandvars(r'%SYSTEMROOT%\Temp'), 

165 r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) 

166 else: 

167 dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) 

168 

169 # As a last resort, the current directory. 

170 try: 

171 dirlist.append(_os.getcwd()) 

172 except (AttributeError, OSError): 

173 dirlist.append(_os.curdir) 

174 

175 return dirlist 

176 

177def _get_default_tempdir(): 

178 """Calculate the default directory to use for temporary files. 

179 This routine should be called exactly once. 

180 

181 We determine whether or not a candidate temp dir is usable by 

182 trying to create and write to a file in that directory. If this 

183 is successful, the test file is deleted. To prevent denial of 

184 service, the name of the test file must be randomized.""" 

185 

186 namer = _RandomNameSequence() 

187 dirlist = _candidate_tempdir_list() 

188 

189 for dir in dirlist: 

190 if dir != _os.curdir: 

191 dir = _os.path.abspath(dir) 

192 # Try only a few names per directory. 

193 for seq in range(100): 

194 name = next(namer) 

195 filename = _os.path.join(dir, name) 

196 try: 

197 fd = _os.open(filename, _bin_openflags, 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 FileExistsError: 

208 pass 

209 except PermissionError: 

210 # This exception is thrown when a directory with the chosen name 

211 # already exists on windows. 

212 if (_os.name == 'nt' and _os.path.isdir(dir) and 

213 _os.access(dir, _os.W_OK)): 

214 continue 

215 break # no point trying more names in this directory 

216 except OSError: 

217 break # no point trying more names in this directory 

218 raise FileNotFoundError(_errno.ENOENT, 

219 "No usable temporary directory found in %s" % 

220 dirlist) 

221 

222_name_sequence = None 

223 

224def _get_candidate_names(): 

225 """Common setup sequence for all user-callable interfaces.""" 

226 

227 global _name_sequence 

228 if _name_sequence is None: 

229 _once_lock.acquire() 

230 try: 

231 if _name_sequence is None: 

232 _name_sequence = _RandomNameSequence() 

233 finally: 

234 _once_lock.release() 

235 return _name_sequence 

236 

237 

238def _mkstemp_inner(dir, pre, suf, flags, output_type): 

239 """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" 

240 

241 names = _get_candidate_names() 

242 if output_type is bytes: 

243 names = map(_os.fsencode, names) 

244 

245 for seq in range(TMP_MAX): 

246 name = next(names) 

247 file = _os.path.join(dir, pre + name + suf) 

248 _sys.audit("tempfile.mkstemp", file) 

249 try: 

250 fd = _os.open(file, flags, 0o600) 

251 except FileExistsError: 

252 continue # try again 

253 except PermissionError: 

254 # This exception is thrown when a directory with the chosen name 

255 # already exists on windows. 

256 if (_os.name == 'nt' and _os.path.isdir(dir) and 

257 _os.access(dir, _os.W_OK)): 

258 continue 

259 else: 

260 raise 

261 return (fd, _os.path.abspath(file)) 

262 

263 raise FileExistsError(_errno.EEXIST, 

264 "No usable temporary file name found") 

265 

266 

267# User visible interfaces. 

268 

269def gettempprefix(): 

270 """The default prefix for temporary directories.""" 

271 return template 

272 

273def gettempprefixb(): 

274 """The default prefix for temporary directories as bytes.""" 

275 return _os.fsencode(gettempprefix()) 

276 

277tempdir = None 

278 

279def gettempdir(): 

280 """Accessor for tempfile.tempdir.""" 

281 global tempdir 

282 if tempdir is None: 

283 _once_lock.acquire() 

284 try: 

285 if tempdir is None: 

286 tempdir = _get_default_tempdir() 

287 finally: 

288 _once_lock.release() 

289 return tempdir 

290 

291def gettempdirb(): 

292 """A bytes version of tempfile.gettempdir().""" 

293 return _os.fsencode(gettempdir()) 

294 

295def mkstemp(suffix=None, prefix=None, dir=None, text=False): 

296 """User-callable function to create and return a unique temporary 

297 file. The return value is a pair (fd, name) where fd is the 

298 file descriptor returned by os.open, and name is the filename. 

299 

300 If 'suffix' is not None, the file name will end with that suffix, 

301 otherwise there will be no suffix. 

302 

303 If 'prefix' is not None, the file name will begin with that prefix, 

304 otherwise a default prefix is used. 

305 

306 If 'dir' is not None, the file will be created in that directory, 

307 otherwise a default directory is used. 

308 

309 If 'text' is specified and true, the file is opened in text 

310 mode. Else (the default) the file is opened in binary mode. On 

311 some operating systems, this makes no difference. 

312 

313 If any of 'suffix', 'prefix' and 'dir' are not None, they must be the 

314 same type. If they are bytes, the returned name will be bytes; str 

315 otherwise. 

316 

317 The file is readable and writable only by the creating user ID. 

318 If the operating system uses permission bits to indicate whether a 

319 file is executable, the file is executable by no one. The file 

320 descriptor is not inherited by children of this process. 

321 

322 Caller is responsible for deleting the file when done with it. 

323 """ 

324 

325 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 

326 

327 if text: 

328 flags = _text_openflags 

329 else: 

330 flags = _bin_openflags 

331 

332 return _mkstemp_inner(dir, prefix, suffix, flags, output_type) 

333 

334 

335def mkdtemp(suffix=None, prefix=None, dir=None): 

336 """User-callable function to create and return a unique temporary 

337 directory. The return value is the pathname of the directory. 

338 

339 Arguments are as for mkstemp, except that the 'text' argument is 

340 not accepted. 

341 

342 The directory is readable, writable, and searchable only by the 

343 creating user. 

344 

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

346 """ 

347 

348 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 

349 

350 names = _get_candidate_names() 

351 if output_type is bytes: 

352 names = map(_os.fsencode, names) 

353 

354 for seq in range(TMP_MAX): 

355 name = next(names) 

356 file = _os.path.join(dir, prefix + name + suffix) 

357 _sys.audit("tempfile.mkdtemp", file) 

358 try: 

359 _os.mkdir(file, 0o700) 

360 except FileExistsError: 

361 continue # try again 

362 except PermissionError: 

363 # This exception is thrown when a directory with the chosen name 

364 # already exists on windows. 

365 if (_os.name == 'nt' and _os.path.isdir(dir) and 

366 _os.access(dir, _os.W_OK)): 

367 continue 

368 else: 

369 raise 

370 return file 

371 

372 raise FileExistsError(_errno.EEXIST, 

373 "No usable temporary directory name found") 

374 

375def mktemp(suffix="", prefix=template, dir=None): 

376 """User-callable function to return a unique temporary file name. The 

377 file is not created. 

378 

379 Arguments are similar to mkstemp, except that the 'text' argument is 

380 not accepted, and suffix=None, prefix=None and bytes file names are not 

381 supported. 

382 

383 THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may 

384 refer to a file that did not exist at some point, but by the time 

385 you get around to creating it, someone else may have beaten you to 

386 the punch. 

387 """ 

388 

389## from warnings import warn as _warn 

390## _warn("mktemp is a potential security risk to your program", 

391## RuntimeWarning, stacklevel=2) 

392 

393 if dir is None: 

394 dir = gettempdir() 

395 

396 names = _get_candidate_names() 

397 for seq in range(TMP_MAX): 

398 name = next(names) 

399 file = _os.path.join(dir, prefix + name + suffix) 

400 if not _exists(file): 

401 return file 

402 

403 raise FileExistsError(_errno.EEXIST, 

404 "No usable temporary filename found") 

405 

406 

407class _TemporaryFileCloser: 

408 """A separate object allowing proper closing of a temporary file's 

409 underlying file object, without adding a __del__ method to the 

410 temporary file.""" 

411 

412 file = None # Set here since __del__ checks it 

413 close_called = False 

414 

415 def __init__(self, file, name, delete=True): 

416 self.file = file 

417 self.name = name 

418 self.delete = delete 

419 

420 # NT provides delete-on-close as a primitive, so we don't need 

421 # the wrapper to do anything special. We still use it so that 

422 # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. 

423 if _os.name != 'nt': 

424 # Cache the unlinker so we don't get spurious errors at 

425 # shutdown when the module-level "os" is None'd out. Note 

426 # that this must be referenced as self.unlink, because the 

427 # name TemporaryFileWrapper may also get None'd out before 

428 # __del__ is called. 

429 

430 def close(self, unlink=_os.unlink): 

431 if not self.close_called and self.file is not None: 

432 self.close_called = True 

433 try: 

434 self.file.close() 

435 finally: 

436 if self.delete: 

437 unlink(self.name) 

438 

439 # Need to ensure the file is deleted on __del__ 

440 def __del__(self): 

441 self.close() 

442 

443 else: 

444 def close(self): 

445 if not self.close_called: 

446 self.close_called = True 

447 self.file.close() 

448 

449 

450class _TemporaryFileWrapper: 

451 """Temporary file wrapper 

452 

453 This class provides a wrapper around files opened for 

454 temporary use. In particular, it seeks to automatically 

455 remove the file when it is no longer needed. 

456 """ 

457 

458 def __init__(self, file, name, delete=True): 

459 self.file = file 

460 self.name = name 

461 self.delete = delete 

462 self._closer = _TemporaryFileCloser(file, name, delete) 

463 

464 def __getattr__(self, name): 

465 # Attribute lookups are delegated to the underlying file 

466 # and cached for non-numeric results 

467 # (i.e. methods are cached, closed and friends are not) 

468 file = self.__dict__['file'] 

469 a = getattr(file, name) 

470 if hasattr(a, '__call__'): 

471 func = a 

472 @_functools.wraps(func) 

473 def func_wrapper(*args, **kwargs): 

474 return func(*args, **kwargs) 

475 # Avoid closing the file as long as the wrapper is alive, 

476 # see issue #18879. 

477 func_wrapper._closer = self._closer 

478 a = func_wrapper 

479 if not isinstance(a, int): 

480 setattr(self, name, a) 

481 return a 

482 

483 # The underlying __enter__ method returns the wrong object 

484 # (self.file) so override it to return the wrapper 

485 def __enter__(self): 

486 self.file.__enter__() 

487 return self 

488 

489 # Need to trap __exit__ as well to ensure the file gets 

490 # deleted when used in a with statement 

491 def __exit__(self, exc, value, tb): 

492 result = self.file.__exit__(exc, value, tb) 

493 self.close() 

494 return result 

495 

496 def close(self): 

497 """ 

498 Close the temporary file, possibly deleting it. 

499 """ 

500 self._closer.close() 

501 

502 # iter() doesn't use __getattr__ to find the __iter__ method 

503 def __iter__(self): 

504 # Don't return iter(self.file), but yield from it to avoid closing 

505 # file as long as it's being used as iterator (see issue #23700). We 

506 # can't use 'yield from' here because iter(file) returns the file 

507 # object itself, which has a close method, and thus the file would get 

508 # closed when the generator is finalized, due to PEP380 semantics. 

509 for line in self.file: 

510 yield line 

511 

512 

513def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, 

514 newline=None, suffix=None, prefix=None, 

515 dir=None, delete=True, *, errors=None): 

516 """Create and return a temporary file. 

517 Arguments: 

518 'prefix', 'suffix', 'dir' -- as for mkstemp. 

519 'mode' -- the mode argument to io.open (default "w+b"). 

520 'buffering' -- the buffer size argument to io.open (default -1). 

521 'encoding' -- the encoding argument to io.open (default None) 

522 'newline' -- the newline argument to io.open (default None) 

523 'delete' -- whether the file is deleted on close (default True). 

524 'errors' -- the errors argument to io.open (default None) 

525 The file is created as mkstemp() would do it. 

526 

527 Returns an object with a file-like interface; the name of the file 

528 is accessible as its 'name' attribute. The file will be automatically 

529 deleted when it is closed unless the 'delete' argument is set to False. 

530 """ 

531 

532 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 

533 

534 flags = _bin_openflags 

535 

536 # Setting O_TEMPORARY in the flags causes the OS to delete 

537 # the file when it is closed. This is only supported by Windows. 

538 if _os.name == 'nt' and delete: 

539 flags |= _os.O_TEMPORARY 

540 

541 (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type) 

542 try: 

543 file = _io.open(fd, mode, buffering=buffering, 

544 newline=newline, encoding=encoding, errors=errors) 

545 

546 return _TemporaryFileWrapper(file, name, delete) 

547 except BaseException: 

548 _os.unlink(name) 

549 _os.close(fd) 

550 raise 

551 

552if _os.name != 'posix' or _sys.platform == 'cygwin': 

553 # On non-POSIX and Cygwin systems, assume that we cannot unlink a file 

554 # while it is open. 

555 TemporaryFile = NamedTemporaryFile 

556 

557else: 

558 # Is the O_TMPFILE flag available and does it work? 

559 # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an 

560 # IsADirectoryError exception 

561 _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') 

562 

563 def TemporaryFile(mode='w+b', buffering=-1, encoding=None, 

564 newline=None, suffix=None, prefix=None, 

565 dir=None, *, errors=None): 

566 """Create and return a temporary file. 

567 Arguments: 

568 'prefix', 'suffix', 'dir' -- as for mkstemp. 

569 'mode' -- the mode argument to io.open (default "w+b"). 

570 'buffering' -- the buffer size argument to io.open (default -1). 

571 'encoding' -- the encoding argument to io.open (default None) 

572 'newline' -- the newline argument to io.open (default None) 

573 'errors' -- the errors argument to io.open (default None) 

574 The file is created as mkstemp() would do it. 

575 

576 Returns an object with a file-like interface. The file has no 

577 name, and will cease to exist when it is closed. 

578 """ 

579 global _O_TMPFILE_WORKS 

580 

581 prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) 

582 

583 flags = _bin_openflags 

584 if _O_TMPFILE_WORKS: 

585 try: 

586 flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT 

587 fd = _os.open(dir, flags2, 0o600) 

588 except IsADirectoryError: 

589 # Linux kernel older than 3.11 ignores the O_TMPFILE flag: 

590 # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory 

591 # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a 

592 # directory cannot be open to write. Set flag to False to not 

593 # try again. 

594 _O_TMPFILE_WORKS = False 

595 except OSError: 

596 # The filesystem of the directory does not support O_TMPFILE. 

597 # For example, OSError(95, 'Operation not supported'). 

598 # 

599 # On Linux kernel older than 3.11, trying to open a regular 

600 # file (or a symbolic link to a regular file) with O_TMPFILE 

601 # fails with NotADirectoryError, because O_TMPFILE is read as 

602 # O_DIRECTORY. 

603 pass 

604 else: 

605 try: 

606 return _io.open(fd, mode, buffering=buffering, 

607 newline=newline, encoding=encoding, 

608 errors=errors) 

609 except: 

610 _os.close(fd) 

611 raise 

612 # Fallback to _mkstemp_inner(). 

613 

614 (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type) 

615 try: 

616 _os.unlink(name) 

617 return _io.open(fd, mode, buffering=buffering, 

618 newline=newline, encoding=encoding, errors=errors) 

619 except: 

620 _os.close(fd) 

621 raise 

622 

623class SpooledTemporaryFile: 

624 """Temporary file wrapper, specialized to switch from BytesIO 

625 or StringIO to a real file when it exceeds a certain size or 

626 when a fileno is needed. 

627 """ 

628 _rolled = False 

629 

630 def __init__(self, max_size=0, mode='w+b', buffering=-1, 

631 encoding=None, newline=None, 

632 suffix=None, prefix=None, dir=None, *, errors=None): 

633 if 'b' in mode: 

634 self._file = _io.BytesIO() 

635 else: 

636 self._file = _io.TextIOWrapper(_io.BytesIO(), 

637 encoding=encoding, errors=errors, 

638 newline=newline) 

639 self._max_size = max_size 

640 self._rolled = False 

641 self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, 

642 'suffix': suffix, 'prefix': prefix, 

643 'encoding': encoding, 'newline': newline, 

644 'dir': dir, 'errors': errors} 

645 

646 def _check(self, file): 

647 if self._rolled: return 

648 max_size = self._max_size 

649 if max_size and file.tell() > max_size: 

650 self.rollover() 

651 

652 def rollover(self): 

653 if self._rolled: return 

654 file = self._file 

655 newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) 

656 del self._TemporaryFileArgs 

657 

658 pos = file.tell() 

659 if hasattr(newfile, 'buffer'): 

660 newfile.buffer.write(file.detach().getvalue()) 

661 else: 

662 newfile.write(file.getvalue()) 

663 newfile.seek(pos, 0) 

664 

665 self._rolled = True 

666 

667 # The method caching trick from NamedTemporaryFile 

668 # won't work here, because _file may change from a 

669 # BytesIO/StringIO instance to a real file. So we list 

670 # all the methods directly. 

671 

672 # Context management protocol 

673 def __enter__(self): 

674 if self._file.closed: 

675 raise ValueError("Cannot enter context with closed file") 

676 return self 

677 

678 def __exit__(self, exc, value, tb): 

679 self._file.close() 

680 

681 # file protocol 

682 def __iter__(self): 

683 return self._file.__iter__() 

684 

685 def close(self): 

686 self._file.close() 

687 

688 @property 

689 def closed(self): 

690 return self._file.closed 

691 

692 @property 

693 def encoding(self): 

694 return self._file.encoding 

695 

696 @property 

697 def errors(self): 

698 return self._file.errors 

699 

700 def fileno(self): 

701 self.rollover() 

702 return self._file.fileno() 

703 

704 def flush(self): 

705 self._file.flush() 

706 

707 def isatty(self): 

708 return self._file.isatty() 

709 

710 @property 

711 def mode(self): 

712 try: 

713 return self._file.mode 

714 except AttributeError: 

715 return self._TemporaryFileArgs['mode'] 

716 

717 @property 

718 def name(self): 

719 try: 

720 return self._file.name 

721 except AttributeError: 

722 return None 

723 

724 @property 

725 def newlines(self): 

726 return self._file.newlines 

727 

728 def read(self, *args): 

729 return self._file.read(*args) 

730 

731 def readline(self, *args): 

732 return self._file.readline(*args) 

733 

734 def readlines(self, *args): 

735 return self._file.readlines(*args) 

736 

737 def seek(self, *args): 

738 return self._file.seek(*args) 

739 

740 @property 

741 def softspace(self): 

742 return self._file.softspace 

743 

744 def tell(self): 

745 return self._file.tell() 

746 

747 def truncate(self, size=None): 

748 if size is None: 

749 self._file.truncate() 

750 else: 

751 if size > self._max_size: 

752 self.rollover() 

753 self._file.truncate(size) 

754 

755 def write(self, s): 

756 file = self._file 

757 rv = file.write(s) 

758 self._check(file) 

759 return rv 

760 

761 def writelines(self, iterable): 

762 file = self._file 

763 rv = file.writelines(iterable) 

764 self._check(file) 

765 return rv 

766 

767 

768class TemporaryDirectory(object): 

769 """Create and return a temporary directory. This has the same 

770 behavior as mkdtemp but can be used as a context manager. For 

771 example: 

772 

773 with TemporaryDirectory() as tmpdir: 

774 ... 

775 

776 Upon exiting the context, the directory and everything contained 

777 in it are removed. 

778 """ 

779 

780 def __init__(self, suffix=None, prefix=None, dir=None): 

781 self.name = mkdtemp(suffix, prefix, dir) 

782 self._finalizer = _weakref.finalize( 

783 self, self._cleanup, self.name, 

784 warn_message="Implicitly cleaning up {!r}".format(self)) 

785 

786 @classmethod 

787 def _rmtree(cls, name): 

788 def onerror(func, path, exc_info): 

789 if issubclass(exc_info[0], PermissionError): 

790 def resetperms(path): 

791 try: 

792 _os.chflags(path, 0) 

793 except AttributeError: 

794 pass 

795 _os.chmod(path, 0o700) 

796 

797 try: 

798 if path != name: 

799 resetperms(_os.path.dirname(path)) 

800 resetperms(path) 

801 

802 try: 

803 _os.unlink(path) 

804 # PermissionError is raised on FreeBSD for directories 

805 except (IsADirectoryError, PermissionError): 

806 cls._rmtree(path) 

807 except FileNotFoundError: 

808 pass 

809 elif issubclass(exc_info[0], FileNotFoundError): 

810 pass 

811 else: 

812 raise 

813 

814 _shutil.rmtree(name, onerror=onerror) 

815 

816 @classmethod 

817 def _cleanup(cls, name, warn_message): 

818 cls._rmtree(name) 

819 _warnings.warn(warn_message, ResourceWarning) 

820 

821 def __repr__(self): 

822 return "<{} {!r}>".format(self.__class__.__name__, self.name) 

823 

824 def __enter__(self): 

825 return self.name 

826 

827 def __exit__(self, exc, value, tb): 

828 self.cleanup() 

829 

830 def cleanup(self): 

831 if self._finalizer.detach(): 

832 self._rmtree(self.name)