https://github.com/python/cpython/commit/b12fcffdb153d992e665510e23bfaa14519de56c
commit: b12fcffdb153d992e665510e23bfaa14519de56c
branch: main
author: Aslan Osmanov <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-10-20T17:22:03+05:30
summary:
gh-157856: Fix `asyncio.as_completed()` outside a running event loop (#157857)
files:
A Misc/NEWS.d/next/Library/2026-09-20-12-00-00.gh-issue-157856.wq4xuF.rst
M Lib/asyncio/tasks.py
M Lib/test/test_asyncio/test_tasks.py
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 33284288a7cca7..1baa7518692d8a 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -578,7 +578,13 @@ def __init__(self, aws, timeout):
self._timeout_handle = None
loop = events.get_event_loop()
- self._cur_task = current_task()
+ # The iterator may be created outside of a running event loop and
+ # then driven with loop.run_until_complete(), in which case there
+ # is no current task to record as the waiter.
+ if events._get_running_loop() is loop:
+ self._cur_task = current_task(loop)
+ else:
+ self._cur_task = None
todo = {ensure_future(aw, loop=loop) for aw in set(aws)}
for f in todo:
f.add_done_callback(self._handle_completion)
diff --git a/Lib/test/test_asyncio/test_tasks.py
b/Lib/test/test_asyncio/test_tasks.py
index 95e1f760123b88..c93e0e7b6a4004 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -1803,6 +1803,22 @@ async def coro():
futs = asyncio.as_completed([a])
list(futs)
+ def test_as_completed_outside_running_loop(self):
+ # gh-157856: as_completed() must not require a running event loop
+ # when the iterator is created, only when it is driven.
+ loop = self.new_test_loop()
+ self.addCleanup(asyncio.set_event_loop, None)
+ asyncio.set_event_loop(loop)
+
+ async def coro(v):
+ await asyncio.sleep(0)
+ return v
+
+ tasks = [loop.create_task(coro(v)) for v in (1, 2)]
+ futs = asyncio.as_completed(tasks)
+ results = [loop.run_until_complete(f) for f in futs]
+ self.assertEqual(sorted(results), [1, 2])
+
def test_as_completed_coroutine_use_running_loop(self):
loop = self.new_test_loop()
diff --git
a/Misc/NEWS.d/next/Library/2026-09-20-12-00-00.gh-issue-157856.wq4xuF.rst
b/Misc/NEWS.d/next/Library/2026-09-20-12-00-00.gh-issue-157856.wq4xuF.rst
new file mode 100644
index 00000000000000..9f221fa657d429
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-09-20-12-00-00.gh-issue-157856.wq4xuF.rst
@@ -0,0 +1,3 @@
+Fix :func:`asyncio.as_completed` raising :exc:`RuntimeError` ("no running
+event loop") when the iterator is created outside of a running event loop and
+driven with :meth:`loop.run_until_complete()
<asyncio.loop.run_until_complete>`.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]