Skip to content

Commit 90de322

Browse files
[3.12] pythongh-126083: Fix a reference leak in asyncio.Task when reinitializing with new non-None context (pythonGH-126103) (python#126230)
pythongh-126083: Fix a reference leak in `asyncio.Task` when reinitializing with new non-`None` context (pythonGH-126103) (cherry picked from commit d07dcce) Co-authored-by: Nico-Posada <[email protected]>
1 parent 9759118 commit 90de322

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Lib/test/test_asyncio/test_tasks.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,6 +2489,28 @@ def test_get_context(self):
24892489
finally:
24902490
loop.close()
24912491

2492+
def test_proper_refcounts(self):
2493+
# see: https://github.com/python/cpython/issues/126083
2494+
class Break:
2495+
def __str__(self):
2496+
raise RuntimeError("break")
2497+
2498+
obj = object()
2499+
initial_refcount = sys.getrefcount(obj)
2500+
2501+
coro = coroutine_function()
2502+
loop = asyncio.new_event_loop()
2503+
task = asyncio.Task.__new__(asyncio.Task)
2504+
2505+
for _ in range(5):
2506+
with self.assertRaisesRegex(RuntimeError, 'break'):
2507+
task.__init__(coro, loop=loop, context=obj, name=Break())
2508+
2509+
coro.close()
2510+
del task
2511+
2512+
self.assertEqual(sys.getrefcount(obj), initial_refcount)
2513+
24922514

24932515
def add_subclass_tests(cls):
24942516
BaseTask = cls.Task
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a reference leak in :class:`asyncio.Task` objects when reinitializing the same object with a non-``None`` context. Patch by Nico Posada.

Modules/_asynciomodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2143,7 +2143,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
21432143
return -1;
21442144
}
21452145
} else {
2146-
self->task_context = Py_NewRef(context);
2146+
Py_XSETREF(self->task_context, Py_NewRef(context));
21472147
}
21482148

21492149
Py_CLEAR(self->task_fut_waiter);

0 commit comments

Comments
 (0)