Write any pending changes to disk.
(self)
| 650 | self._locked = False |
| 651 | |
| 652 | def flush(self): |
| 653 | """Write any pending changes to disk.""" |
| 654 | if not self._pending: |
| 655 | if self._pending_sync: |
| 656 | # Messages have only been added, so syncing the file |
| 657 | # is enough. |
| 658 | _sync_flush(self._file) |
| 659 | self._pending_sync = False |
| 660 | return |
| 661 | |
| 662 | # In order to be writing anything out at all, self._toc must |
| 663 | # already have been generated (and presumably has been modified |
| 664 | # by adding or deleting an item). |
| 665 | assert self._toc is not None |
| 666 | |
| 667 | # Check length of self._file; if it's changed, some other process |
| 668 | # has modified the mailbox since we scanned it. |
| 669 | self._file.seek(0, 2) |
| 670 | cur_len = self._file.tell() |
| 671 | if cur_len != self._file_length: |
| 672 | raise ExternalClashError('Size of mailbox file changed ' |
| 673 | '(expected %i, found %i)' % |
| 674 | (self._file_length, cur_len)) |
| 675 | |
| 676 | new_file = _create_temporary(self._path) |
| 677 | try: |
| 678 | new_toc = {} |
| 679 | self._pre_mailbox_hook(new_file) |
| 680 | for key in sorted(self._toc.keys()): |
| 681 | start, stop = self._toc[key] |
| 682 | self._file.seek(start) |
| 683 | self._pre_message_hook(new_file) |
| 684 | new_start = new_file.tell() |
| 685 | while True: |
| 686 | buffer = self._file.read(min(4096, |
| 687 | stop - self._file.tell())) |
| 688 | if not buffer: |
| 689 | break |
| 690 | new_file.write(buffer) |
| 691 | new_toc[key] = (new_start, new_file.tell()) |
| 692 | self._post_message_hook(new_file) |
| 693 | self._file_length = new_file.tell() |
| 694 | except: |
| 695 | new_file.close() |
| 696 | os.remove(new_file.name) |
| 697 | raise |
| 698 | _sync_close(new_file) |
| 699 | # self._file is about to get replaced, so no need to sync. |
| 700 | self._file.close() |
| 701 | # Make sure the new file's mode is the same as the old file's |
| 702 | mode = os.stat(self._path).st_mode |
| 703 | os.chmod(new_file.name, mode) |
| 704 | try: |
| 705 | os.rename(new_file.name, self._path) |
| 706 | except FileExistsError: |
| 707 | os.remove(self._path) |
| 708 | os.rename(new_file.name, self._path) |
| 709 | self._file = open(self._path, 'rb+') |
no test coverage detected