https://github.com/python/cpython/commit/ac00bf0e96d93adf20879217dc7022c7c3a5dc89
commit: ac00bf0e96d93adf20879217dc7022c7c3a5dc89
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: sobolevn <[email protected]>
date: 2024-10-31T08:14:00Z
summary:

[3.13] gh-126083: Fix a reference leak in `asyncio.Task` when reinitializing 
with new non-`None` context (GH-126103) (#126229)

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 5b09c81faef62a..313eed9d715158 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -2684,6 +2684,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 c47b921d72ae3a..44529f633fbe2e 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2070,7 +2070,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]

Reply via email to