This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Inconsistent behavior with KeyboardInterrupt and asyncio futures
Type: behavior Stage:
Components: asyncio Versions: Python 3.5
process
Status: closed Resolution: third party
Dependencies: Superseder:
Assigned To: Nosy List: Michel Desmoulin, gvanrossum, mvolfik, yselivanov
Priority: normal Keywords:

Created on 2016-02-28 19:50 by Michel Desmoulin, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg260984 - (view) Author: Michel Desmoulin (Michel Desmoulin) Date: 2016-02-28 19:50
If you trigger KeyboardInterrupt in a coroutine and catch it, the program terminates cleanly:

import asyncio

async def bar():
    raise KeyboardInterrupt

loop = asyncio.get_event_loop()

try:
    loop.run_until_complete(bar())
except KeyboardInterrupt:
    print("It's ok")
finally:
    loop.stop()
    loop.close()


This outputs:

It's ok

However, if you wrap the coroutine in a Task, you will get a mixed behavior:

try:
    task = asyncio.ensure_future(bar())
    loop.run_until_complete(task)
except KeyboardInterrupt:
    print("It's ok")

This outputs:

It's ok
Task exception was never retrieved
future: <Task finished coro=<bar() done, defined at ki_bug.py:4> exception=KeyboardInterrupt()>
Traceback (most recent call last):
  File "ki_bug.py", line 10, in <module>
    loop.run_until_complete(main_future)
  File "/usr/lib/python3.5/asyncio/base_events.py", line 325, in run_until_complete
    self.run_forever()
  File "/usr/lib/python3.5/asyncio/base_events.py", line 295, in run_forever
    self._run_once()
  File "/usr/lib/python3.5/asyncio/base_events.py", line 1258, in _run_once
    handle._run()
  File "/usr/lib/python3.5/asyncio/events.py", line 125, in _run
    self._callback(*self._args)
  File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
    result = coro.send(None)
  File "ki_bug.py", line 5, in bar
    raise KeyboardInterrupt
KeyboardInterrupt

We have several contradictory behaviors: the KeyboardInterrupt is raised, and captured by the future (since your can do task.exception() to suppress the stracktrace) but also catched by except while the program is allowed to continue, yet still the stack trace is displayed and eventually the program return code will  be 0.

It's very confusing.
msg275380 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2016-09-09 18:41
Closing this issue in favor of the upstream one: https://github.com/python/asyncio/issues/341
msg386087 - (view) Author: Matej Volf (mvolfik) Date: 2021-02-01 18:09
python/asyncio is archived now and there is no definitive resolution, nor a concrete workaround in that thread. has this progressed elsewhere? or is it still unresolved?

could anyone please show sample workaround code? (i need to call some cleanup code which still runs in the context of the event loop)

---

also, I was unable to login to this bug tracker with GitHub, because my name contains non-ascii characters. where should I report that :D ?
msg386088 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-02-01 18:13
If you just need help, I recommend https://discuss.python.org/c/users/7

If you still have an issue with ^C, open a new issue.
History
Date User Action Args
2022-04-11 14:58:28adminsetgithub: 70642
2021-02-01 20:53:20vstinnersetnosy: - vstinner
2021-02-01 18:13:24gvanrossumsetmessages: + msg386088
2021-02-01 18:09:11mvolfiksetnosy: + mvolfik
messages: + msg386087
2016-09-09 18:41:34gvanrossumsetstatus: open -> closed
resolution: third party
messages: + msg275380
2016-02-28 19:50:26Michel Desmoulincreate