Bug report
Bug description:
I discovered this while working on #126080. If the func is given a context that isn't None, instead of doing Py_XSETREF it'll just do a regular assignment meaning that whatever was there before wont have its reference count decreased.
| } else { | |
| self->task_context = Py_NewRef(context); | |
| } |
import asyncio import sys # for convenience so I dont have to set up everything else for a Task obj # and can just focus on the ref leak class Break: def __str__(self): raise Exception("break") async def coro(): pass task = asyncio.Task.__new__(asyncio.Task) co = coro() obj = object() print("refcount before bug", sys.getrefcount(obj)) for _ in range(10000): try: task.__init__(co, context=obj, name=Break()) except: pass print("refcount after bug", sys.getrefcount(obj))
Output
refcount before bug 2
refcount after bug 10002
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
- gh-126083: Fix a reference leak in
asyncio.Taskwhen reinitializing with new non-Nonecontext #126103 - [3.13] gh-126083: Fix a reference leak in
asyncio.Taskwhen reinitializing with new non-Nonecontext (GH-126103) #126229 - [3.12] gh-126083: Fix a reference leak in
asyncio.Taskwhen reinitializing with new non-Nonecontext (GH-126103) #126230