You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
asyncio.create_task() documentation should mention user needs to keep reference to the task #88831
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2021-07-18.06:01:26.261>labels= ['3.11', 'type-feature', '3.9', '3.10', 'docs']
title='asyncio.create_task() documentation should mention user needs to keep reference to the task'updated_at=<Date2022-01-06.08:53:46.602>user='https://github.com/vincentbernat'
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"?
Here is my answer for anyone wondering how to reproduce this issue (as their code works just fine without keeping a reference to the tasks). I tried to explain what I understood:
Only the last one will work. The two other ones don't keep a reference on the tasks after the coro() function ends.
But when the coro() function ends, all the tasks created inside coro() are done, so I don't need to keep the references anymore, right?
Maybe I should have clarified that I call the await inside the same coro() function.
So like:
asyncdefcoro():
task1=asyncio.create_task(...)
task2=asyncio.create_task(...)
task3=asyncio.create_task(...)
task4=asyncio.create_task(...)
awaittask1awaittask2awaittask3awaittask4# all the tasks are done and coro() ends
In this case, would it work? Do I even need to keep the references task1, task2, etc or can I do directly away asyncio.create_task(...) without risking my tasks to be garbage collected before they are done?
asyncdefcoro():
awaitasyncio.create_task(...)
awaitasyncio.create_task(...)
awaitasyncio.create_task(...)
awaitasyncio.create_task(...)
# all the tasks are done and coro() ends
Thanks for the help.
Editing this post to avoid creating more noise:
I don't think this issue should be a support forum.
Agree but the documentation was updated following this issue and the wording is confusing. As you can see in the previous comments and in mine, it raises a lot of questions. The doc suggests to keep references of the tasks in any case, while apparently is not always necessary (like in my example).
Is there any reason why the event loop should not keep strong reference to the task until the task is completed?
-- never mind, this is being discussed already here: #91887
Activity
vincentbernat commentedon Jul 18, 2021
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"?
The same applies to ensure_future as it now uses create_task, so maybe a "See create_task()".
nanjekyejoannah commentedon Oct 22, 2021
@bernat and ncoghlan, please see if the wording I have used in the linked PR helps to clarify this.
cmeyer commentedon Oct 22, 2021
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).
22 remaining items
Ensure we hold strong references to tasks
Ensure we hold strong references to tasks
util.CallbackManager: keep strong references for running futures
util.CallbackManager: keep strong references for running futures
amirsoroush commentedon Aug 5, 2023
Here is my answer for anyone wondering how to reproduce this issue (as their code works just fine without keeping a reference to the tasks). I tried to explain what I understood:
https://stackoverflow.com/a/76823668/13944524
util.CallbackManager: keep strong references for running futures
util.CallbackManager: keep strong references for running futures
util.CallbackManager: keep strong references for running futures
ggregoire commentedon Feb 28, 2024
@vincentbernat just to clarify, since I'm not that familiar with the intricacies of Python's garbage collector.
Is this enough (in the context of this issue) to keep a reference of the task like this?
Or is it really needed to keep them in a collection?
If so, can the collection be declared inside the coroutine? Or does it need to be outside to be a "strong" reference?
vs.
Just trying to keep the code as simple as possible.
vincentbernat commentedon Feb 28, 2024
Only the last one will work. The two other ones don't keep a reference on the tasks after the coro() function ends.
ggregoire commentedon Feb 28, 2024
But when the coro() function ends, all the tasks created inside coro() are done, so I don't need to keep the references anymore, right?
Maybe I should have clarified that I call the
awaitinside the same coro() function.So like:
In this case, would it work? Do I even need to keep the references
task1,task2, etc or can I do directlyaway asyncio.create_task(...)without risking my tasks to be garbage collected before they are done?Thanks for the help.
Editing this post to avoid creating more noise:
Agree but the documentation was updated following this issue and the wording is confusing. As you can see in the previous comments and in mine, it raises a lot of questions. The doc suggests to keep references of the tasks in any case, while apparently is not always necessary (like in my example).
I appreciate the help anyway. Thanks.
vincentbernat commentedon Feb 28, 2024
I don't think this issue should be a support forum. But yes, both ways are fine (but they don't do the same thing).
[BugFix] Prevent the task of `_force_log` from being garbage collected
pkch commentedon Oct 20, 2024
Is there any reason why the event loop should not keep strong reference to the task until the task is completed?-- never mind, this is being discussed already here: #91887
util.CallbackManager: keep strong references for running futures