Issue 44665: asyncio.create_task() documentation should mention user needs to keep reference to the task
Created on 2021-07-18 06:01 by bernat, last changed 2022-04-11 14:59 by admin.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 29163 | merged | nanjekyejoannah, 2021-10-22 14:39 | |
| Messages (5) | |||
|---|---|---|---|
| msg397741 - (view) | Author: Vincent Bernat (bernat) * | Date: 2021-07-18 06:01 | |
asyncio will only keep weak references to alive tasks (in `_all_tasks`). If a user does not keep a reference to a task and the task is not currently executing or sleeping, the user may get "Task was destroyed but it is pending!". I would suggest adding the following paragraph to `create_task()` documentation: Python only keeps weak references to the scheduled tasks. To avoid the task being destroyed by the garbage collector while still pending, a reference to it should be kept until the task is done. And maybe an example in case a user wants something "fire and forget"? ```python running_tasks = set() # [...] task = asyncio.create_task(some_background_function()) running_tasks.add(task) task.add_done_callback(lambda t: running_tasks.remove(t)) ``` The same applies to ensure_future as it now uses create_task, so maybe a "See create_task()". |
|||
| msg404776 - (view) | Author: Joannah Nanjekye (nanjekyejoannah) * ![]() |
Date: 2021-10-22 14:40 | |
@bernat and ncoghlan, please see if the wording I have used in the linked PR helps to clarify this. |
|||
| msg404782 - (view) | Author: Chris Meyer (cmeyer) * | Date: 2021-10-22 15:27 | |
Is there a way to reproduce this issue? I run the following code in Python 3.9 and it works as expected (prints "xyz" twice).
import asyncio
import gc
async def xyz():
print("xyz")
event_loop = asyncio.get_event_loop()
event_loop.create_task(xyz())
t = event_loop.create_task(xyz())
del t
gc.collect()
event_loop.stop()
event_loop.run_forever()
|
|||
| msg404827 - (view) | Author: Vincent Bernat (bernat) * | Date: 2021-10-22 21:18 | |
Hummm, I have a hard time finding a short example when `__del__` is not called until the task is finished. Sorry. I did run into this several time, for example here: https://github.com/ldo/dbussy/pull/45 (and some internal projects as well). So, it happens from time to time, but it is hard to find a simple reproducer. |
|||
| msg409821 - (view) | Author: Alexander Hartl (alexhartl) | Date: 2022-01-06 08:53 | |
I just found this PR when a task of mine spontaneously crashed with a "Task was destroyed but it is pending" in the middle of program execution. I think the warning should be added to `loop.create_task()`, too. Not sure if `loop.call_later()` and `loop.call_at()` are also affected? I think it would be a good idea to add the fire-and-forget example that @bernat gave. At the moment, stackoverflow is full of suggestions to just use `create_task()` in this case, ignoring the return value. Actually, I think it is a true shortcoming that asyncio doesn't provide a fire-and forget functionality by itself. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:59:47 | admin | set | github: 88831 |
| 2022-01-06 08:53:46 | alexhartl | set | nosy:
+ alexhartl messages: + msg409821 |
| 2021-10-22 21:18:59 | bernat | set | messages: + msg404827 |
| 2021-10-22 15:27:20 | cmeyer | set | nosy:
+ cmeyer messages: + msg404782 |
| 2021-10-22 14:40:58 | nanjekyejoannah | set | messages:
+ msg404776 stage: patch review -> |
| 2021-10-22 14:39:29 | nanjekyejoannah | set | keywords:
+ patch nosy: + nanjekyejoannah pull_requests:
+ pull_request27437 |
| 2021-08-24 02:30:11 | ncoghlan | link | issue42538 superseder |
| 2021-07-18 06:01:26 | bernat | create | |
