bpo-40375: Implement imaplib.IMAP4.unselect (GH-19712)
This commit is contained in:
parent
91a5ae1835
commit
c5c42815ec
|
@ -582,6 +582,15 @@ An :class:`IMAP4` instance has the following methods:
|
||||||
|
|
||||||
Unsubscribe from old mailbox.
|
Unsubscribe from old mailbox.
|
||||||
|
|
||||||
|
.. method:: IMAP4.unselect()
|
||||||
|
|
||||||
|
:meth:`imaplib.IMAP4.unselect` frees server's resources associated with the
|
||||||
|
selected mailbox and returns the server to the authenticated
|
||||||
|
state. This command performs the same actions as :meth:`imaplib.IMAP4.close`, except
|
||||||
|
that no messages are permanently removed from the currently
|
||||||
|
selected mailbox.
|
||||||
|
|
||||||
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
.. method:: IMAP4.xatom(name[, ...])
|
.. method:: IMAP4.xatom(name[, ...])
|
||||||
|
|
||||||
|
|
|
@ -320,6 +320,13 @@ with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and
|
||||||
:class:`~imaplib.IMAP4_stream` were applied to this change.
|
:class:`~imaplib.IMAP4_stream` were applied to this change.
|
||||||
(Contributed by Dong-hee Na in :issue:`38615`.)
|
(Contributed by Dong-hee Na in :issue:`38615`.)
|
||||||
|
|
||||||
|
:meth:`imaplib.IMAP4.unselect` is added.
|
||||||
|
:meth:`imaplib.IMAP4.unselect` frees server's resources associated with the
|
||||||
|
selected mailbox and returns the server to the authenticated
|
||||||
|
state. This command performs the same actions as :meth:`imaplib.IMAP4.close`, except
|
||||||
|
that no messages are permanently removed from the currently
|
||||||
|
selected mailbox. (Contributed by Dong-hee Na in :issue:`40375`.)
|
||||||
|
|
||||||
importlib
|
importlib
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ Commands = {
|
||||||
'THREAD': ('SELECTED',),
|
'THREAD': ('SELECTED',),
|
||||||
'UID': ('SELECTED',),
|
'UID': ('SELECTED',),
|
||||||
'UNSUBSCRIBE': ('AUTH', 'SELECTED'),
|
'UNSUBSCRIBE': ('AUTH', 'SELECTED'),
|
||||||
|
'UNSELECT': ('SELECTED',),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Patterns to match server responses
|
# Patterns to match server responses
|
||||||
|
@ -902,6 +903,22 @@ class IMAP4:
|
||||||
return self._simple_command('UNSUBSCRIBE', mailbox)
|
return self._simple_command('UNSUBSCRIBE', mailbox)
|
||||||
|
|
||||||
|
|
||||||
|
def unselect(self):
|
||||||
|
"""Free server's resources associated with the selected mailbox
|
||||||
|
and returns the server to the authenticated state.
|
||||||
|
This command performs the same actions as CLOSE, except
|
||||||
|
that no messages are permanently removed from the currently
|
||||||
|
selected mailbox.
|
||||||
|
|
||||||
|
(typ, [data]) = <instance>.unselect()
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
typ, data = self._simple_command('UNSELECT')
|
||||||
|
finally:
|
||||||
|
self.state = 'AUTH'
|
||||||
|
return typ, data
|
||||||
|
|
||||||
|
|
||||||
def xatom(self, name, *args):
|
def xatom(self, name, *args):
|
||||||
"""Allow simple extension commands
|
"""Allow simple extension commands
|
||||||
notified by server in CAPABILITY response.
|
notified by server in CAPABILITY response.
|
||||||
|
|
|
@ -116,6 +116,7 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
super().setup()
|
super().setup()
|
||||||
|
self.server.is_selected = False
|
||||||
self.server.logged = None
|
self.server.logged = None
|
||||||
|
|
||||||
def _send(self, message):
|
def _send(self, message):
|
||||||
|
@ -190,6 +191,18 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler):
|
||||||
self.server.logged = args[0]
|
self.server.logged = args[0]
|
||||||
self._send_tagged(tag, 'OK', 'LOGIN completed')
|
self._send_tagged(tag, 'OK', 'LOGIN completed')
|
||||||
|
|
||||||
|
def cmd_SELECT(self, tag, args):
|
||||||
|
self.server.is_selected = True
|
||||||
|
self._send_line(b'* 2 EXISTS')
|
||||||
|
self._send_tagged(tag, 'OK', '[READ-WRITE] SELECT completed.')
|
||||||
|
|
||||||
|
def cmd_UNSELECT(self, tag, args):
|
||||||
|
if self.server.is_selected:
|
||||||
|
self.server.is_selected = False
|
||||||
|
self._send_tagged(tag, 'OK', 'Returned to authenticated state. (Success)')
|
||||||
|
else:
|
||||||
|
self._send_tagged(tag, 'BAD', 'No mailbox selected')
|
||||||
|
|
||||||
|
|
||||||
class NewIMAPTestsMixin():
|
class NewIMAPTestsMixin():
|
||||||
client = None
|
client = None
|
||||||
|
@ -511,6 +524,18 @@ class NewIMAPTestsMixin():
|
||||||
self.assertEqual(typ, 'OK')
|
self.assertEqual(typ, 'OK')
|
||||||
self.assertEqual(data[0], b'() "." directoryA')
|
self.assertEqual(data[0], b'() "." directoryA')
|
||||||
|
|
||||||
|
def test_unselect(self):
|
||||||
|
client, _ = self._setup(SimpleIMAPHandler)
|
||||||
|
client.login('user', 'pass')
|
||||||
|
typ, data = client.select()
|
||||||
|
self.assertEqual(typ, 'OK')
|
||||||
|
self.assertEqual(data[0], b'2')
|
||||||
|
|
||||||
|
typ, data = client.unselect()
|
||||||
|
self.assertEqual(typ, 'OK')
|
||||||
|
self.assertEqual(data[0], b'Returned to authenticated state. (Success)')
|
||||||
|
self.assertEqual(client.state, 'AUTH')
|
||||||
|
|
||||||
|
|
||||||
class NewIMAPTests(NewIMAPTestsMixin, unittest.TestCase):
|
class NewIMAPTests(NewIMAPTestsMixin, unittest.TestCase):
|
||||||
imap_class = imaplib.IMAP4
|
imap_class = imaplib.IMAP4
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
:meth:`imaplib.IMAP4.unselect` is added. Patch by Dong-hee Na.
|
Loading…
Reference in New Issue