From 63c9598528790eda5530d5d2cc7dd91e4964702c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:35:40 +0000 Subject: [PATCH 1/2] Initial plan From d56ba6aee485718cd4073132e0b3ea828bcaeb61 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 22:40:20 +0000 Subject: [PATCH 2/2] fix: restrict match_arg overload to str-only when several_ok=False The first overload previously accepted `str | Iterable[str]` for the `arg` parameter when `several_ok=False`, but passing an Iterable with `several_ok=False` raises ValueError at runtime. This change narrows the type to just `str` so the type system correctly reflects the runtime behavior, catching invalid calls at type-check time. Co-authored-by: nathanjmcdougall <18602289+nathanjmcdougall@users.noreply.github.com> --- src/ruru/base/matching.py | 4 +--- tests/ruru/base/test_matching.py | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ruru/base/matching.py b/src/ruru/base/matching.py index bac0410..ca40883 100644 --- a/src/ruru/base/matching.py +++ b/src/ruru/base/matching.py @@ -12,9 +12,7 @@ @overload -def match_arg( - arg: str | Iterable[str], choices: list[str], *, several_ok: Literal[False] = False -) -> str: ... +def match_arg(arg: str, choices: list[str], *, several_ok: Literal[False] = False) -> str: ... @overload def match_arg( arg: str | Iterable[str], choices: list[str], *, several_ok: Literal[True] diff --git a/tests/ruru/base/test_matching.py b/tests/ruru/base/test_matching.py index c0529e3..d7ccf3a 100644 --- a/tests/ruru/base/test_matching.py +++ b/tests/ruru/base/test_matching.py @@ -160,7 +160,7 @@ def test_match_arg_list_input_several_ok_false(self, standard_choices): """Test list input with several_ok=False raises error.""" error_msg = "Iterable input is only allowed when several_ok=True" with pytest.raises(ValueError, match=error_msg): - match_arg(["ban", "app"], standard_choices, several_ok=False) + match_arg(["ban", "app"], standard_choices, several_ok=False) # type: ignore[call-overload] def test_match_arg_list_with_ambiguous_element(self, partial_match_choices): """Test list with ambiguous element returns all matches when several_ok=True.""" @@ -233,7 +233,7 @@ def test_match_arg_tuple_input_several_ok_false(self, standard_choices): """Test tuple input with several_ok=False raises error.""" error_msg = "Iterable input is only allowed when several_ok=True" with pytest.raises(ValueError, match=error_msg): - match_arg(("ban", "app"), standard_choices, several_ok=False) + match_arg(("ban", "app"), standard_choices, several_ok=False) # type: ignore[call-overload] def test_match_arg_empty_tuple(self, standard_choices): """Test empty tuple input returns empty list."""