mirror of https://github.com/python/cpython
gh-126083: Fix a reference leak in `asyncio.Task` when reinitializing with new non-`None` context (#126103)
This commit is contained in:
parent
d467d9246c
commit
d07dcce693
|
@ -2688,6 +2688,28 @@ class BaseTaskTests:
|
||||||
finally:
|
finally:
|
||||||
loop.close()
|
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):
|
def add_subclass_tests(cls):
|
||||||
BaseTask = cls.Task
|
BaseTask = cls.Task
|
||||||
|
|
|
@ -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.
|
|
@ -2120,7 +2120,7 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->task_context = Py_NewRef(context);
|
Py_XSETREF(self->task_context, Py_NewRef(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_CLEAR(self->task_fut_waiter);
|
Py_CLEAR(self->task_fut_waiter);
|
||||||
|
|
Loading…
Reference in New Issue