Skip to content

asyncio: interrupting run_until_complete makes the next run stop early #158406

Description

@tjkuson

Bug report

Bug description:

Interrupting loop.run_until_complete() after its future is done means that the next run of the same loop can stop after one iteration. If the future of that run is not done by then, loop.run_until_complete() raises RuntimeError: Event loop stopped before Future completed.

import asyncio
import signal

async def amain():
    asyncio.get_running_loop().call_soon(signal.raise_signal, signal.SIGINT)

loop = asyncio.new_event_loop()
try:
    loop.run_until_complete(amain())
except KeyboardInterrupt:
    pass
loop.run_until_complete(asyncio.sleep(0))

The above raises RuntimeError. The expected behaviour is that no error is raised.

If I understand correctly, this is due to the callback that stops the loop being missed by remove_done_callback() and thus deferred to the next iteration of the loop due to the timing of the signal.

Thus, this also affects asyncio.run() which runs the loop again during shutdown.

import asyncio
import signal

async def amain():
    asyncio.create_task(asyncio.sleep(1))
    asyncio.get_running_loop().call_soon(signal.raise_signal, signal.SIGINT)

asyncio.run(amain())

This raises RuntimeError. The expected behaviour is that KeyboardInterrupt is raised.

gh-66619 and gh-74608 related to similar cases.

CPython versions tested on:

3.15, 3.14, 3.13, 3.11, 3.12, 3.10, CPython main branch

Operating systems tested on:

macOS

Linked PRs

Activity

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

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions