From 0932f30d06e514462892b1ce060b6f0e83fa1542 Mon Sep 17 00:00:00 2001 From: WolfGanG <169568318+wolfgang-aura@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:11:13 +0800 Subject: [PATCH] Strip multi-word rich tags when rich is not installed (#1807) Without `rich` installed, `kasa` prints tags like `[bold red]Only discover is available without --host or --alias[/bold red]` verbatim. The fallback in `kasa/cli/common.py` strips only single-word tags (`\[/?[a-z]+]`), and `error()` uses the two-word `[bold red]`. The pattern is changed to `\[/?[a-z]+(?: [a-z]+)*]`, so space-separated lowercase words are stripped too. --- kasa/cli/common.py | 2 +- tests/test_cli.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/kasa/cli/common.py b/kasa/cli/common.py index 4d6c4a5d..58927be1 100644 --- a/kasa/cli/common.py +++ b/kasa/cli/common.py @@ -34,7 +34,7 @@ except ImportError: # but only lower case tags to avoid stripping out # raw data from the device that is printed from # the device state. - rich_formatting = re.compile(r"\[/?[a-z]+]") + rich_formatting = re.compile(r"\[/?[a-z]+(?: [a-z]+)*]") def _strip_rich_formatting(echo_func): """Strip rich formatting from messages.""" diff --git a/tests/test_cli.py b/tests/test_cli.py index ca5b5525..11023d23 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,5 +1,7 @@ +import importlib.util import json import re +import sys from datetime import datetime from unittest.mock import ANY, PropertyMock, patch from zoneinfo import ZoneInfo @@ -1552,3 +1554,17 @@ async def test_discover_config_invalid( ) assert res.exit_code == 1 assert "--target is not a valid option for single host discovery" in res.output + + +def test_echo_strips_rich_tags_without_rich(monkeypatch, capsys): + """Multi-word rich tags are stripped when rich is not installed.""" + monkeypatch.setitem(sys.modules, "rich", None) + spec = importlib.util.find_spec("kasa.cli.common") + assert spec + assert spec.loader + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + module._echo("[bold red]Only discover is available[/bold red] [ABC]") + + assert capsys.readouterr().out == "Only discover is available [ABC]\n"