镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Add a cancelling_pending async context manager #39

Description

@llucax

What's needed?

Sometimes it is useful to ensure any pending futures will be cancelled after some block of code.

Proposed solution

@asynccontextmanager
async def cancelling_pending(*futures: Future[Any]):
    try:
        yield
    finally:
        for future in futures:
            if not future.done():
                future.cancel()
                try:
                    await future
                except asyncio.CancelledError:
                    pass

Example usage:

class Timer:
    ...
    async def ready() -> None:
        ...
        while time_to_next_tick > 0:
            tasks = [
                asyncio.create_task(asyncio.sleep(time_to_next_tick)),
                asyncio.create_task(self._reset_event.wait()),
            ]
            async with cancelling_pending(tasks):
                await next(asyncio.as_completed(tasks))
            self._reset_event.clear()
            now = self._now()
            time_to_next_tick = self._next_tick_time - now

Use cases

Alternatives and workarounds

            _, pending = await asyncio.wait(
                [
                    asyncio.create_task(asyncio.sleep(time_to_next_tick)),
                    asyncio.create_task(self._reset_event.wait()),
                ],
                return_when=asyncio.FIRST_COMPLETED,
            )
            for task in pending:
                task.cancel()
                try:
                    await task
                except asyncio.CancelledError:
                    pass

Additional context

No response

Activity

  1. added this to the v1.0.0 milestone on Nov 19, 2024
  2. modified the milestones: v1.0.0, Untriaged on Jun 6, 2025
  3. added
    status:blockedOther issues must be resolved before this can be worked on
    on Jun 6, 2025
  4. llucax commented on Jun 6, 2025

    @llucax
    ContributorAuthor

    Blocking because we need to rethink how we are doing tasks in general.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    part:asyncioAffects the asyncio modulestatus:blockedOther issues must be resolved before this can be worked ontype:enhancementNew feature or enhancement visitble to users

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions