Skip to content

Commit 31fac5d

Browse files
miss-islingtonserhiy-storchakaclaude
authored
[3.13] gh-153417: Fix BytesWarning in imaplib error messages for bytes arguments (GH-153423) (GH-153432)
IMAP4.select() and IMAP4.uid() formatted the mailbox and command argument with %s in their error messages, which raised BytesWarning under -bb when the argument was bytes and masked the real error. Use %r instead, which is safe for bytes and also quotes the value. (cherry picked from commit 11f1b70) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 91abe31 commit 31fac5d

3 files changed

Lines changed: 31 additions & 2 deletions

File tree

Lib/imaplib.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ def select(self, mailbox='INBOX', readonly=False):
797797
if __debug__:
798798
if self.debug >= 1:
799799
self._dump_ur(self.untagged_responses)
800-
raise self.readonly('%s is not writable' % mailbox)
800+
raise self.readonly('%r is not writable' % (mailbox,))
801801
return typ, self.untagged_responses.get('EXISTS', [None])
802802

803803

@@ -921,7 +921,7 @@ def uid(self, command, *args):
921921
"""
922922
command = command.upper()
923923
if not command in Commands:
924-
raise self.error("Unknown IMAP4 UID command: %s" % command)
924+
raise self.error("Unknown IMAP4 UID command: %r" % (command,))
925925
if self.state not in Commands[command]:
926926
raise self.error("command %s illegal in state %s, "
927927
"only allowed in states %s" %

Lib/test/test_imaplib.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,32 @@ def cmd_CAPABILITY(self, tag, args):
833833
client.login('user', 'pass')
834834
self.assertIn('ENABLE', client.capabilities)
835835

836+
def test_readonly_error_reports_mailbox(self):
837+
# The read-only error reports the mailbox via repr(), which also
838+
# avoids BytesWarning for a bytes mailbox under -bb.
839+
class ReadOnlyHandler(SimpleIMAPHandler):
840+
def cmd_SELECT(self, tag, args):
841+
self._send_line(b'* 2 EXISTS')
842+
self._send_tagged(tag, 'OK', '[READ-ONLY] SELECT completed.')
843+
client, _ = self._setup(ReadOnlyHandler)
844+
client.login('user', 'pass')
845+
for mailbox, expected in [('INBOX', "'INBOX'"), (b'INBOX', r"b'INBOX'")]:
846+
with self.subTest(mailbox=mailbox):
847+
with self.assertRaisesRegex(imaplib.IMAP4.readonly,
848+
r"%s is not writable" % expected):
849+
client.select(mailbox)
850+
851+
def test_uid_unknown_command_reports_command(self):
852+
# The unknown-UID-command error reports the command via repr(), which
853+
# also avoids BytesWarning for a bytes command under -bb.
854+
client, _ = self._setup(SimpleIMAPHandler)
855+
for command, expected in [('BOGUS', "'BOGUS'"), (b'BOGUS', r"b'BOGUS'")]:
856+
with self.subTest(command=command):
857+
with self.assertRaisesRegex(
858+
imaplib.IMAP4.error,
859+
r"Unknown IMAP4 UID command: %s" % expected):
860+
client.uid(command, '1')
861+
836862
def test_logout(self):
837863
client, _ = self._setup(SimpleIMAPHandler)
838864
typ, data = client.login('user', 'pass')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Error messages from :meth:`imaplib.IMAP4.select` and :meth:`imaplib.IMAP4.uid`
2+
no longer raise :exc:`BytesWarning` under :option:`!-bb`
3+
when the mailbox or command argument is :class:`bytes`.

0 commit comments

Comments
 (0)