From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Sat, 10 Sep 2022 14:57:44 +0000 (-0700) Subject: gh-94972: document that shield users need to keep a reference to their task (GH-96724) X-Git-Tag: v3.10.8~136 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9b710581a3c59bf8c92e27cd9da5d3b9750587fe;p=thirdparty%2FPython%2Fcpython.git gh-94972: document that shield users need to keep a reference to their task (GH-96724) Co-authored-by: Thomas Grainger Co-authored-by: Guido van Rossum (cherry picked from commit 6281affee6423296893b509cd78dc563ca58b196) Co-authored-by: Hendrik Makait --- diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst index 7426e8291e14..412304ab6148 100644 --- a/Doc/library/asyncio-future.rst +++ b/Doc/library/asyncio-future.rst @@ -55,7 +55,7 @@ Future Functions preferred way for creating new Tasks. Save a reference to the result of this function, to avoid - a task disappearing mid execution. + a task disappearing mid-execution. .. versionchanged:: 3.5.1 The function accepts any :term:`awaitable` object. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index e535a5bf0425..8f9cef727463 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -262,9 +262,9 @@ Creating Tasks .. important:: Save a reference to the result of this function, to avoid - a task disappearing mid execution. The event loop only keeps + a task disappearing mid-execution. The event loop only keeps weak references to tasks. A task that isn't referenced elsewhere - may get garbage-collected at any time, even before it's done. + may get garbage collected at any time, even before it's done. For reliable "fire-and-forget" background tasks, gather them in a collection:: @@ -441,7 +441,8 @@ Shielding From Cancellation The statement:: - res = await shield(something()) + task = asyncio.create_task(something()) + res = await shield(task) is equivalent to:: @@ -460,11 +461,19 @@ Shielding From Cancellation the ``shield()`` function should be combined with a try/except clause, as follows:: + task = asyncio.create_task(something()) try: - res = await shield(something()) + res = await shield(task) except CancelledError: res = None + .. important:: + + Save a reference to tasks passed to this function, to avoid + a task disappearing mid-execution. The event loop only keeps + weak references to tasks. A task that isn't referenced elsewhere + may get garbage collected at any time, even before it's done. + .. versionchanged:: 3.10 Removed the *loop* parameter. diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index c4bedb5c72b0..f391586d1287 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -809,7 +809,8 @@ def shield(arg): The statement - res = await shield(something()) + task = asyncio.create_task(something()) + res = await shield(task) is exactly equivalent to the statement @@ -825,10 +826,16 @@ def shield(arg): If you want to completely ignore cancellation (not recommended) you can combine shield() with a try/except clause, as follows: + task = asyncio.create_task(something()) try: - res = await shield(something()) + res = await shield(task) except CancelledError: res = None + + Save a reference to tasks passed to this function, to avoid + a task disappearing mid-execution. The event loop only keeps + weak references to tasks. A task that isn't referenced elsewhere + may get garbage collected at any time, even before it's done. """ inner = _ensure_future(arg) if inner.done():