https://github.com/python/cpython/commit/d07dcce6935364cab807e0df931ed09b088ade69
commit: d07dcce6935364cab807e0df931ed09b088ade69
branch: main
author: Nico-Posada <[email protected]>
committer: sobolevn <[email protected]>
date: 2024-10-31T10:47:57+03:00
summary:
gh-126083: Fix a reference leak in `asyncio.Task` when reinitializing with new
non-`None` context (#126103)
files:
A Misc/NEWS.d/next/Library/2024-10-28-22-35-22.gh-issue-126083.TuI--n.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 a1013ab803348d..9d2d356631b42c 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -2688,6 +2688,28 @@ def test_get_context(self):
finally:
loop.close()
+ def test_proper_refcounts(self):
+ # see: https://github.com/python/cpython/issues/126083
+ class Break:
+ def __str__(self):
+ raise RuntimeError("break")
+
+ obj = object()
+ initial_refcount = sys.getrefcount(obj)
+
+ coro = coroutine_function()
+ loop = asyncio.new_event_loop()
+ task = asyncio.Task.__new__(asyncio.Task)
+
+ for _ in range(5):
+ with self.assertRaisesRegex(RuntimeError, 'break'):
+ task.__init__(coro, loop=loop, context=obj, name=Break())
+
+ coro.close()
+ del task
+
+ self.assertEqual(sys.getrefcount(obj), initial_refcount)
+
def add_subclass_tests(cls):
BaseTask = cls.Task
diff --git
a/Misc/NEWS.d/next/Library/2024-10-28-22-35-22.gh-issue-126083.TuI--n.rst
b/Misc/NEWS.d/next/Library/2024-10-28-22-35-22.gh-issue-126083.TuI--n.rst
new file mode 100644
index 00000000000000..d64b7dd2fedbd6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-10-28-22-35-22.gh-issue-126083.TuI--n.rst
@@ -0,0 +1 @@
+Fixed a reference leak in :class:`asyncio.Task` objects when reinitializing
the same object with a non-``None`` context. Patch by Nico Posada.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index d4135f04e56575..c2500fbd692d4d 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2120,7 +2120,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject
*coro, PyObject *loop,
return -1;
}
} else {
- self->task_context = Py_NewRef(context);
+ Py_XSETREF(self->task_context, Py_NewRef(context));
}
Py_CLEAR(self->task_fut_waiter);
_______________________________________________
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]