https://github.com/python/cpython/commit/89afed25c3427911c9df815ca4d8aeb261ab46ca commit: 89afed25c3427911c9df815ca4d8aeb261ab46ca branch: main author: Serhiy Storchaka <[email protected]> committer: serhiy-storchaka <[email protected]> date: 2026-07-05T20:02:45+03:00 summary:
gh-77508: Add imaplib.IMAP4.move method (GH-153121) Add a wrapper for the IMAP MOVE command (RFC 6851), analogous to copy(). The arguments of MOVE and UID MOVE are quoted when necessary. Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]> files: A Misc/NEWS.d/next/Library/2026-07-01-15-30-00.gh-issue-77508.Bn2kXt.rst M Doc/library/imaplib.rst M Doc/whatsnew/3.16.rst M Lib/imaplib.py M Lib/test/test_imaplib.py diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 3f46c5146acc6ee..6b7c02f54e90af2 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -452,6 +452,15 @@ An :class:`IMAP4` instance has the following methods: Returned data are tuples of message part envelope and data. +.. method:: IMAP4.move(message_set, new_mailbox) + + Move *message_set* messages onto end of *new_mailbox*. + + The server must support the ``MOVE`` capability (:rfc:`6851`). + + .. versionadded:: next + + .. method:: IMAP4.myrights(mailbox) Show my ACLs for a mailbox (i.e. the rights that I have on mailbox). diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 8219700cc1e8385..cf105a26d98d45d 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -228,6 +228,14 @@ io (Contributed by Marcel Martin in :gh:`90533`.) +imaplib +------- + +* Add the :meth:`~imaplib.IMAP4.move` method, + a wrapper for the ``MOVE`` command (:rfc:`6851`). + (Contributed by Serhiy Storchaka in :gh:`77508`.) + + logging ------- diff --git a/Lib/imaplib.py b/Lib/imaplib.py index 8e271209a664faa..adfd8afb9c053bb 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -789,6 +789,14 @@ def lsub(self, directory='', pattern='*'): self._list_mailbox(pattern)) return self._untagged_response(typ, dat, name) + def move(self, message_set, new_mailbox): + """Move 'message_set' messages onto end of 'new_mailbox'. + + (typ, [data]) = <instance>.move(message_set, new_mailbox) + """ + return self._simple_command('MOVE', self._sequence_set(message_set), + self._astring(new_mailbox)) + def myrights(self, mailbox): """Show my ACLs for a mailbox (i.e. the rights that I have on mailbox). @@ -1031,7 +1039,7 @@ def uid(self, command, *args): (command, self.state, ', '.join(Commands[command]))) name = 'UID' - if command == 'COPY': + if command in ('COPY', 'MOVE'): message_set, new_mailbox = args args = (self._sequence_set(message_set), self._astring(new_mailbox)) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index ef283267ff08ef0..046d28f4d30c8a4 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -1173,6 +1173,35 @@ def test_uid_copy(self): self.assertEqual(data, [None]) self.assertEqual(server.args, ['COPY', '4827313:4828442', '"New folder"']) + def test_move(self): + client, server = self._setup(make_simple_handler('MOVE')) + client.login('user', 'pass') + client.select() + typ, data = client.move('2:4', 'MEETING') + self.assertEqual(typ, 'OK') + self.assertEqual(data, [b'MOVE completed']) + self.assertEqual(server.args, ['2:4', 'MEETING']) + + typ, data = client.move('2:4', 'New folder') + self.assertEqual(typ, 'OK') + self.assertEqual(data, [b'MOVE completed']) + self.assertEqual(server.args, ['2:4', '"New folder"']) + + def test_uid_move(self): + client, server = self._setup(make_simple_handler('UID', + completed='UID MOVE completed')) + client.login('user', 'pass') + client.select() + typ, data = client.uid('move', '4827313:4828442', 'MEETING') + self.assertEqual(typ, 'OK') + self.assertEqual(data, [None]) + self.assertEqual(server.args, ['MOVE', '4827313:4828442', 'MEETING']) + + typ, data = client.uid('move', '4827313:4828442', 'New folder') + self.assertEqual(typ, 'OK') + self.assertEqual(data, [None]) + self.assertEqual(server.args, ['MOVE', '4827313:4828442', '"New folder"']) + def test_store(self): client, server = self._setup(make_simple_handler('STORE', [ r'* 2 FETCH (FLAGS (\Deleted \Seen))', diff --git a/Misc/NEWS.d/next/Library/2026-07-01-15-30-00.gh-issue-77508.Bn2kXt.rst b/Misc/NEWS.d/next/Library/2026-07-01-15-30-00.gh-issue-77508.Bn2kXt.rst new file mode 100644 index 000000000000000..d6f1bd23be080a3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-01-15-30-00.gh-issue-77508.Bn2kXt.rst @@ -0,0 +1,2 @@ +Add :meth:`imaplib.IMAP4.move`, a wrapper for the IMAP ``MOVE`` command +(:rfc:`6851`), analogous to :meth:`~imaplib.IMAP4.copy`. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
