@@ -308,22 +308,28 @@ An :class:`IMAP4` instance has the following methods:
308
308
of the IMAP4 QUOTA extension defined in rfc2087.
309
309
310
310
311
- .. method :: IMAP4.idle([ dur] )
311
+ .. method :: IMAP4.idle(dur=None )
312
312
313
313
Return an iterable context manager implementing the ``IDLE `` command
314
314
as defined in :rfc: `2177 `.
315
315
316
- The optional *dur * argument specifies a maximum duration (in seconds) to
317
- keep idling. It defaults to ``None ``, meaning no time limit.
318
- To avoid inactivity timeouts on servers that impose them, callers are
319
- advised to keep this <= 29 minutes. See the note below regarding
316
+ The context manager sends the ``IDLE `` command when activated by the
317
+ :keyword: `with ` statement, produces IMAP untagged responses via the
318
+ :term: `iterator ` protocol, and sends ``DONE `` upon context exit.
319
+
320
+ The *dur * argument sets a maximum duration (in seconds) to keep idling,
321
+ after which iteration will stop. It defaults to ``None ``, meaning no time
322
+ limit. Callers wishing to avoid inactivity timeouts on servers that impose
323
+ them should keep this <= 29 minutes.
324
+ See the :ref: `warning below <windows-pipe-timeout-warning >` if using
320
325
:class: `IMAP4_stream ` on Windows.
321
326
322
- The context manager sends the ``IDLE `` command upon entry, produces
323
- responses via iteration, and sends ``DONE `` upon exit.
324
- It represents responses as ``(type, datum) `` tuples, rather than the
325
- ``(type, [data, ...]) `` tuples returned by other methods, because only
326
- one response is represented at a time.
327
+ Response tuples produced by the iterator almost exactly match those
328
+ returned by other imaplib methods. The difference is that the tuple's
329
+ second member is a single response datum, rather than a list of data.
330
+ Therefore, in a mailbox where calling ``M.response('EXISTS') `` would
331
+ return ``('EXISTS', [b'1']) ``, the idle iterator would produce
332
+ ``('EXISTS', b'1') ``.
327
333
328
334
Example::
329
335
@@ -332,22 +338,59 @@ An :class:`IMAP4` instance has the following methods:
332
338
typ, datum = response
333
339
print(typ, datum)
334
340
335
- It is also possible to process a burst of responses all at once instead
336
- of one at a time. See ` IDLE Context Manager `_ for details.
341
+ ('EXISTS', b'1')
342
+ ('RECENT', b'1')
337
343
338
- Responses produced by the iterator will not be returned by
339
- :meth: `IMAP4.response `.
344
+ Instead of iterating one response at a time, it is also possible to retrieve
345
+ the next response along with any immediately available subsequent responses
346
+ (e.g. a rapid series of ``EXPUNGE `` events from a bulk delete). This
347
+ batch processing aid is provided by the context's ``burst() ``
348
+ :term: `generator `:
340
349
341
- .. note ::
350
+ .. method :: idler.burst(interval=0.1)
351
+
352
+ Yield a burst of responses no more than *interval * seconds apart.
353
+
354
+ Example::
355
+
356
+ with M.idle() as idler:
357
+
358
+ # get the next response and any others following by < 0.1 seconds
359
+ batch = list(idler.burst())
360
+
361
+ print(f'processing {len(batch)} responses...')
362
+ print(batch)
363
+
364
+ processing 3 responses...
365
+ [('EXPUNGE', b'2'), ('EXPUNGE', b'1'), ('RECENT', b'0')]
366
+
367
+ The ``IDLE `` context's maximum duration (the *dur * argument to
368
+ :meth: `IMAP4.idle `) is respected when waiting for the first response
369
+ in a burst. Therefore, an expired idle context will cause this generator
370
+ to return immediately without producing anything. Callers should
371
+ consider this if using it in a loop.
372
+
373
+
374
+ .. _windows-pipe-timeout-warning :
375
+
376
+ .. warning ::
342
377
343
378
Windows :class: `IMAP4_stream ` connections have no way to accurately
344
- respect *dur *, since Windows ``select() `` only works on sockets.
345
- However, if the server regularly sends status messages during ``IDLE ``,
346
- they will wake our selector and keep iteration from blocking for long.
347
- Dovecot's ``imap_idle_notify_interval `` is two minutes by default.
348
- Assuming that's typical of IMAP servers, subtracting it from the 29
349
- minutes needed to avoid server inactivity timeouts would make 27
350
- minutes a sensible value for *dur * in this situation.
379
+ respect the *dur * or *interval * arguments, since Windows ``select() ``
380
+ only works on sockets.
381
+
382
+ If the server regularly sends status messages during ``IDLE ``, they will
383
+ wake our iterator anyway, allowing *dur * to behave roughly as intended,
384
+ although usually late. Dovecot's ``imap_idle_notify_interval `` default
385
+ setting does this every 2 minutes. Assuming that's typical of IMAP
386
+ servers, subtracting it from the 29 minutes needed to avoid server
387
+ inactivity timeouts would make 27 minutes a sensible value for *dur * in
388
+ this situation.
389
+
390
+ There is no such fallback for ``burst() ``, which will yield endless
391
+ responses and block indefinitely for each one. It is therefore advised
392
+ not to use ``burst() `` with an :class: `IMAP4_stream ` connection on
393
+ Windows.
351
394
352
395
353
396
.. method :: IMAP4.list([directory[, pattern]])
@@ -655,62 +698,6 @@ The following attributes are defined on instances of :class:`IMAP4`:
655
698
.. versionadded :: 3.5
656
699
657
700
658
- .. _idle context manager :
659
-
660
- IDLE Context Manager
661
- --------------------
662
-
663
- The object returned by :meth: `IMAP4.idle ` implements the context management
664
- protocol for the :keyword: `with ` statement, and the :term: `iterator ` protocol
665
- for retrieving untagged responses while the context is active.
666
- It also has the following method:
667
-
668
- .. method :: IdleContextManager.burst([interval])
669
-
670
- Yield a burst of responses no more than *interval * seconds apart.
671
-
672
- This generator retrieves the next response along with any
673
- immediately available subsequent responses (e.g. a rapid series of
674
- ``EXPUNGE `` responses after a bulk delete) so they can be efficiently
675
- processed as a batch instead of one at a time.
676
-
677
- The optional *interval * argument specifies a time limit (in seconds)
678
- for each response after the first. It defaults to 0.1 seconds.
679
- (The ``IDLE `` context's maximum duration is respected when waiting for the
680
- first response.)
681
-
682
- Represents responses as ``(type, datum) `` tuples, just as when
683
- iterating directly on the context manager.
684
-
685
- Example::
686
-
687
- with M.idle() as idler:
688
-
689
- # get the next response and any others following by < 0.1 seconds
690
- batch = list(idler.burst())
691
-
692
- print(f'processing {len(batch)} responses...')
693
- for typ, datum in batch:
694
- print(typ, datum)
695
-
696
- Produces no responses and returns immediately if the ``IDLE `` context's
697
- maximum duration (the *dur * argument to :meth: `IMAP4.idle `) has elapsed.
698
- Callers should plan accordingly if using this method in a loop.
699
-
700
- .. note ::
701
-
702
- Windows :class: `IMAP4_stream ` connections will ignore the *interval *
703
- argument, yielding endless responses and blocking indefinitely for each
704
- one, since Windows ``select() `` only works on sockets. It is therefore
705
- advised not to use this method with an :class: `IMAP4_stream ` connection
706
- on Windows.
707
-
708
- .. note ::
709
-
710
- The context manager's type name is not part of its public interface,
711
- and is subject to change.
712
-
713
-
714
701
.. _imap4-example :
715
702
716
703
IMAP4 Example
0 commit comments