summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/imaplib.rst9
-rw-r--r--Doc/whatsnew/3.9.rst7
-rw-r--r--Lib/imaplib.py17
-rw-r--r--Lib/test/test_imaplib.py25
-rw-r--r--Misc/NEWS.d/next/Library/2020-04-25-23-14-11.bpo-40375.5GuK2A.rst1
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.