mirror of
https://github.com/python/cpython.git
synced 2026-03-31 09:01:19 +00:00
gh-55454: Clarify imaplib idle() docs
- Add example idle response tuples, to make the minor difference from other imaplib response tuples more obvious. - Merge the idle context manager's burst() method docs with the IMAP object's idle() method docs, for easier understanding. - Upgrade the Windows note regarding lack of pipe timeouts to a warning. - Rephrase various things for clarity.
This commit is contained in:
parent
572d1e5676
commit
dc71241eda
1 changed files with 65 additions and 78 deletions
|
|
@ -308,22 +308,28 @@ An :class:`IMAP4` instance has the following methods:
|
|||
of the IMAP4 QUOTA extension defined in rfc2087.
|
||||
|
||||
|
||||
.. method:: IMAP4.idle([dur])
|
||||
.. method:: IMAP4.idle(dur=None)
|
||||
|
||||
Return an iterable context manager implementing the ``IDLE`` command
|
||||
as defined in :rfc:`2177`.
|
||||
|
||||
The optional *dur* argument specifies a maximum duration (in seconds) to
|
||||
keep idling. It defaults to ``None``, meaning no time limit.
|
||||
To avoid inactivity timeouts on servers that impose them, callers are
|
||||
advised to keep this <= 29 minutes. See the note below regarding
|
||||
The context manager sends the ``IDLE`` command when activated by the
|
||||
:keyword:`with` statement, produces IMAP untagged responses via the
|
||||
:term:`iterator` protocol, and sends ``DONE`` upon context exit.
|
||||
|
||||
The *dur* argument sets a maximum duration (in seconds) to keep idling,
|
||||
after which iteration will stop. It defaults to ``None``, meaning no time
|
||||
limit. Callers wishing to avoid inactivity timeouts on servers that impose
|
||||
them should keep this <= 29 minutes.
|
||||
See the :ref:`warning below <windows-pipe-timeout-warning>` if using
|
||||
:class:`IMAP4_stream` on Windows.
|
||||
|
||||
The context manager sends the ``IDLE`` command upon entry, produces
|
||||
responses via iteration, and sends ``DONE`` upon exit.
|
||||
It represents responses as ``(type, datum)`` tuples, rather than the
|
||||
``(type, [data, ...])`` tuples returned by other methods, because only
|
||||
one response is represented at a time.
|
||||
Response tuples produced by the iterator almost exactly match those
|
||||
returned by other imaplib methods. The difference is that the tuple's
|
||||
second member is a single response datum, rather than a list of data.
|
||||
Therefore, in a mailbox where calling ``M.response('EXISTS')`` would
|
||||
return ``('EXISTS', [b'1'])``, the idle iterator would produce
|
||||
``('EXISTS', b'1')``.
|
||||
|
||||
Example::
|
||||
|
||||
|
|
@ -332,22 +338,59 @@ An :class:`IMAP4` instance has the following methods:
|
|||
typ, datum = response
|
||||
print(typ, datum)
|
||||
|
||||
It is also possible to process a burst of responses all at once instead
|
||||
of one at a time. See `IDLE Context Manager`_ for details.
|
||||
('EXISTS', b'1')
|
||||
('RECENT', b'1')
|
||||
|
||||
Responses produced by the iterator will not be returned by
|
||||
:meth:`IMAP4.response`.
|
||||
Instead of iterating one response at a time, it is also possible to retrieve
|
||||
the next response along with any immediately available subsequent responses
|
||||
(e.g. a rapid series of ``EXPUNGE`` events from a bulk delete). This
|
||||
batch processing aid is provided by the context's ``burst()``
|
||||
:term:`generator`:
|
||||
|
||||
.. note::
|
||||
.. method:: idler.burst(interval=0.1)
|
||||
|
||||
Yield a burst of responses no more than *interval* seconds apart.
|
||||
|
||||
Example::
|
||||
|
||||
with M.idle() as idler:
|
||||
|
||||
# get the next response and any others following by < 0.1 seconds
|
||||
batch = list(idler.burst())
|
||||
|
||||
print(f'processing {len(batch)} responses...')
|
||||
print(batch)
|
||||
|
||||
processing 3 responses...
|
||||
[('EXPUNGE', b'2'), ('EXPUNGE', b'1'), ('RECENT', b'0')]
|
||||
|
||||
The ``IDLE`` context's maximum duration (the *dur* argument to
|
||||
:meth:`IMAP4.idle`) is respected when waiting for the first response
|
||||
in a burst. Therefore, an expired idle context will cause this generator
|
||||
to return immediately without producing anything. Callers should
|
||||
consider this if using it in a loop.
|
||||
|
||||
|
||||
.. _windows-pipe-timeout-warning:
|
||||
|
||||
.. warning::
|
||||
|
||||
Windows :class:`IMAP4_stream` connections have no way to accurately
|
||||
respect *dur*, since Windows ``select()`` only works on sockets.
|
||||
However, if the server regularly sends status messages during ``IDLE``,
|
||||
they will wake our selector and keep iteration from blocking for long.
|
||||
Dovecot's ``imap_idle_notify_interval`` is two minutes by default.
|
||||
Assuming that's typical of IMAP servers, subtracting it from the 29
|
||||
minutes needed to avoid server inactivity timeouts would make 27
|
||||
minutes a sensible value for *dur* in this situation.
|
||||
respect the *dur* or *interval* arguments, since Windows ``select()``
|
||||
only works on sockets.
|
||||
|
||||
If the server regularly sends status messages during ``IDLE``, they will
|
||||
wake our iterator anyway, allowing *dur* to behave roughly as intended,
|
||||
although usually late. Dovecot's ``imap_idle_notify_interval`` default
|
||||
setting does this every 2 minutes. Assuming that's typical of IMAP
|
||||
servers, subtracting it from the 29 minutes needed to avoid server
|
||||
inactivity timeouts would make 27 minutes a sensible value for *dur* in
|
||||
this situation.
|
||||
|
||||
There is no such fallback for ``burst()``, which will yield endless
|
||||
responses and block indefinitely for each one. It is therefore advised
|
||||
not to use ``burst()`` with an :class:`IMAP4_stream` connection on
|
||||
Windows.
|
||||
|
||||
|
||||
.. method:: IMAP4.list([directory[, pattern]])
|
||||
|
|
@ -655,62 +698,6 @@ The following attributes are defined on instances of :class:`IMAP4`:
|
|||
.. versionadded:: 3.5
|
||||
|
||||
|
||||
.. _idle context manager:
|
||||
|
||||
IDLE Context Manager
|
||||
--------------------
|
||||
|
||||
The object returned by :meth:`IMAP4.idle` implements the context management
|
||||
protocol for the :keyword:`with` statement, and the :term:`iterator` protocol
|
||||
for retrieving untagged responses while the context is active.
|
||||
It also has the following method:
|
||||
|
||||
.. method:: IdleContextManager.burst([interval])
|
||||
|
||||
Yield a burst of responses no more than *interval* seconds apart.
|
||||
|
||||
This generator retrieves the next response along with any
|
||||
immediately available subsequent responses (e.g. a rapid series of
|
||||
``EXPUNGE`` responses after a bulk delete) so they can be efficiently
|
||||
processed as a batch instead of one at a time.
|
||||
|
||||
The optional *interval* argument specifies a time limit (in seconds)
|
||||
for each response after the first. It defaults to 0.1 seconds.
|
||||
(The ``IDLE`` context's maximum duration is respected when waiting for the
|
||||
first response.)
|
||||
|
||||
Represents responses as ``(type, datum)`` tuples, just as when
|
||||
iterating directly on the context manager.
|
||||
|
||||
Example::
|
||||
|
||||
with M.idle() as idler:
|
||||
|
||||
# get the next response and any others following by < 0.1 seconds
|
||||
batch = list(idler.burst())
|
||||
|
||||
print(f'processing {len(batch)} responses...')
|
||||
for typ, datum in batch:
|
||||
print(typ, datum)
|
||||
|
||||
Produces no responses and returns immediately if the ``IDLE`` context's
|
||||
maximum duration (the *dur* argument to :meth:`IMAP4.idle`) has elapsed.
|
||||
Callers should plan accordingly if using this method in a loop.
|
||||
|
||||
.. note::
|
||||
|
||||
Windows :class:`IMAP4_stream` connections will ignore the *interval*
|
||||
argument, yielding endless responses and blocking indefinitely for each
|
||||
one, since Windows ``select()`` only works on sockets. It is therefore
|
||||
advised not to use this method with an :class:`IMAP4_stream` connection
|
||||
on Windows.
|
||||
|
||||
.. note::
|
||||
|
||||
The context manager's type name is not part of its public interface,
|
||||
and is subject to change.
|
||||
|
||||
|
||||
.. _imap4-example:
|
||||
|
||||
IMAP4 Example
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue