@@ -282,6 +282,24 @@ Creating Tasks
282282 Added the *context * parameter.
283283
284284
285+ Task Cancellation
286+ =================
287+
288+ Tasks can easily and safely be cancelled.
289+ When a task is cancelled, :exc: `asyncio.CancelledError ` will be raised
290+ in the task at the next opportunity.
291+
292+ It is recommended that coroutines use ``try/finally `` blocks to robustly
293+ perform clean-up logic. In case :exc: `asyncio.CancelledError `
294+ is explicitly caught, it should generally be propagated when
295+ clean-up is complete. Most code can safely ignore :exc: `asyncio.CancelledError `.
296+
297+ Important asyncio components, like :class: `asyncio.TaskGroup ` and the
298+ :func: `asyncio.timeout ` context manager, are implemented using cancellation
299+ internally and might misbehave if a coroutine swallows
300+ :exc: `asyncio.CancelledError `.
301+
302+
285303Task Groups
286304===========
287305
@@ -537,6 +555,122 @@ Shielding From Cancellation
537555Timeouts
538556========
539557
558+ .. coroutinefunction :: timeout(delay)
559+
560+ An :ref: `asynchronous context manager <async-context-managers >`
561+ that can be used to limit the amount of time spent waiting on
562+ something.
563+
564+ *delay * can either be ``None ``, or a float/int number of
565+ seconds to wait. If *delay * is ``None ``, no time limit will
566+ be applied; this can be useful if the delay is unknown when
567+ the context manager is created.
568+
569+ In either case, the context manager can be rescheduled after
570+ creation using :meth: `Timeout.reschedule `.
571+
572+ Example::
573+
574+ async def main():
575+ async with asyncio.timeout(10):
576+ await long_running_task()
577+
578+ If ``long_running_task `` takes more than 10 seconds to complete,
579+ the context manager will cancel the current task and handle
580+ the resulting :exc: `asyncio.CancelledError ` internally, transforming it
581+ into an :exc: `asyncio.TimeoutError ` which can be caught and handled.
582+
583+ .. note ::
584+
585+ The :func: `asyncio.timeout ` context manager is what transforms
586+ the :exc: `asyncio.CancelledError ` into an :exc: `asyncio.TimeoutError `,
587+ which means the :exc: `asyncio.TimeoutError ` can only be caught
588+ *outside * of the context manager.
589+
590+ Example of catching :exc: `asyncio.TimeoutError `::
591+
592+ async def main():
593+ try:
594+ async with asyncio.timeout(10):
595+ await long_running_task()
596+ except TimeoutError:
597+ print("The long operation timed out, but we've handled it.")
598+
599+ print("This statement will run regardless.")
600+
601+ The context manager produced by :func: `asyncio.timeout ` can be
602+ rescheduled to a different deadline and inspected.
603+
604+ .. class :: Timeout()
605+
606+ An :ref: `asynchronous context manager <async-context-managers >`
607+ that limits time spent inside of it.
608+
609+ .. versionadded :: 3.11
610+
611+ .. method :: when() -> float | None
612+
613+ Return the current deadline, or ``None `` if the current
614+ deadline is not set.
615+
616+ The deadline is a float, consistent with the time returned by
617+ :meth: `loop.time `.
618+
619+ .. method :: reschedule(when: float | None)
620+
621+ Change the time the timeout will trigger.
622+
623+ If *when * is `None `, any current deadline will be removed, and the
624+ context manager will wait indefinitely.
625+
626+ If *when * is a float, it is set as the new deadline.
627+
628+ .. method :: expired() -> bool
629+
630+ Return whether the context manager has exceeded its deadline
631+ (expired).
632+
633+ Example::
634+
635+ async def main():
636+ try:
637+ # We do not know the timeout when starting, so we pass ``None``.
638+ async with asyncio.timeout(None) as cm:
639+ # We know the timeout now, so we reschedule it.
640+ new_deadline = get_running_loop().time() + 10
641+ cm.reschedule(new_deadline)
642+
643+ await long_running_task()
644+ except TimeoutError:
645+ pass
646+
647+ if cm.expired:
648+ print("Looks like we haven't finished on time.")
649+
650+ Timeout context managers can be safely nested.
651+
652+ .. versionadded :: 3.11
653+
654+ .. coroutinefunction :: timeout_at(when)
655+
656+ Similar to :func: `asyncio.timeout `, except *when * is the absolute time
657+ to stop waiting, or ``None ``.
658+
659+ Example::
660+
661+ async def main():
662+ loop = get_running_loop()
663+ deadline = loop.time() + 20
664+ try:
665+ async with asyncio.timeout_at(deadline):
666+ await long_running_task()
667+ except TimeoutError:
668+ print("The long operation timed out, but we've handled it.")
669+
670+ print("This statement will run regardless.")
671+
672+ .. versionadded :: 3.11
673+
540674.. coroutinefunction :: wait_for(aw, timeout)
541675
542676 Wait for the *aw * :ref: `awaitable <asyncio-awaitables >`
0 commit comments