[Python-checkins] cpython: imaplib.IMAP4 now supports the context manager protocol.

serhiy.storchaka python-checkins at python.org
Tue Sep 9 18:09:20 CEST 2014


http://hg.python.org/cpython/rev/e1b1be597736
changeset: 92379:e1b1be597736
user: Serhiy Storchaka <storchaka at gmail.com>
date: Tue Sep 09 19:07:49 2014 +0300
summary:
 imaplib.IMAP4 now supports the context manager protocol.
Original patch by Tarek Ziadé.
files:
 Doc/library/imaplib.rst | 13 ++++++++++
 Doc/whatsnew/3.5.rst | 8 ++++++
 Lib/imaplib.py | 8 ++++++
 Lib/test/test_imaplib.py | 35 ++++++++++++++++++++++++++++
 Misc/NEWS | 3 ++
 5 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst
--- a/Doc/library/imaplib.rst
+++ b/Doc/library/imaplib.rst
@@ -37,6 +37,19 @@
 initialized. If *host* is not specified, ``''`` (the local host) is used. If
 *port* is omitted, the standard IMAP4 port (143) is used.
 
+ The :class:`IMAP4` class supports the :keyword:`with` statement. When used
+ like this, the IMAP4 ``LOGOUT`` command is issued automatically when the
+ :keyword:`with` statement exits. E.g.::
+
+ >>> from imaplib import IMAP4
+ >>> with IMAP4("domain.org") as M:
+ ... M.noop()
+ ...
+ ('OK', [b'Nothing Accomplished. d25if65hy903weo.87'])
+
+ .. versionchanged:: 3.5
+ Support for the :keyword:`with` statement was added.
+
 Three exceptions are defined as attributes of the :class:`IMAP4` class:
 
 
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -141,6 +141,14 @@
 *module* contains no docstrings instead of raising :exc:`ValueError`
 (contributed by Glenn Jones in :issue:`15916`).
 
+imaplib
+-------
+
+* :class:`IMAP4` now supports the context management protocol. When used in a
+ :keyword:`with` statement, the IMAP4 ``LOGOUT`` command will be called
+ automatically at the end of the block. (Contributed by Tarek Ziadé and
+ Serhiy Storchaka in :issue:`4972`).
+
 imghdr
 ------
 
diff --git a/Lib/imaplib.py b/Lib/imaplib.py
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -238,6 +238,14 @@
 return getattr(self, attr.lower())
 raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
 
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ try:
+ self.logout()
+ except OSError:
+ pass
 
 
 # Overridable methods
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -98,6 +98,10 @@
 continuation = None
 capabilities = ''
 
+ def setup(self):
+ super().setup()
+ self.server.logged = None
+
 def _send(self, message):
 if verbose:
 print("SENT: %r" % message.strip())
@@ -162,9 +166,14 @@
 self._send_tagged(tag, 'OK', 'CAPABILITY completed')
 
 def cmd_LOGOUT(self, tag, args):
+ self.server.logged = None
 self._send_textline('* BYE IMAP4ref1 Server logging out')
 self._send_tagged(tag, 'OK', 'LOGOUT completed')
 
+ def cmd_LOGIN(self, tag, args):
+ self.server.logged = args[0]
+ self._send_tagged(tag, 'OK', 'LOGIN completed')
+
 
 class ThreadedNetworkedTests(unittest.TestCase):
 server_class = socketserver.TCPServer
@@ -345,6 +354,32 @@
 self.assertRaises(imaplib.IMAP4.error,
 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):
+ pass
+
+ @reap_threads
+ def test_with_statement(self):
+ with self.reaped_server(SimpleIMAPHandler) as server:
+ with self.imap_class(*server.server_address) as imap:
+ imap.login('user', 'pass')
+ self.assertEqual(server.logged, 'user')
+ self.assertIsNone(server.logged)
+
+ @reap_threads
+ def test_with_statement_logout(self):
+ # what happens if already logout in the block?
+ with self.reaped_server(SimpleIMAPHandler) as server:
+ with self.imap_class(*server.server_address) as imap:
+ imap.login('user', 'pass')
+ self.assertEqual(server.logged, 'user')
+ imap.logout()
+ self.assertIsNone(server.logged)
+ self.assertIsNone(server.logged)
+
 
 @unittest.skipUnless(ssl, "SSL not available")
 class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -132,6 +132,9 @@
 Library
 -------
 
+- Issue #12410: imaplib.IMAP4 now supports the context manager protocol.
+ Original patch by Tarek Ziadé.
+
 - Issue #16662: load_tests() is now unconditionally run when it is present in
 a package's __init__.py. TestLoader.loadTestsFromModule() still accepts
 use_load_tests, but it is deprecated and ignored. A new keyword-only
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /