mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-09 20:24:02 +00:00
Enable ruff check for ANN (#1139)
This commit is contained in:
@@ -7,7 +7,7 @@ import re
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from functools import singledispatch, update_wrapper, wraps
|
||||
from typing import Final
|
||||
from typing import TYPE_CHECKING, Any, Callable, Final
|
||||
|
||||
import asyncclick as click
|
||||
|
||||
@@ -37,7 +37,7 @@ except ImportError:
|
||||
"""Strip rich formatting from messages."""
|
||||
|
||||
@wraps(echo_func)
|
||||
def wrapper(message=None, *args, **kwargs):
|
||||
def wrapper(message=None, *args, **kwargs) -> None:
|
||||
if message is not None:
|
||||
message = rich_formatting.sub("", message)
|
||||
echo_func(message, *args, **kwargs)
|
||||
@@ -47,20 +47,20 @@ except ImportError:
|
||||
_echo = _strip_rich_formatting(click.echo)
|
||||
|
||||
|
||||
def echo(*args, **kwargs):
|
||||
def echo(*args, **kwargs) -> None:
|
||||
"""Print a message."""
|
||||
ctx = click.get_current_context().find_root()
|
||||
if "json" not in ctx.params or ctx.params["json"] is False:
|
||||
_echo(*args, **kwargs)
|
||||
|
||||
|
||||
def error(msg: str):
|
||||
def error(msg: str) -> None:
|
||||
"""Print an error and exit."""
|
||||
echo(f"[bold red]{msg}[/bold red]")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def json_formatter_cb(result, **kwargs):
|
||||
def json_formatter_cb(result: Any, **kwargs) -> None:
|
||||
"""Format and output the result as JSON, if requested."""
|
||||
if not kwargs.get("json"):
|
||||
return
|
||||
@@ -82,7 +82,7 @@ def json_formatter_cb(result, **kwargs):
|
||||
print(json_content)
|
||||
|
||||
|
||||
def pass_dev_or_child(wrapped_function):
|
||||
def pass_dev_or_child(wrapped_function: Callable) -> Callable:
|
||||
"""Pass the device or child to the click command based on the child options."""
|
||||
child_help = (
|
||||
"Child ID or alias for controlling sub-devices. "
|
||||
@@ -133,7 +133,10 @@ def pass_dev_or_child(wrapped_function):
|
||||
|
||||
|
||||
async def _get_child_device(
|
||||
device: Device, child_option, child_index_option, info_command
|
||||
device: Device,
|
||||
child_option: str | None,
|
||||
child_index_option: int | None,
|
||||
info_command: str | None,
|
||||
) -> Device | None:
|
||||
def _list_children():
|
||||
return "\n".join(
|
||||
@@ -178,11 +181,15 @@ async def _get_child_device(
|
||||
f"{child_option} children are:\n{_list_children()}"
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
assert isinstance(child_index_option, int)
|
||||
|
||||
if child_index_option + 1 > len(device.children) or child_index_option < 0:
|
||||
error(
|
||||
f"Invalid index {child_index_option}, "
|
||||
f"device has {len(device.children)} children"
|
||||
)
|
||||
|
||||
child_by_index = device.children[child_index_option]
|
||||
echo(f"Targeting child device {child_by_index.alias}")
|
||||
return child_by_index
|
||||
@@ -195,7 +202,7 @@ def CatchAllExceptions(cls):
|
||||
https://stackoverflow.com/questions/52213375
|
||||
"""
|
||||
|
||||
def _handle_exception(debug, exc):
|
||||
def _handle_exception(debug, exc) -> None:
|
||||
if isinstance(exc, click.ClickException):
|
||||
raise
|
||||
# Handle exit request from click.
|
||||
|
@@ -22,7 +22,7 @@ from .common import (
|
||||
|
||||
@click.group()
|
||||
@pass_dev_or_child
|
||||
def device(dev):
|
||||
def device(dev) -> None:
|
||||
"""Commands to control basic device settings."""
|
||||
|
||||
|
||||
|
@@ -36,7 +36,7 @@ async def detail(ctx):
|
||||
auth_failed = []
|
||||
sem = asyncio.Semaphore()
|
||||
|
||||
async def print_unsupported(unsupported_exception: UnsupportedDeviceError):
|
||||
async def print_unsupported(unsupported_exception: UnsupportedDeviceError) -> None:
|
||||
unsupported.append(unsupported_exception)
|
||||
async with sem:
|
||||
if unsupported_exception.discovery_result:
|
||||
@@ -50,7 +50,7 @@ async def detail(ctx):
|
||||
|
||||
from .device import state
|
||||
|
||||
async def print_discovered(dev: Device):
|
||||
async def print_discovered(dev: Device) -> None:
|
||||
async with sem:
|
||||
try:
|
||||
await dev.update()
|
||||
@@ -189,7 +189,7 @@ async def config(ctx):
|
||||
error(f"Unable to connect to {host}")
|
||||
|
||||
|
||||
def _echo_dictionary(discovery_info: dict):
|
||||
def _echo_dictionary(discovery_info: dict) -> None:
|
||||
echo("\t[bold]== Discovery information ==[/bold]")
|
||||
for key, value in discovery_info.items():
|
||||
key_name = " ".join(x.capitalize() or "_" for x in key.split("_"))
|
||||
@@ -197,7 +197,7 @@ def _echo_dictionary(discovery_info: dict):
|
||||
echo(f"\t{key_name_and_spaces}{value}")
|
||||
|
||||
|
||||
def _echo_discovery_info(discovery_info):
|
||||
def _echo_discovery_info(discovery_info) -> None:
|
||||
# We don't have discovery info when all connection params are passed manually
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
@@ -24,7 +24,7 @@ def _echo_features(
|
||||
category: Feature.Category | None = None,
|
||||
verbose: bool = False,
|
||||
indent: str = "\t",
|
||||
):
|
||||
) -> None:
|
||||
"""Print out a listing of features and their values."""
|
||||
if category is not None:
|
||||
features = {
|
||||
@@ -43,7 +43,9 @@ def _echo_features(
|
||||
echo(f"{indent}{feat.name} ({feat.id}): [red]got exception ({ex})[/red]")
|
||||
|
||||
|
||||
def _echo_all_features(features, *, verbose=False, title_prefix=None, indent=""):
|
||||
def _echo_all_features(
|
||||
features, *, verbose=False, title_prefix=None, indent=""
|
||||
) -> None:
|
||||
"""Print out all features by category."""
|
||||
if title_prefix is not None:
|
||||
echo(f"[bold]\n{indent}== {title_prefix} ==[/bold]")
|
||||
|
@@ -3,6 +3,8 @@
|
||||
Taken from the click help files.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
|
||||
import asyncclick as click
|
||||
@@ -11,7 +13,7 @@ import asyncclick as click
|
||||
class LazyGroup(click.Group):
|
||||
"""Lazy group class."""
|
||||
|
||||
def __init__(self, *args, lazy_subcommands=None, **kwargs):
|
||||
def __init__(self, *args, lazy_subcommands=None, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
# lazy_subcommands is a map of the form:
|
||||
#
|
||||
@@ -31,9 +33,9 @@ class LazyGroup(click.Group):
|
||||
return self._lazy_load(cmd_name)
|
||||
return super().get_command(ctx, cmd_name)
|
||||
|
||||
def format_commands(self, ctx, formatter):
|
||||
def format_commands(self, ctx, formatter) -> None:
|
||||
"""Format the top level help output."""
|
||||
sections = {}
|
||||
sections: dict[str, list] = {}
|
||||
for cmd, parent in self.lazy_subcommands.items():
|
||||
sections.setdefault(parent, [])
|
||||
cmd_obj = self.get_command(ctx, cmd)
|
||||
|
@@ -15,7 +15,7 @@ from .common import echo, error, pass_dev_or_child
|
||||
|
||||
@click.group()
|
||||
@pass_dev_or_child
|
||||
def light(dev):
|
||||
def light(dev) -> None:
|
||||
"""Commands to control light settings."""
|
||||
|
||||
|
||||
|
@@ -43,7 +43,7 @@ ENCRYPT_TYPES = [encrypt_type.value for encrypt_type in DeviceEncryptionType]
|
||||
DEFAULT_TARGET = "255.255.255.255"
|
||||
|
||||
|
||||
def _legacy_type_to_class(_type):
|
||||
def _legacy_type_to_class(_type: str) -> Any:
|
||||
from kasa.iot import (
|
||||
IotBulb,
|
||||
IotDimmer,
|
||||
@@ -396,9 +396,9 @@ async def cli(
|
||||
|
||||
@cli.command()
|
||||
@pass_dev_or_child
|
||||
async def shell(dev: Device):
|
||||
async def shell(dev: Device) -> None:
|
||||
"""Open interactive shell."""
|
||||
echo("Opening shell for %s" % dev)
|
||||
echo(f"Opening shell for {dev}")
|
||||
from ptpython.repl import embed
|
||||
|
||||
logging.getLogger("parso").setLevel(logging.WARNING) # prompt parsing
|
||||
|
@@ -14,7 +14,7 @@ from .common import (
|
||||
|
||||
@click.group()
|
||||
@pass_dev
|
||||
async def schedule(dev):
|
||||
async def schedule(dev) -> None:
|
||||
"""Scheduling commands."""
|
||||
|
||||
|
||||
|
@@ -23,7 +23,7 @@ from .common import (
|
||||
|
||||
@click.group(invoke_without_command=True)
|
||||
@click.pass_context
|
||||
async def time(ctx: click.Context):
|
||||
async def time(ctx: click.Context) -> None:
|
||||
"""Get and set time."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.invoke(time_get)
|
||||
|
@@ -78,13 +78,13 @@ async def energy(dev: Device, year, month, erase):
|
||||
else:
|
||||
emeter_status = dev.emeter_realtime
|
||||
|
||||
echo("Current: %s A" % emeter_status["current"])
|
||||
echo("Voltage: %s V" % emeter_status["voltage"])
|
||||
echo("Power: %s W" % emeter_status["power"])
|
||||
echo("Total consumption: %s kWh" % emeter_status["total"])
|
||||
echo("Current: {} A".format(emeter_status["current"]))
|
||||
echo("Voltage: {} V".format(emeter_status["voltage"]))
|
||||
echo("Power: {} W".format(emeter_status["power"]))
|
||||
echo("Total consumption: {} kWh".format(emeter_status["total"]))
|
||||
|
||||
echo("Today: %s kWh" % dev.emeter_today)
|
||||
echo("This month: %s kWh" % dev.emeter_this_month)
|
||||
echo(f"Today: {dev.emeter_today} kWh")
|
||||
echo(f"This month: {dev.emeter_this_month} kWh")
|
||||
|
||||
return emeter_status
|
||||
|
||||
@@ -122,8 +122,8 @@ async def usage(dev: Device, year, month, erase):
|
||||
usage_data = await usage.get_daystat(year=month.year, month=month.month)
|
||||
else:
|
||||
# Call with no argument outputs summary data and returns
|
||||
echo("Today: %s minutes" % usage.usage_today)
|
||||
echo("This month: %s minutes" % usage.usage_this_month)
|
||||
echo(f"Today: {usage.usage_today} minutes")
|
||||
echo(f"This month: {usage.usage_this_month} minutes")
|
||||
|
||||
return usage
|
||||
|
||||
|
@@ -16,7 +16,7 @@ from .common import (
|
||||
|
||||
@click.group()
|
||||
@pass_dev
|
||||
def wifi(dev):
|
||||
def wifi(dev) -> None:
|
||||
"""Commands to control wifi settings."""
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user