diff -r 2cf89e2e6247 Lib/imaplib.py --- a/Lib/imaplib.py Sun Jan 27 06:20:51 2013 +0200 +++ b/Lib/imaplib.py Sun Jan 27 12:49:07 2013 +0200 @@ -227,7 +227,14 @@ return getattr(self, attr.lower()) raise AttributeError("Unknown IMAP4 command: '%s'" % attr) + def __enter__(self): + """Context management protocol. Returns self.""" + return self + def __exit__(self, *args): + """Context management protocol. + logout() will close properly even if not logged in.""" + self.logout() # Overridable methods diff -r 2cf89e2e6247 Lib/test/test_imaplib.py --- a/Lib/test/test_imaplib.py Sun Jan 27 06:20:51 2013 +0200 +++ b/Lib/test/test_imaplib.py Sun Jan 27 12:49:07 2013 +0200 @@ -135,6 +135,12 @@ self._send(b'* CAPABILITY IMAP4rev1\r\n') self._send('{} OK CAPABILITY completed\r\n'.format(tag).encode('ASCII')) + def cmd_LOGOUT(self, tag, args): + self._send('{} OK LOGOUT\r\n'.format(tag).encode('ASCII')) + + def cmd_LOGIN(self, tag, args): + self._send('{} OK LOGIN\r\n'.format(tag).encode('ASCII')) + class BaseThreadedNetworkedTests(unittest.TestCase): @@ -214,6 +220,27 @@ self.assertRaises(imaplib.IMAP4.abort, self.imap_class, *server.server_address) + @reap_threads + def test_simple_with_statement(self): + # simplest call + with self.reaped_server(SimpleIMAPHandler) as server: + with self.imap_class(*server.server_address) as imap: + pass + + @reap_threads + def test_with_statement(self): + # doing something + with self.reaped_server(SimpleIMAPHandler) as server: + with self.imap_class(*server.server_address) as imap: + imap.login('user', 'pass') + + @reap_threads + def test_with_statement_quit(self): + # what happens if already quit in the block ? + with self.reaped_server(SimpleIMAPHandler) as server: + with self.imap_class(*server.server_address) as imap: + imap.login('user', 'pass') + imap.logout() class ThreadedNetworkedTests(BaseThreadedNetworkedTests):