asyncio-dangling-task (RUF006)#
What it does#
Checks for asyncio.create_task
and asyncio.ensure_future
calls
that do not store a reference to the returned result.
Why is this bad?#
Per the asyncio
documentation, the event loop only retains a weak
reference to tasks. If the task returned by asyncio.create_task
and
asyncio.ensure_future
is not stored in a variable, or a collection,
or otherwise referenced, it may be garbage collected at any time. This
can lead to unexpected and inconsistent behavior, as your tasks may or
may not run to completion.
Example#
import asyncio
for i in range(10):
# This creates a weak reference to the task, which may be garbage
# collected at any time.
asyncio.create_task(some_coro(param=i))
Use instead:
import asyncio
background_tasks = set()
for i in range(10):
task = asyncio.create_task(some_coro(param=i))
# Add task to the set. This creates a strong reference.
background_tasks.add(task)
# To prevent keeping references to finished tasks forever,
# make each task remove its own reference from the set after
# completion:
task.add_done_callback(background_tasks.discard)