|
10 | 10 | .. changes for IMAP4_SSL by Tino Lange <Tino.Lange@isg.de>, March 2002
|
11 | 11 | .. changes for IMAP4_stream by Piers Lauder <piers@communitysolutions.com.au>,
|
12 | 12 | November 2002
|
| 13 | +.. changes for IMAP4 IDLE by Forest <forestix@nom.one>, August 2024 |
13 | 14 |
|
14 | 15 | **Source code:** :source:`Lib/imaplib.py`
|
15 | 16 |
|
@@ -187,7 +188,7 @@ However, the *password* argument to the ``LOGIN`` command is always quoted. If
|
187 | 188 | you want to avoid having an argument string quoted (eg: the *flags* argument to
|
188 | 189 | ``STORE``) then enclose the string in parentheses (eg: ``r'(\Deleted)'``).
|
189 | 190 |
|
190 |
| -Each command returns a tuple: ``(type, [data, ...])`` where *type* is usually |
| 191 | +Most commands return a tuple: ``(type, [data, ...])`` where *type* is usually |
191 | 192 | ``'OK'`` or ``'NO'``, and *data* is either the text from the command response,
|
192 | 193 | or mandated results from the command. Each *data* is either a ``bytes``, or a
|
193 | 194 | tuple. If a tuple, then the first part is the header of the response, and the
|
@@ -307,6 +308,93 @@ An :class:`IMAP4` instance has the following methods:
|
307 | 308 | of the IMAP4 QUOTA extension defined in rfc2087.
|
308 | 309 |
|
309 | 310 |
|
| 311 | +.. method:: IMAP4.idle(duration=None) |
| 312 | + |
| 313 | + Return an :class:`!Idler`: an iterable context manager implementing the |
| 314 | + IMAP4 ``IDLE`` command as defined in :rfc:`2177`. |
| 315 | + |
| 316 | + The returned object 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 | + All untagged responses that arrive after sending the ``IDLE`` command |
| 321 | + (including any that arrive before the server acknowledges the command) will |
| 322 | + be available via iteration. Any leftover responses (those not iterated in |
| 323 | + the :keyword:`with` context) can be retrieved in the usual way after |
| 324 | + ``IDLE`` ends, using :meth:`IMAP4.response`. |
| 325 | + |
| 326 | + Responses are represented as ``(type, [data, ...])`` tuples, as described |
| 327 | + in :ref:`IMAP4 Objects <imap4-objects>`. |
| 328 | + |
| 329 | + The *duration* argument sets a maximum duration (in seconds) to keep idling, |
| 330 | + after which any ongoing iteration will stop. It can be an :class:`int` or |
| 331 | + :class:`float`, or ``None`` for no time limit. |
| 332 | + Callers wishing to avoid inactivity timeouts on servers that impose them |
| 333 | + should keep this at most 29 minutes (1740 seconds). |
| 334 | + Requires a socket connection; *duration* must be ``None`` on |
| 335 | + :class:`IMAP4_stream` connections. |
| 336 | + |
| 337 | + .. code-block:: pycon |
| 338 | +
|
| 339 | + >>> with M.idle(duration=29 * 60) as idler: |
| 340 | + ... for typ, data in idler: |
| 341 | + ... print(typ, data) |
| 342 | + ... |
| 343 | + EXISTS [b'1'] |
| 344 | + RECENT [b'1'] |
| 345 | +
|
| 346 | +
|
| 347 | + .. method:: Idler.burst(interval=0.1) |
| 348 | + |
| 349 | + Yield a burst of responses no more than *interval* seconds apart |
| 350 | + (expressed as an :class:`int` or :class:`float`). |
| 351 | + |
| 352 | + This :term:`generator` is an alternative to iterating one response at a |
| 353 | + time, intended to aid in efficient batch processing. It retrieves the |
| 354 | + next response along with any immediately available subsequent responses. |
| 355 | + (For example, a rapid series of ``EXPUNGE`` responses after a bulk |
| 356 | + delete.) |
| 357 | + |
| 358 | + Requires a socket connection; does not work on :class:`IMAP4_stream` |
| 359 | + connections. |
| 360 | + |
| 361 | + .. code-block:: pycon |
| 362 | +
|
| 363 | + >>> with M.idle() as idler: |
| 364 | + ... # get a response and any others following by < 0.1 seconds |
| 365 | + ... batch = list(idler.burst()) |
| 366 | + ... print(f'processing {len(batch)} responses...') |
| 367 | + ... print(batch) |
| 368 | + ... |
| 369 | + processing 3 responses... |
| 370 | + [('EXPUNGE', [b'2']), ('EXPUNGE', [b'1']), ('RECENT', [b'0'])] |
| 371 | +
|
| 372 | + .. tip:: |
| 373 | + |
| 374 | + The ``IDLE`` context's maximum duration, as passed to |
| 375 | + :meth:`IMAP4.idle`, is respected when waiting for the first response |
| 376 | + in a burst. Therefore, an expired :class:`!Idler` will cause this |
| 377 | + generator to return immediately without producing anything. Callers |
| 378 | + should consider this if using it in a loop. |
| 379 | + |
| 380 | + |
| 381 | + .. note:: |
| 382 | + |
| 383 | + The iterator returned by :meth:`IMAP4.idle` is usable only within a |
| 384 | + :keyword:`with` statement. Before or after that context, unsolicited |
| 385 | + responses are collected internally whenever a command finishes, and can |
| 386 | + be retrieved with :meth:`IMAP4.response`. |
| 387 | + |
| 388 | + .. note:: |
| 389 | + |
| 390 | + The :class:`!Idler` class name and structure are internal interfaces, |
| 391 | + subject to change. Calling code can rely on its context management, |
| 392 | + iteration, and public method to remain stable, but should not subclass, |
| 393 | + instantiate, compare, or otherwise directly reference the class. |
| 394 | + |
| 395 | + .. versionadded:: next |
| 396 | + |
| 397 | + |
310 | 398 | .. method:: IMAP4.list([directory[, pattern]])
|
311 | 399 |
|
312 | 400 | List mailbox names in *directory* matching *pattern*. *directory* defaults to
|
|
0 commit comments