From ae591633eca1414c4c1aa06a81e8154cee20efd7 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Wed, 22 Jul 2026 02:11:39 +0300 Subject: [PATCH] Replace deprecated MultiCommand with Group, default to status command - Use click.Group instead of the deprecated click.MultiCommand - Invoke status automatically when no subcommand is specified --- miio/click_common.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/miio/click_common.py b/miio/click_common.py index a0d25b3ab..534ed2691 100644 --- a/miio/click_common.py +++ b/miio/click_common.py @@ -157,7 +157,7 @@ def supported_models(cls) -> list[str]: return list(cls._mappings.keys()) or cls._supported_models -class DeviceGroup(click.MultiCommand): +class DeviceGroup(click.Group): class Command: def __init__(self, name, decorators, *, default_output=None, **kwargs): self.name = name @@ -238,8 +238,8 @@ def __init__( result_callback_pass_device=True, **attrs, ): - self.commands = getattr(device_class, "_device_group_commands", None) - if self.commands is None: + device_commands = getattr(device_class, "_device_group_commands", None) + if device_commands is None: raise RuntimeError( "Class {} doesn't use DeviceGroupMeta meta class." " It can't be used with DeviceGroup." @@ -248,6 +248,10 @@ def __init__( self.device_class = device_class self.device_pass = click.make_pass_decorator(device_class) + # Default to running status instead of showing help when called with no subcommand. + if no_args_is_help is None and "status" in device_commands: + no_args_is_help = False + attrs.setdefault("params", self.DEFAULT_PARAMS) attrs.setdefault("callback", click.pass_context(self.group_callback)) if result_callback_pass_device and callable(result_callback): @@ -263,6 +267,9 @@ def __init__( **attrs, ) + # Preserve our command dict, which click.Group resets in __init__ + self.commands = device_commands + def group_callback(self, ctx, *args, **kwargs): gco = ctx.find_object(GlobalContextObject) if gco: @@ -282,6 +289,11 @@ def _save_cache() -> None: ctx.call_on_close(_save_cache) + def invoke(self, ctx): + if not ctx._protected_args and not ctx.args and "status" in self.commands: + ctx._protected_args = ["status"] + return super().invoke(ctx) + def command_callback(self, miio_command, miio_device, *args, **kwargs): return miio_command.call(miio_device, *args, **kwargs)