merge #11767: use context manager to close file in __getitem__ to prevent FD leak

This commit is contained in:
R David Murray 2011-06-17 12:56:41 -04:00
commit 4c7d21e2b3
3 changed files with 37 additions and 2 deletions

View File

@ -20,6 +20,7 @@ import email
import email.message import email.message
import email.generator import email.generator
import io import io
import contextlib
try: try:
if sys.platform == 'os2emx': if sys.platform == 'os2emx':
# OS/2 EMX fcntl() not adequate # OS/2 EMX fcntl() not adequate
@ -76,7 +77,8 @@ class Mailbox:
if not self._factory: if not self._factory:
return self.get_message(key) return self.get_message(key)
else: else:
return self._factory(self.get_file(key)) with contextlib.closing(self.get_file(key)) as file:
return self._factory(file)
def get_message(self, key): def get_message(self, key):
"""Return a Message representation or raise a KeyError.""" """Return a Message representation or raise a KeyError."""

View File

@ -1201,6 +1201,37 @@ class TestBabyl(TestMailbox):
self.assertEqual(set(self._box.get_labels()), set(['blah'])) self.assertEqual(set(self._box.get_labels()), set(['blah']))
class FakeFileLikeObject:
def __init__(self):
self.closed = False
def close(self):
self.closed = True
class FakeMailBox(mailbox.Mailbox):
def __init__(self):
mailbox.Mailbox.__init__(self, '', lambda file: None)
self.files = [FakeFileLikeObject() for i in range(10)]
def get_file(self, key):
return self.files[key]
class TestFakeMailBox(unittest.TestCase):
def test_closing_fd(self):
box = FakeMailBox()
for i in range(10):
self.assertFalse(box.files[i].closed)
for i in range(10):
box[i]
for i in range(10):
self.assertTrue(box.files[i].closed)
class TestMessage(TestBase): class TestMessage(TestBase):
_factory = mailbox.Message # Overridden by subclasses to reuse tests _factory = mailbox.Message # Overridden by subclasses to reuse tests
@ -2113,7 +2144,7 @@ def test_main():
TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage, TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage,
TestMHMessage, TestBabylMessage, TestMMDFMessage, TestMHMessage, TestBabylMessage, TestMMDFMessage,
TestMessageConversion, TestProxyFile, TestPartialFile, TestMessageConversion, TestProxyFile, TestPartialFile,
MaildirTestCase) MaildirTestCase, TestFakeMailBox)
support.run_unittest(*tests) support.run_unittest(*tests)
support.reap_children() support.reap_children()

View File

@ -193,6 +193,8 @@ Core and Builtins
Library Library
------- -------
- Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method.
- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP
connection if its getresponse() method fails with a socket error. Patch connection if its getresponse() method fails with a socket error. Patch
written by Ezio Melotti. written by Ezio Melotti.