Skip to content

Commit 69a2601

Browse files
serhiy-storchakaclaude
authored andcommitted
gh-153417: Fix BytesWarning in imaplib error messages for bytes arguments (GH-153423)
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 6404803 commit 69a2601

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
@@ -899,7 +899,7 @@ def select(self, mailbox='INBOX', readonly=False):
899899
if __debug__:
900900
if self.debug >= 1:
901901
self._dump_ur(self.untagged_responses)
902-
raise self.readonly('%s is not writable' % mailbox)
902+
raise self.readonly('%r is not writable' % (mailbox,))
903903
return typ, self.untagged_responses.get('EXISTS', [None])
904904

905905

@@ -1024,7 +1024,7 @@ def uid(self, command, *args):
10241024
"""
10251025
command = command.upper()
10261026
if not command in Commands:
1027-
raise self.error("Unknown IMAP4 UID command: %s" % command)
1027+
raise self.error("Unknown IMAP4 UID command: %r" % (command,))
10281028
if self.state not in Commands[command]:
10291029
raise self.error("command %s illegal in state %s, "
10301030
"only allowed in states %s" %

Lib/test/test_imaplib.py

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

945+
def test_readonly_error_reports_mailbox(self):
946+
# The read-only error reports the mailbox via repr(), which also
947+
# avoids BytesWarning for a bytes mailbox under -bb.
948+
class ReadOnlyHandler(SimpleIMAPHandler):
949+
def cmd_SELECT(self, tag, args):
950+
self._send_line(b'* 2 EXISTS')
951+
self._send_tagged(tag, 'OK', '[READ-ONLY] SELECT completed.')
952+
client, _ = self._setup(ReadOnlyHandler)
953+
client.login('user', 'pass')
954+
for mailbox, expected in [('INBOX', "'INBOX'"), (b'INBOX', r"b'INBOX'")]:
955+
with self.subTest(mailbox=mailbox):
956+
with self.assertRaisesRegex(imaplib.IMAP4.readonly,
957+
r"%s is not writable" % expected):
958+
client.select(mailbox)
959+
960+
def test_uid_unknown_command_reports_command(self):
961+
# The unknown-UID-command error reports the command via repr(), which
962+
# also avoids BytesWarning for a bytes command under -bb.
963+
client, _ = self._setup(SimpleIMAPHandler)
964+
for command, expected in [('BOGUS', "'BOGUS'"), (b'BOGUS', r"b'BOGUS'")]:
965+
with self.subTest(command=command):
966+
with self.assertRaisesRegex(
967+
imaplib.IMAP4.error,
968+
r"Unknown IMAP4 UID command: %s" % expected):
969+
client.uid(command, '1')
970+
945971
def test_logout(self):
946972
client, _ = self._setup(SimpleIMAPHandler)
947973
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)