New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mailbox.mbox creates new file when adding message to mbox #53768
Comments
When you call mailbox.mbox.add() the old mbox file is copied, the new file is modified and then renamed to the name of the'old' mbox file. This breaks the way that many MUAs detect and manage new mail in an mbox, in particular I discovered this with mutt. If the python process writing the mbox and mutt are on the same system writing a local file then you get the message "Mailbox was externally modified. Flags may be wrong." from mutt (and various odd things can happen). If mutt is reading the mbox over NFS then you get a "Stale NFS file handle" error. This should be strongly noted in the documentation for mailbox.mbox, in addition it would be really nice if there was a mailbox.mbox.append() method which *really* appends the data to the end of the mbox rather than changing it completely. Most MDAs (all?) do just append new mail to the end of the mbox and I feel that python should really try and do the same. |
This is actually not true. When calling add(), mbox (and MMDF and Babyl) append the message to the file without rewriting it. It's the following flush() call that rewrites the whole mailbox contents. I think this could be changed to work correctly by not setting self._pending = True in _singlefileMailbox.add. This way, the file wouldn't be rewritten by flush() if messages are only appended. OTOH, flush() should still fsync the mailbox file (if we want to ensure that the changes are really written to disk). This would probably require a new flag in addition to self._pending, to indicate that there are unsynced changes. |
Attached a patch that doesn't rewrite+rename if messages have only been added. In this case, flush() only syncs the mailbox file to make sure all changes have been written to disk. David & Barry: what do you think about including this on bugfix releases? Could someone depend on the file being rewritten in all situations? |
Could someone be depending on it? Sure. Is that likely enough to block this as a bug fix? Personally I think not. Appending to the mailbox when adding messages is, I think, the expected behavior, and always rewriting it is the surprising behavior. The patch looks good to me, though personally I'd eliminate the extra blank lines. |
New changeset c37cb11b546f by Petri Lehtinen in branch '2.7': New changeset 5f447a005d67 by Petri Lehtinen in branch '3.2': New changeset 0bacbab678ed by Petri Lehtinen in branch 'default': |
Fixed. I removed the extra newlines. |
See bpo-15122 for always modifying single-file mailboxes in-place. |
The _pre_mailbox_hook may be called twice, like this: babyl = mailbox.Babyl('new_file')
babyl.add('foo\n')
babyl.remove(0)
babyl.add('bar\n') This only affects Babyl, that writes the mailbox header in _pre_mailbox_hook. The mailbox is corrupted on disk until flush() is called. |
New changeset 3d7a75e945ee by Petri Lehtinen in branch '2.7': New changeset 7cf5a629fde2 by Petri Lehtinen in branch '3.2': New changeset 5a0ec296b287 by Petri Lehtinen in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: