@@ -867,19 +867,50 @@ Waiting Primitives
867867
868868.. function :: as_completed(aws, *, timeout=None)
869869
870- Run :ref: `awaitable objects <asyncio-awaitables >` in the *aws *
871- iterable concurrently. Return an iterator of coroutines.
872- Each coroutine returned can be awaited to get the earliest next
873- result from the iterable of the remaining awaitables.
874-
875- Raises :exc: `TimeoutError ` if the timeout occurs before
876- all Futures are done.
877-
878- Example::
879-
880- for coro in as_completed(aws):
881- earliest_result = await coro
882- # ...
870+ Run :ref: `awaitable objects <asyncio-awaitables >` in the *aws * iterable
871+ concurrently. The returned object can be iterated to obtain the results
872+ of the awaitables as they finish.
873+
874+ The object returned by ``as_completed() `` can be iterated as an
875+ :term: `asynchronous iterator ` or a plain :term: `iterator `. When asynchronous
876+ iteration is used, the originally-supplied awaitables are yielded if they
877+ are tasks or futures. This makes it easy to correlate previously-scheduled
878+ tasks with their results. Example::
879+
880+ ipv4_connect = create_task(open_connection("127.0.0.1", 80))
881+ ipv6_connect = create_task(open_connection("::1", 80))
882+ tasks = [ipv4_connect, ipv6_connect]
883+
884+ async for earliest_connect in as_completed(tasks):
885+ # earliest_connect is done. The result can be obtained by
886+ # awaiting it or calling earliest_connect.result()
887+ reader, writer = await earliest_connect
888+
889+ if earliest_connect is ipv6_connect:
890+ print("IPv6 connection established.")
891+ else:
892+ print("IPv4 connection established.")
893+
894+ During asynchronous iteration, implicitly-created tasks will be yielded for
895+ supplied awaitables that aren't tasks or futures.
896+
897+ When used as a plain iterator, each iteration yields a new coroutine that
898+ returns the result or raises the exception of the next completed awaitable.
899+ This pattern is compatible with Python versions older than 3.13::
900+
901+ ipv4_connect = create_task(open_connection("127.0.0.1", 80))
902+ ipv6_connect = create_task(open_connection("::1", 80))
903+ tasks = [ipv4_connect, ipv6_connect]
904+
905+ for next_connect in as_completed(tasks):
906+ # next_connect is not one of the original task objects. It must be
907+ # awaited to obtain the result value or raise the exception of the
908+ # awaitable that finishes next.
909+ reader, writer = await next_connect
910+
911+ A :exc: `TimeoutError ` is raised if the timeout occurs before all awaitables
912+ are done. This is raised by the ``async for `` loop during asynchronous
913+ iteration or by the coroutines yielded during plain iteration.
883914
884915 .. versionchanged :: 3.10
885916 Removed the *loop * parameter.
@@ -891,6 +922,10 @@ Waiting Primitives
891922 .. versionchanged :: 3.12
892923 Added support for generators yielding tasks.
893924
925+ .. versionchanged :: 3.13
926+ The result can now be used as either an :term: `asynchronous iterator `
927+ or as a plain :term: `iterator ` (previously it was only a plain iterator).
928+
894929
895930Running in Threads
896931==================
0 commit comments