Refactor AsyncIter to use 3.6+ asynchronous generators

This commit is contained in:
Kaylynn Morgan
2022-02-20 13:58:13 +11:00
committed by GitHub
parent dc19c6c7d5
commit 588cda0996
8 changed files with 386 additions and 930 deletions

View File

@ -2614,135 +2614,6 @@ of :class:`enum.Enum`.
The guild may contain NSFW content.
Async Iterator
----------------
Some API functions return an "async iterator". An async iterator is something that is
capable of being used in an :ref:`async for statement <py:async for>`.
These async iterators can be used as follows: ::
async for elem in channel.history():
# do stuff with elem here
Certain utilities make working with async iterators easier, detailed below.
.. class:: AsyncIterator
Represents the "AsyncIterator" concept. Note that no such class exists,
it is purely abstract.
.. container:: operations
.. describe:: async for x in y
Iterates over the contents of the async iterator.
.. method:: next()
:async:
|coro|
Advances the iterator by one, if possible. If no more items are found
then this raises :exc:`NoMoreItems`.
.. method:: get(**attrs)
:async:
|coro|
Similar to :func:`utils.get` except run over the async iterator.
Getting the last message by a user named 'Dave' or ``None``: ::
msg = await channel.history().get(author__name='Dave')
.. method:: find(predicate)
:async:
|coro|
Similar to :func:`utils.find` except run over the async iterator.
Unlike :func:`utils.find`\, the predicate provided can be a
|coroutine_link|_.
Getting the last audit log with a reason or ``None``: ::
def predicate(event):
return event.reason is not None
event = await guild.audit_logs().find(predicate)
:param predicate: The predicate to use. Could be a |coroutine_link|_.
:return: The first element that returns ``True`` for the predicate or ``None``.
.. method:: flatten()
:async:
|coro|
Flattens the async iterator into a :class:`list` with all the elements.
:return: A list of every element in the async iterator.
:rtype: list
.. method:: chunk(max_size)
Collects items into chunks of up to a given maximum size.
Another :class:`AsyncIterator` is returned which collects items into
:class:`list`\s of a given size. The maximum chunk size must be a positive integer.
.. versionadded:: 1.6
Collecting groups of users: ::
async for leader, *users in reaction.users().chunk(3):
...
.. warning::
The last chunk collected may not be as large as ``max_size``.
:param max_size: The size of individual chunks.
:rtype: :class:`AsyncIterator`
.. method:: map(func)
This is similar to the built-in :func:`map <py:map>` function. Another
:class:`AsyncIterator` is returned that executes the function on
every element it is iterating over. This function can either be a
regular function or a |coroutine_link|_.
Creating a content iterator: ::
def transform(message):
return message.content
async for content in channel.history().map(transform):
message_length = len(content)
:param func: The function to call on every element. Could be a |coroutine_link|_.
:rtype: :class:`AsyncIterator`
.. method:: filter(predicate)
This is similar to the built-in :func:`filter <py:filter>` function. Another
:class:`AsyncIterator` is returned that filters over the original
async iterator. This predicate can be a regular function or a |coroutine_link|_.
Getting messages by non-bot accounts: ::
def predicate(message):
return not message.author.bot
async for elem in channel.history().filter(predicate):
...
:param predicate: The predicate to call on every element. Could be a |coroutine_link|_.
:rtype: :class:`AsyncIterator`
.. _discord-api-audit-logs:
Audit Log Data