Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
Description
Test program based on a SO question; press Ctrl-C after "coro stop" and before "thread stop":
import asyncioimport timeasync def main(): print("coro start") loop = asyncio.get_running_loop() loop.run_in_executor(None, blocking) await asyncio.sleep(1.0) print("coro stop")def blocking(): print("thread start") time.sleep(3.0) print("thread stop")try: asyncio.run(main())except KeyboardInterrupt: print("interrupted!")
The output is as expected:
coro startthread startcoro stop^Cinterrupted!thread stop
but a stack trace is printed to stderr:
exception calling callback for <Future at 0x7fb3e38bc0a0 state=finished returned NoneType>Traceback (most recent call last): File "/usr/lib64/python3.10/concurrent/futures/_base.py", line 342, in _invoke_callbacks callback(self) File "/usr/lib64/python3.10/asyncio/futures.py", line 399, in _call_set_state dest_loop.call_soon_threadsafe(_set_state, destination, source) File "/usr/lib64/python3.10/asyncio/base_events.py", line 795, in call_soon_threadsafe self._check_closed() File "/usr/lib64/python3.10/asyncio/base_events.py", line 515, in _check_closed raise RuntimeError('Event loop is closed')RuntimeError: Event loop is closedException in thread Thread-1 (_do_shutdown):Traceback (most recent call last): File "/usr/lib64/python3.10/asyncio/base_events.py", line 576, in _do_shutdown self.call_soon_threadsafe(future.set_result, None) File "/usr/lib64/python3.10/asyncio/base_events.py", line 795, in call_soon_threadsafe self._check_closed() File "/usr/lib64/python3.10/asyncio/base_events.py", line 515, in _check_closed raise RuntimeError('Event loop is closed')RuntimeError: Event loop is closedDuring handling of the above exception, another exception occurred:Traceback (most recent call last): File "/usr/lib64/python3.10/threading.py", line 1016, in _bootstrap_inner self.run() File "/usr/lib64/python3.10/threading.py", line 953, in run self._target(*self._args, **self._kwargs) File "/usr/lib64/python3.10/asyncio/base_events.py", line 578, in _do_shutdown self.call_soon_threadsafe(future.set_exception, ex) File "/usr/lib64/python3.10/asyncio/base_events.py", line 795, in call_soon_threadsafe self._check_closed() File "/usr/lib64/python3.10/asyncio/base_events.py", line 515, in _check_closed raise RuntimeError('Event loop is closed')RuntimeError: Event loop is closed
The interrupt occurs inasyncio.run
at line 49 in the fileasyncio/runners.py
39 loop = events.new_event_loop() 40 try: 41 events.set_event_loop(loop) 42 if debug is not None: 43 loop.set_debug(debug) 44 return loop.run_until_complete(main) 45 finally: 46 try: 47 _cancel_all_tasks(loop) 48 loop.run_until_complete(loop.shutdown_asyncgens()) 49 loop.run_until_complete(loop.shutdown_default_executor()) 50 finally: 51 events.set_event_loop(None) 52 loop.close()
The control returns to the main program (except KeyboardInterrupt
), but the cleanup waits
until the spawned thread terminates and at that time the event loop is closed and theRuntimeError
occurs.
In my opinion, noRuntimeError
should happen. Given that the entire user's program is guarded bytry-except
which successfully catches theKeyboardInterrupt
, there is very little a programmer
can do to avoid this situation maybe except suppressing the output by redirecting the stderr to /dev/null.
Your environment
Python 3.10
Metadata
Metadata
Assignees
Labels
Projects
Status