https://github.com/python/cpython/commit/90de322b32a72c69afafa2fb879676923357cf3a commit: 90de322b32a72c69afafa2fb879676923357cf3a branch: 3.12 author: Miss Islington (bot) <[email protected]> committer: sobolevn <[email protected]> date: 2024-10-31T08:19:56Z summary:
[3.12] gh-126083: Fix a reference leak in `asyncio.Task` when reinitializing with new non-`None` context (GH-126103) (#126230) gh-126083: Fix a reference leak in `asyncio.Task` when reinitializing with new non-`None` context (GH-126103) (cherry picked from commit d07dcce6935364cab807e0df931ed09b088ade69) Co-authored-by: Nico-Posada <[email protected]> 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 6e8a51ce2555d5..792ab4fbede0a2 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2489,6 +2489,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 9016c077e0d657..96821762c5ae68 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2143,7 +2143,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]
