imaplib.IMAP4 now supports the context manager protocol.
Original patch by Tarek Ziadé.
This commit is contained in:
parent
bb1e3f1ebe
commit
38684c3663
|
@ -37,6 +37,19 @@ base class:
|
||||||
initialized. If *host* is not specified, ``''`` (the local host) is used. If
|
initialized. If *host* is not specified, ``''`` (the local host) is used. If
|
||||||
*port* is omitted, the standard IMAP4 port (143) is used.
|
*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:
|
Three exceptions are defined as attributes of the :class:`IMAP4` class:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,14 @@ doctest
|
||||||
*module* contains no docstrings instead of raising :exc:`ValueError`
|
*module* contains no docstrings instead of raising :exc:`ValueError`
|
||||||
(contributed by Glenn Jones in :issue:`15916`).
|
(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
|
imghdr
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,14 @@ class IMAP4:
|
||||||
return getattr(self, attr.lower())
|
return getattr(self, attr.lower())
|
||||||
raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
|
raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
try:
|
||||||
|
self.logout()
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Overridable methods
|
# Overridable methods
|
||||||
|
|
|
@ -98,6 +98,10 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler):
|
||||||
continuation = None
|
continuation = None
|
||||||
capabilities = ''
|
capabilities = ''
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
super().setup()
|
||||||
|
self.server.logged = None
|
||||||
|
|
||||||
def _send(self, message):
|
def _send(self, message):
|
||||||
if verbose:
|
if verbose:
|
||||||
print("SENT: %r" % message.strip())
|
print("SENT: %r" % message.strip())
|
||||||
|
@ -162,9 +166,14 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler):
|
||||||
self._send_tagged(tag, 'OK', 'CAPABILITY completed')
|
self._send_tagged(tag, 'OK', 'CAPABILITY completed')
|
||||||
|
|
||||||
def cmd_LOGOUT(self, tag, args):
|
def cmd_LOGOUT(self, tag, args):
|
||||||
|
self.server.logged = None
|
||||||
self._send_textline('* BYE IMAP4ref1 Server logging out')
|
self._send_textline('* BYE IMAP4ref1 Server logging out')
|
||||||
self._send_tagged(tag, 'OK', 'LOGOUT completed')
|
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):
|
class ThreadedNetworkedTests(unittest.TestCase):
|
||||||
server_class = socketserver.TCPServer
|
server_class = socketserver.TCPServer
|
||||||
|
@ -345,6 +354,32 @@ class ThreadedNetworkedTests(unittest.TestCase):
|
||||||
self.assertRaises(imaplib.IMAP4.error,
|
self.assertRaises(imaplib.IMAP4.error,
|
||||||
self.imap_class, *server.server_address)
|
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")
|
@unittest.skipUnless(ssl, "SSL not available")
|
||||||
class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests):
|
class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests):
|
||||||
|
|
|
@ -132,6 +132,9 @@ Core and Builtins
|
||||||
Library
|
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
|
- Issue #16662: load_tests() is now unconditionally run when it is present in
|
||||||
a package's __init__.py. TestLoader.loadTestsFromModule() still accepts
|
a package's __init__.py. TestLoader.loadTestsFromModule() still accepts
|
||||||
use_load_tests, but it is deprecated and ignored. A new keyword-only
|
use_load_tests, but it is deprecated and ignored. A new keyword-only
|
||||||
|
|
Loading…
Reference in New Issue