diff --git a/discord/iterators.py b/discord/iterators.py
index 34dcd4126..514316511 100644
--- a/discord/iterators.py
+++ b/discord/iterators.py
@@ -62,6 +62,11 @@ class _AsyncIterator:
if ret:
return elem
+ def chunk(self, max_size):
+ if max_size <= 0:
+ raise ValueError('async iterator chunk sizes must be greater than 0.')
+ return _ChunkedAsyncIterator(self, max_size)
+
def map(self, func):
return _MappedAsyncIterator(self, func)
@@ -92,6 +97,26 @@ class _AsyncIterator:
def _identity(x):
return x
+class _ChunkedAsyncIterator(_AsyncIterator):
+ def __init__(self, iterator, max_size):
+ self.iterator = iterator
+ self.max_size = max_size
+
+ async def next(self):
+ ret = []
+ n = 0
+ while n < self.max_size:
+ try:
+ item = await self.iterator.next()
+ except NoMoreItems:
+ if ret:
+ return ret
+ raise
+ else:
+ ret.append(item)
+ n += 1
+ return ret
+
class _MappedAsyncIterator(_AsyncIterator):
def __init__(self, iterator, func):
self.iterator = iterator
diff --git a/docs/api.rst b/docs/api.rst
index 6790f3959..892e175ef 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -2085,6 +2085,26 @@ Certain utilities make working with async iterators easier, detailed below.
: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