Skip to content

CancelScope shielding fails to protect against cancellation until task_status.started is called on asyncio #837

Open
@tapetersen

Description

@tapetersen

Things to check first

  • I have searched the existing issues and didn't find my bug already reported there

  • I have checked that my bug is still present in the latest release

AnyIO version

4.7.0

Python version

3.10

What happened?

Running some quite involved code that needs to do shielded cleanup if it fails sometime exits a shielded scope due to cancellation of the host-task calling TaskGroup.start before the child-task has called task_status.started()

I know these are edge cases and may also be really hard to solve so feel free to resolve as such.

How can we reproduce the bug?

I've managed to reduce it to the following test-case.

async def test_anyio_cancel_shielding_start():
    entered_inner_scope = anyio.Event()
    async with (
        anyio.create_task_group() as tg,
        anyio.create_task_group() as inner_tg,
    ):
        async def inner_task(*, task_status: anyio.abc.TaskStatus = anyio.TASK_STATUS_IGNORED):
            # task_status.started() # Uncommenting this lets the task hang forever instead

            with anyio.CancelScope(shield=True):
                entered_inner_scope.set()
                try:
                    await anyio.sleep_forever()
                except anyio.get_cancelled_exc_class():
                    assert False, "Shouldn't be cancelled in a shielded scope"

        async def start_inner_task():
            await inner_tg.start(inner_task)

        tg.start_soon(start_inner_task)
        await entered_inner_scope.wait()
        tg.cancel_scope.cancel()



if __name__ == "__main__":
    anyio.run(test_anyio_cancel_shielding_start)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions