cpython: c37cb11b546f (original) (raw)
Mercurial > cpython
changeset 77832:c37cb11b546f 2.7
#9559: Append data to single-file mailbox files if messages are only added If messages were only added, a new file is no longer created and renamed over the old file when flush() is called on an mbox, MMDF or Babyl mailbox. [#9559]
Petri Lehtinen petri@digip.org | |
---|---|
date | Thu, 28 Jun 2012 13:48:17 +0300 |
parents | 73710ae9fedc |
children | 49dee01d72f9 |
files | Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS |
diffstat | 3 files changed, 46 insertions(+), 5 deletions(-)[+] [-] Lib/mailbox.py 18 Lib/test/test_mailbox.py 29 Misc/NEWS 4 |
line wrap: on
line diff
--- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -561,16 +561,19 @@ class _singlefileMailbox(Mailbox): self._file = f self._toc = None self._next_key = 0
self._pending = False # No changes require rewriting the file.[](#l1.7)
self._pending = False # No changes require rewriting the file.[](#l1.8)
self._pending_sync = False # No need to sync the file[](#l1.9) self._locked = False[](#l1.10)
self._file_length = None # Used to record mailbox size[](#l1.11)
self._file_length = None # Used to record mailbox size[](#l1.12)
def add(self, message): """Add message and return assigned key.""" self._lookup() self._toc[self._next_key] = self._append_message(message) self._next_key += 1
self._pending = True[](#l1.19)
# _append_message appends the message to the mailbox file. We[](#l1.20)
# don't need a full rewrite + rename, sync is enough.[](#l1.21)
self._pending_sync = True[](#l1.22) return self._next_key - 1[](#l1.23)
def remove(self, key): @@ -616,6 +619,11 @@ class _singlefileMailbox(Mailbox): def flush(self): """Write any pending changes to disk.""" if not self._pending:
if self._pending_sync:[](#l1.30)
# Messages have only been added, so syncing the file[](#l1.31)
# is enough.[](#l1.32)
_sync_flush(self._file)[](#l1.33)
self._pending_sync = False[](#l1.34) return[](#l1.35)
# In order to be writing anything out at all, self._toc must @@ -669,6 +677,7 @@ class _singlefileMailbox(Mailbox): self._file = open(self._path, 'rb+') self._toc = new_toc self._pending = False
self._pending_sync = False[](#l1.42) if self._locked:[](#l1.43) _lock_file(self._file, dotlock=False)[](#l1.44)
@@ -705,6 +714,9 @@ class _singlefileMailbox(Mailbox): """Append message to mailbox and return (start, stop) offsets.""" self._file.seek(0, 2) before = self._file.tell()
if len(self._toc) == 0:[](#l1.50)
# This is the first message[](#l1.51)
self._pre_mailbox_hook(self._file)[](#l1.52) try:[](#l1.53) self._pre_message_hook(self._file)[](#l1.54) offsets = self._install_message(message)[](#l1.55)
--- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -824,7 +824,32 @@ class TestMaildir(TestMailbox, unittest. self._box._refresh() self.assertTrue(refreshed()) -class _TestMboxMMDF(TestMailbox): + +class _TestSingleFile(TestMailbox):
- def test_add_doesnt_rewrite(self):
# When only adding messages, flush() should not rewrite the[](#l2.13)
# mailbox file. See issue #9559.[](#l2.14)
# Inode number changes if the contents are written to another[](#l2.16)
# file which is then renamed over the original file. So we[](#l2.17)
# must check that the inode number doesn't change.[](#l2.18)
inode_before = os.stat(self._path).st_ino[](#l2.19)
self._box.add(self._template % 0)[](#l2.21)
self._box.flush()[](#l2.22)
inode_after = os.stat(self._path).st_ino[](#l2.24)
self.assertEqual(inode_before, inode_after)[](#l2.25)
# Make sure the message was really added[](#l2.27)
self._box.close()[](#l2.28)
self._box = self._factory(self._path)[](#l2.29)
self.assertEqual(len(self._box), 1)[](#l2.30)
+ + +class _TestMboxMMDF(_TestSingleFile): def tearDown(self): self._box.close() @@ -1085,7 +1110,7 @@ class TestMH(TestMailbox, unittest.TestC return os.path.join(self._path, '.mh_sequences.lock') -class TestBabyl(TestMailbox, unittest.TestCase): +class TestBabyl(_TestSingleFile, unittest.TestCase): _factory = lambda self, path, factory=None: mailbox.Babyl(path, factory)
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -75,6 +75,10 @@ Core and Builtins Library ------- +- Issue #9559: If messages were only added, a new file is no longer