Skip to content

Commit

Permalink
imaplib: downgrade idle-denied exception to error
Browse files Browse the repository at this point in the history
This makes it easier for client code to distinguish a temporary
rejection of the IDLE command from a server responding incorrectly to
IDLE.
  • Loading branch information
foresto committed Dec 22, 2024
1 parent b767ab6 commit dcd0161
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Lib/imaplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,9 @@ def __enter__(self):
# this occurs.
while resp := imap._get_response():
if imap.tagged_commands[self._tag]:
typ, data = imap.tagged_commands.pop(self._tag)
if typ == 'NO':
raise imap.error(f'idle denied: {data}')
raise imap.abort(f'unexpected status response: {resp}')

if __debug__ and imap.debug >= 4:
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_imaplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ def cmd_UNSELECT(self, tag, args):
self._send_tagged(tag, 'BAD', 'No mailbox selected')


class IdleCmdDenyHandler(SimpleIMAPHandler):
capabilities = 'IDLE'
def cmd_IDLE(self, tag, args):
self._send_tagged(tag, 'NO', 'IDLE is not allowed at this time')


class IdleCmdHandler(SimpleIMAPHandler):
capabilities = 'IDLE'
def cmd_IDLE(self, tag, args):
Expand Down Expand Up @@ -529,6 +535,13 @@ def test_idle_capability(self):
with client.idle():
pass

def test_idle_denied(self):
client, _ = self._setup(IdleCmdDenyHandler)
client.login('user', 'pass')
with self.assertRaises(imaplib.IMAP4.error):
with client.idle() as idler:
pass

def test_idle_iter(self):
client, _ = self._setup(IdleCmdHandler)
client.login('user', 'pass')
Expand Down

0 comments on commit dcd0161

Please sign in to comment.