mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 11:13:34 +00:00
Handle KeyboardInterrupts in the cli better (#1391)
Addresses an issue with how `asyncclick` deals with `KeyboardInterrupt` errors. Instead of the `click.main` receiving `KeyboardInterrupt` it receives `CancelledError` because it's a task running inside the loop. Also ensures that discovery catches the `CancelledError` and closes the http clients.
This commit is contained in:
parent
fe88b52e19
commit
296af3192e
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from functools import singledispatch, update_wrapper, wraps
|
from functools import singledispatch, update_wrapper, wraps
|
||||||
|
from gettext import gettext
|
||||||
from typing import TYPE_CHECKING, Any, Final
|
from typing import TYPE_CHECKING, Any, Final
|
||||||
|
|
||||||
import asyncclick as click
|
import asyncclick as click
|
||||||
@ -238,4 +240,19 @@ def CatchAllExceptions(cls):
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
_handle_exception(self._debug, exc)
|
_handle_exception(self._debug, exc)
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
"""Run the coroutine in the event loop and print any exceptions.
|
||||||
|
|
||||||
|
python click catches KeyboardInterrupt in main, raises Abort()
|
||||||
|
and does sys.exit. asyncclick doesn't properly handle a coroutine
|
||||||
|
receiving CancelledError on a KeyboardInterrupt, so we catch the
|
||||||
|
KeyboardInterrupt here once asyncio.run has re-raised it. This
|
||||||
|
avoids large stacktraces when a user presses Ctrl-C.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
asyncio.run(self.main(*args, **kwargs))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
click.echo(gettext("\nAborted!"), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
return _CommandCls
|
return _CommandCls
|
||||||
|
@ -498,7 +498,7 @@ class Discover:
|
|||||||
try:
|
try:
|
||||||
_LOGGER.debug("Waiting %s seconds for responses...", discovery_timeout)
|
_LOGGER.debug("Waiting %s seconds for responses...", discovery_timeout)
|
||||||
await protocol.wait_for_discovery_to_complete()
|
await protocol.wait_for_discovery_to_complete()
|
||||||
except KasaException as ex:
|
except (KasaException, asyncio.CancelledError) as ex:
|
||||||
for device in protocol.discovered_devices.values():
|
for device in protocol.discovered_devices.values():
|
||||||
await device.protocol.close()
|
await device.protocol.close()
|
||||||
raise ex
|
raise ex
|
||||||
|
Loading…
Reference in New Issue
Block a user