Index: Lib/mailbox.py =================================================================== --- Lib/mailbox.py (revision 53106) +++ Lib/mailbox.py (working copy) @@ -513,6 +513,7 @@ self._next_key = 0 self._pending = False # No changes require rewriting the file. self._locked = False + self._file_length = None # Used to record mailbox size def add(self, message): """Add message and return assigned key.""" @@ -566,7 +567,21 @@ """Write any pending changes to disk.""" if not self._pending: return - self._lookup() + + # In order to be writing anything out at all, self._toc must + # already have been generated (and presumably has been modified + # by adding or deleting an item). + assert self._toc is not None + + # Check length of self._file; if it's changed, some other process + # has modified the mailbox since we scanned it. + self._file.seek(0, 2) + cur_len = self._file.tell() + if cur_len != self._file_length: + raise ExternalClashError('Size of mailbox file changed ' + '(expected %i, found %i)' % + (self._file_length, cur_len)) + new_file = _create_temporary(self._path) try: new_toc = {} @@ -642,6 +657,7 @@ offsets = self._install_message(message) self._post_message_hook(self._file) self._file.flush() + self._file_length = self._file.tell() # Record current length of mailbox return offsets @@ -733,6 +749,7 @@ break self._toc = dict(enumerate(zip(starts, stops))) self._next_key = len(self._toc) + self._file_length = self._file.tell() class MMDF(_mboxMMDF): @@ -776,6 +793,8 @@ break self._toc = dict(enumerate(zip(starts, stops))) self._next_key = len(self._toc) + self._file.seek(0, 2) + self._file_length = self._file.tell() class MH(Mailbox): @@ -1201,7 +1220,9 @@ self._toc = dict(enumerate(zip(starts, stops))) self._labels = dict(enumerate(label_lists)) self._next_key = len(self._toc) - + self._file.seek(0, 2) + self._file_length = self._file.tell() + def _pre_mailbox_hook(self, f): """Called before writing the mailbox to file f.""" f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s\037' %