Temporary file wrapper This class provides a wrapper around files opened for temporary use. In particular, it seeks to automatically remove the file when it is no longer needed.
| 474 | |
| 475 | |
| 476 | class _TemporaryFileWrapper: |
| 477 | """Temporary file wrapper |
| 478 | |
| 479 | This class provides a wrapper around files opened for |
| 480 | temporary use. In particular, it seeks to automatically |
| 481 | remove the file when it is no longer needed. |
| 482 | """ |
| 483 | |
| 484 | def __init__(self, file, name, delete=True): |
| 485 | self.file = file |
| 486 | self.name = name |
| 487 | self.delete = delete |
| 488 | self._closer = _TemporaryFileCloser(file, name, delete) |
| 489 | |
| 490 | def __getattr__(self, name): |
| 491 | # Attribute lookups are delegated to the underlying file |
| 492 | # and cached for non-numeric results |
| 493 | # (i.e. methods are cached, closed and friends are not) |
| 494 | file = self.__dict__['file'] |
| 495 | a = getattr(file, name) |
| 496 | if hasattr(a, '__call__'): |
| 497 | func = a |
| 498 | @_functools.wraps(func) |
| 499 | def func_wrapper(*args, **kwargs): |
| 500 | return func(*args, **kwargs) |
| 501 | # Avoid closing the file as long as the wrapper is alive, |
| 502 | # see issue #18879. |
| 503 | func_wrapper._closer = self._closer |
| 504 | a = func_wrapper |
| 505 | if not isinstance(a, int): |
| 506 | setattr(self, name, a) |
| 507 | return a |
| 508 | |
| 509 | # The underlying __enter__ method returns the wrong object |
| 510 | # (self.file) so override it to return the wrapper |
| 511 | def __enter__(self): |
| 512 | self.file.__enter__() |
| 513 | return self |
| 514 | |
| 515 | # Need to trap __exit__ as well to ensure the file gets |
| 516 | # deleted when used in a with statement |
| 517 | def __exit__(self, exc, value, tb): |
| 518 | result = self.file.__exit__(exc, value, tb) |
| 519 | self.close() |
| 520 | return result |
| 521 | |
| 522 | def close(self): |
| 523 | """ |
| 524 | Close the temporary file, possibly deleting it. |
| 525 | """ |
| 526 | self._closer.close() |
| 527 | |
| 528 | # iter() doesn't use __getattr__ to find the __iter__ method |
| 529 | def __iter__(self): |
| 530 | # Don't return iter(self.file), but yield from it to avoid closing |
| 531 | # file as long as it's being used as iterator (see issue #23700). We |
| 532 | # can't use 'yield from' here because iter(file) returns the file |
| 533 | # object itself, which has a close method, and thus the file would get |
no outgoing calls
no test coverage detected