Skip to content

asyncio.TaskGroup swallows cancellations coming from outside of it #155433

Description

@deadlovelll

Bug report

Bug description:

After tg.cancel() taskgroup silently swallows any cancellation requested from outside it

Repro:

import asyncio

async def worker():
    try:
        await asyncio.sleep(3600)
    finally:
        await asyncio.sleep(1)

async def main():
    async with asyncio.timeout(0.5):
        async with asyncio.TaskGroup() as tg:
            tg.create_task(worker())
            await asyncio.sleep(0.1)
            tg.cancel()
    print("no error")

asyncio.run(main())

Expected output:

raise TimeoutError from exc_val
TimeoutError

But actually:

no error

Proposed fix - add else branch: if uncancel() leaves requests pending, cancellation was not ours, so we need to propogate it

        if self._parent_cancel_requested:
            # If this flag is set we *must* call uncancel().
            if self._parent_task.uncancel() == 0:
                # If there are no pending cancellations left,
                # don't propagate CancelledError.
                propagate_cancellation_error = None
            else:
                propagate_cancellation_error = exceptions.CancelledError()

Have a fix ready

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-asynciotype-bugAn unexpected behavior, bug, or error

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions