diff options
-rw-r--r-- | Doc/library/imaplib.rst | 9 | ||||
-rw-r--r-- | Doc/whatsnew/3.9.rst | 7 | ||||
-rw-r--r-- | Lib/imaplib.py | 17 | ||||
-rw-r--r-- | Lib/test/test_imaplib.py | 25 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2020-04-25-23-14-11.bpo-40375.5GuK2A.rst | 1 |
5 files changed, 59 insertions, 0 deletions
diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 5b8ca7c..7c5b075 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -582,6 +582,15 @@ An :class:`IMAP4` instance has the following methods: 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[, ...]) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 728e600..0b15ec7 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -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. (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 --------- diff --git a/Lib/imaplib.py b/Lib/imaplib.py index abfdd73..d9720f2 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -98,6 +98,7 @@ Commands = { 'THREAD': ('SELECTED',), 'UID': ('SELECTED',), 'UNSUBSCRIBE': ('AUTH', 'SELECTED'), + 'UNSELECT': ('SELECTED',), } # Patterns to match server responses @@ -902,6 +903,22 @@ class IMAP4: 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): """Allow simple extension commands notified by server in CAPABILITY response. diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 7645666..69ee63b 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -116,6 +116,7 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler): def setup(self): super().setup() + self.server.is_selected = False self.server.logged = None def _send(self, message): @@ -190,6 +191,18 @@ class SimpleIMAPHandler(socketserver.StreamRequestHandler): self.server.logged = args[0] 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(): client = None @@ -511,6 +524,18 @@ class NewIMAPTestsMixin(): self.assertEqual(typ, 'OK') 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): imap_class = imaplib.IMAP4 diff --git a/Misc/NEWS.d/next/Library/2020-04-25-23-14-11.bpo-40375.5GuK2A.rst b/Misc/NEWS.d/next/Library/2020-04-25-23-14-11.bpo-40375.5GuK2A.rst new file mode 100644 index 0000000..eb58e00 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-04-25-23-14-11.bpo-40375.5GuK2A.rst @@ -0,0 +1 @@ +:meth:`imaplib.IMAP4.unselect` is added. Patch by Dong-hee Na. |