Bug report
I don't have an actual failure to report: it's a potential issue I noticed while inspecting the code.
An asyncio.Runner on the main thread installs a SIGINT handler using signal.signal (and NOT loop.add_signal_handler for whatever reason). The signal handler could thus run at more-or-less any time and cannot rely on the asyncio machinery being in a consistent state. However, it directly interacts with the main task, calling main_task.done() and main_task.cancel():
def _on_sigint(self, signum, frame, main_task):
self._interrupt_count += 1
if self._interrupt_count == 1 and not main_task.done():
main_task.cancel()
# wakeup loop if it is blocked by select() with long timeout
self._loop.call_soon_threadsafe(lambda: None)
return
raise KeyboardInterrupt()
Task.cancel in particular seems like a complex piece of code that will depend on invariants, and that's before considering that one might have a user-provided event loop factory which in turn uses a custom task class.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Bug report
I don't have an actual failure to report: it's a potential issue I noticed while inspecting the code.
An asyncio.Runner on the main thread installs a SIGINT handler using
signal.signal(and NOTloop.add_signal_handlerfor whatever reason). The signal handler could thus run at more-or-less any time and cannot rely on the asyncio machinery being in a consistent state. However, it directly interacts with the main task, callingmain_task.done()andmain_task.cancel():Task.cancelin particular seems like a complex piece of code that will depend on invariants, and that's before considering that one might have a user-provided event loop factory which in turn uses a custom task class.CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux