mirror of
https://github.com/python/cpython.git
synced 2025-10-15 11:22:18 +00:00
gh-66515: Fix locking of an MH mailbox without ".mh_sequences" file (GH-113482)
Guarantee that it either open an existing ".mh_sequences" file or create a new ".mh_sequences" file, but do not replace existing ".mh_sequences" file.
This commit is contained in:
parent
89cee94b31
commit
be5e65fdf6
2 changed files with 26 additions and 2 deletions
|
@ -1141,10 +1141,24 @@ class MH(Mailbox):
|
||||||
"""Return a count of messages in the mailbox."""
|
"""Return a count of messages in the mailbox."""
|
||||||
return len(list(self.iterkeys()))
|
return len(list(self.iterkeys()))
|
||||||
|
|
||||||
|
def _open_mh_sequences_file(self, text):
|
||||||
|
mode = '' if text else 'b'
|
||||||
|
kwargs = {'encoding': 'ASCII'} if text else {}
|
||||||
|
path = os.path.join(self._path, '.mh_sequences')
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
return open(path, 'r+' + mode, **kwargs)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
return open(path, 'x+' + mode, **kwargs)
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
def lock(self):
|
def lock(self):
|
||||||
"""Lock the mailbox."""
|
"""Lock the mailbox."""
|
||||||
if not self._locked:
|
if not self._locked:
|
||||||
self._file = open(os.path.join(self._path, '.mh_sequences'), 'rb+')
|
self._file = self._open_mh_sequences_file(text=False)
|
||||||
_lock_file(self._file)
|
_lock_file(self._file)
|
||||||
self._locked = True
|
self._locked = True
|
||||||
|
|
||||||
|
@ -1225,8 +1239,9 @@ class MH(Mailbox):
|
||||||
|
|
||||||
def set_sequences(self, sequences):
|
def set_sequences(self, sequences):
|
||||||
"""Set sequences using the given name-to-key-list dictionary."""
|
"""Set sequences using the given name-to-key-list dictionary."""
|
||||||
f = open(os.path.join(self._path, '.mh_sequences'), 'w', encoding='ASCII')
|
f = self._open_mh_sequences_file(text=True)
|
||||||
try:
|
try:
|
||||||
|
os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC))
|
||||||
for name, keys in sequences.items():
|
for name, keys in sequences.items():
|
||||||
if len(keys) == 0:
|
if len(keys) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -1360,6 +1360,15 @@ class TestMH(TestMailbox, unittest.TestCase):
|
||||||
box.set_sequences({})
|
box.set_sequences({})
|
||||||
self.assertEqual(os.listdir(path), ['.mh_sequences'])
|
self.assertEqual(os.listdir(path), ['.mh_sequences'])
|
||||||
|
|
||||||
|
def test_lock_unlock_no_dot_mh_sequences_file(self):
|
||||||
|
path = os.path.join(self._path, 'foo.bar')
|
||||||
|
os.mkdir(path)
|
||||||
|
box = self._factory(path)
|
||||||
|
self.assertEqual(os.listdir(path), [])
|
||||||
|
box.lock()
|
||||||
|
box.unlock()
|
||||||
|
self.assertEqual(os.listdir(path), ['.mh_sequences'])
|
||||||
|
|
||||||
def test_issue2625(self):
|
def test_issue2625(self):
|
||||||
msg0 = mailbox.MHMessage(self._template % 0)
|
msg0 = mailbox.MHMessage(self._template % 0)
|
||||||
msg0.add_sequence('foo')
|
msg0.add_sequence('foo')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue