Below is a small example of something that I need to do in a much more involved, real-world form. I need my program to close in an orderly fashion, shutting down connections cleanly, if a keyboard interrupt (^C) is pressed. But as the results below show, the keyboard interrupt isn't being caught. The "finally" works but the "except" doesn't. And if I catch it at the main level instead of where my try statement is, I will no longer have the context of my function to display the information I might like to display.
Is there a better way to do this?
async def tryAsynchronous():
count = 0
try:
while True:
count = count + 1
print(count)
await asyncio.sleep(1)
except KeyboardInterrupt as e:
print("interrupt", count)
finally:
print("final count", count)
asyncio.run(tryAsynchronous())
Here are the results, when I press control-C after the third count:
% python3 kbint.py
1
2
3
^Cfinal count 3
Traceback (most recent call last):
File "/Users/ken/thermo/py/test/kbint.py", line 45, in <module>
asyncio.run(tryAsynchronous())
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 629, in run_until_complete
self.run_forever()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 596, in run_forever
self._run_once()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 1854, in _run_once
event_list = self._selector.select(timeout)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/selectors.py", line 562, in select
kev_list = self._selector.control(None, max_ev, timeout)
KeyboardInterrupt