https://github.com/python/cpython/commit/f5f50593ad80cab01b942d407f46d216644c5e84
commit: f5f50593ad80cab01b942d407f46d216644c5e84
branch: main
author: Timofei <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-07-26T10:26:24+05:30
summary:
gh-154695: fix asyncio.Task eager_start=True with no explicit loop (#154697)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-07-25-17-35-14.gh-issue-154695.aQWLLv.rst
M Lib/test/test_asyncio/test_tasks.py
M Modules/_asynciomodule.c
diff --git a/Lib/test/test_asyncio/test_tasks.py
b/Lib/test/test_asyncio/test_tasks.py
index 609ccdbfdb2b28..110cd0936c007c 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -2733,6 +2733,18 @@ async def main():
self.assertEqual(name, "example")
await t
+ def test_eager_start_true_no_loop(self):
+ # gh-154695: eager_start must use the resolved loop, not loop=None.
+ async def asyncfn():
+ return 42
+
+ async def main():
+ t = self.__class__.Task(asyncfn(), eager_start=True)
+ self.assertTrue(t.done())
+ self.assertEqual(await t, 42)
+
+ asyncio.run(main(), loop_factory=asyncio.EventLoop)
+
def test_eager_start_false(self):
name = None
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-25-17-35-14.gh-issue-154695.aQWLLv.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-25-17-35-14.gh-issue-154695.aQWLLv.rst
new file mode 100644
index 00000000000000..6e147cf7f31a88
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-25-17-35-14.gh-issue-154695.aQWLLv.rst
@@ -0,0 +1,2 @@
+Fix :class:`asyncio.Task` raising :exc:`AttributeError` when created with
+``eager_start=True`` and no explicit *loop* argument.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 9c29eb8232ed3f..0cd41d0b4c4d0d 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2364,7 +2364,9 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject
*coro, PyObject *loop,
_PyObject_SetMaybeWeakref((PyObject *)self);
#endif
if (eager_start) {
- PyObject *res = PyObject_CallMethodNoArgs(loop, &_Py_ID(is_running));
+ // gh-154695: loop may be None here, future_init() resolved it into
task_loop.
+ PyObject *res = PyObject_CallMethodNoArgs(self->task_loop,
+ &_Py_ID(is_running));
if (res == NULL) {
return -1;
}
_______________________________________________
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]