Skip to content

Commit 89afed2

Browse files
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) <noreply@anthropic.com>
1 parent cdcf228 commit 89afed2

5 files changed

Lines changed: 57 additions & 1 deletion

File tree

Doc/library/imaplib.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,15 @@ An :class:`IMAP4` instance has the following methods:
452452
Returned data are tuples of message part envelope and data.
453453

454454

455+
.. method:: IMAP4.move(message_set, new_mailbox)
456+
457+
Move *message_set* messages onto end of *new_mailbox*.
458+
459+
The server must support the ``MOVE`` capability (:rfc:`6851`).
460+
461+
.. versionadded:: next
462+
463+
455464
.. method:: IMAP4.myrights(mailbox)
456465

457466
Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).

Doc/whatsnew/3.16.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,14 @@ io
228228
(Contributed by Marcel Martin in :gh:`90533`.)
229229

230230

231+
imaplib
232+
-------
233+
234+
* Add the :meth:`~imaplib.IMAP4.move` method,
235+
a wrapper for the ``MOVE`` command (:rfc:`6851`).
236+
(Contributed by Serhiy Storchaka in :gh:`77508`.)
237+
238+
231239
logging
232240
-------
233241

Lib/imaplib.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,14 @@ def lsub(self, directory='', pattern='*'):
789789
self._list_mailbox(pattern))
790790
return self._untagged_response(typ, dat, name)
791791

792+
def move(self, message_set, new_mailbox):
793+
"""Move 'message_set' messages onto end of 'new_mailbox'.
794+
795+
(typ, [data]) = <instance>.move(message_set, new_mailbox)
796+
"""
797+
return self._simple_command('MOVE', self._sequence_set(message_set),
798+
self._astring(new_mailbox))
799+
792800
def myrights(self, mailbox):
793801
"""Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).
794802
@@ -1031,7 +1039,7 @@ def uid(self, command, *args):
10311039
(command, self.state,
10321040
', '.join(Commands[command])))
10331041
name = 'UID'
1034-
if command == 'COPY':
1042+
if command in ('COPY', 'MOVE'):
10351043
message_set, new_mailbox = args
10361044
args = (self._sequence_set(message_set),
10371045
self._astring(new_mailbox))

Lib/test/test_imaplib.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,35 @@ def test_uid_copy(self):
11731173
self.assertEqual(data, [None])
11741174
self.assertEqual(server.args, ['COPY', '4827313:4828442', '"New folder"'])
11751175

1176+
def test_move(self):
1177+
client, server = self._setup(make_simple_handler('MOVE'))
1178+
client.login('user', 'pass')
1179+
client.select()
1180+
typ, data = client.move('2:4', 'MEETING')
1181+
self.assertEqual(typ, 'OK')
1182+
self.assertEqual(data, [b'MOVE completed'])
1183+
self.assertEqual(server.args, ['2:4', 'MEETING'])
1184+
1185+
typ, data = client.move('2:4', 'New folder')
1186+
self.assertEqual(typ, 'OK')
1187+
self.assertEqual(data, [b'MOVE completed'])
1188+
self.assertEqual(server.args, ['2:4', '"New folder"'])
1189+
1190+
def test_uid_move(self):
1191+
client, server = self._setup(make_simple_handler('UID',
1192+
completed='UID MOVE completed'))
1193+
client.login('user', 'pass')
1194+
client.select()
1195+
typ, data = client.uid('move', '4827313:4828442', 'MEETING')
1196+
self.assertEqual(typ, 'OK')
1197+
self.assertEqual(data, [None])
1198+
self.assertEqual(server.args, ['MOVE', '4827313:4828442', 'MEETING'])
1199+
1200+
typ, data = client.uid('move', '4827313:4828442', 'New folder')
1201+
self.assertEqual(typ, 'OK')
1202+
self.assertEqual(data, [None])
1203+
self.assertEqual(server.args, ['MOVE', '4827313:4828442', '"New folder"'])
1204+
11761205
def test_store(self):
11771206
client, server = self._setup(make_simple_handler('STORE', [
11781207
r'* 2 FETCH (FLAGS (\Deleted \Seen))',
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add :meth:`imaplib.IMAP4.move`, a wrapper for the IMAP ``MOVE`` command
2+
(:rfc:`6851`), analogous to :meth:`~imaplib.IMAP4.copy`.

0 commit comments

Comments
 (0)