MCPcopy Index your code
hub / github.com/python/cpython / shield

Function shield

Lib/asyncio/tasks.py:930–1004  ·  view source on GitHub ↗

Wait for a future, shielding it from cancellation. The statement task = asyncio.create_task(something()) res = await shield(task) is exactly equivalent to the statement res = await something() *except* that if the coroutine containing it is cancelled, the

(arg)

Source from the content-addressed store, hash-verified

928
929
930def shield(arg):
931 """Wait for a future, shielding it from cancellation.
932
933 The statement
934
935 task = asyncio.create_task(something())
936 res = await shield(task)
937
938 is exactly equivalent to the statement
939
940 res = await something()
941
942 *except* that if the coroutine containing it is cancelled, the
943 task running in something() is not cancelled. From the POV of
944 something(), the cancellation did not happen. But its caller is
945 still cancelled, so the yield-from expression still raises
946 CancelledError. Note: If something() is cancelled by other means
947 this will still cancel shield().
948
949 If you want to completely ignore cancellation (not recommended)
950 you can combine shield() with a try/except clause, as follows:
951
952 task = asyncio.create_task(something())
953 try:
954 res = await shield(task)
955 except CancelledError:
956 res = None
957
958 Save a reference to tasks passed to this function, to avoid
959 a task disappearing mid-execution. The event loop only keeps
960 weak references to tasks. A task that isn't referenced elsewhere
961 may get garbage collected at any time, even before it's done.
962 """
963 inner = ensure_future(arg)
964 if inner.done():
965 # Shortcut.
966 return inner
967 loop = futures._get_loop(inner)
968 outer = loop.create_future()
969
970 if loop is not None and (cur_task := current_task(loop)) is not None:
971 futures.future_add_to_awaited_by(inner, cur_task)
972 else:
973 cur_task = None
974
975 def _clear_awaited_by_callback(inner):
976 futures.future_discard_from_awaited_by(inner, cur_task)
977
978 def _inner_done_callback(inner):
979 if outer.cancelled():
980 return
981
982 if inner.cancelled():
983 outer.cancel()
984 else:
985 exc = inner.exception()
986 if exc is not None:
987 outer.set_exception(exc)

Callers

nothing calls this directly

Calls 6

ensure_futureFunction · 0.85
current_taskFunction · 0.85
_get_loopMethod · 0.80
doneMethod · 0.45
create_futureMethod · 0.45
add_done_callbackMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…