From 90a7ce1014641a3a5c6e16f693f0086f69f78322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sun, 1 Mar 2026 19:56:53 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(metavar):=20render=20all=20t?= =?UTF-8?q?uple=20metavar=20elements=20and=20suppress=20None=20defaults?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tuple metavars (e.g. nargs=2 with metavar=("KEY", "VALUE")) only rendered the first element. Now all elements are joined with spaces. Additionally, arguments with default=None no longer display "(default: None)" since that adds no useful information. Fixes #159, fixes #177 --- roots/test-tuple-metavar/conf.py | 8 ++++++++ roots/test-tuple-metavar/index.rst | 3 +++ roots/test-tuple-metavar/parser.py | 10 ++++++++++ src/sphinx_argparse_cli/_logic.py | 8 +++++++- tests/complex.txt | 6 ++---- tests/complex_pre_310.txt | 6 ++---- tests/test_logic.py | 13 +++++++++++-- 7 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 roots/test-tuple-metavar/conf.py create mode 100644 roots/test-tuple-metavar/index.rst create mode 100644 roots/test-tuple-metavar/parser.py diff --git a/roots/test-tuple-metavar/conf.py b/roots/test-tuple-metavar/conf.py new file mode 100644 index 0000000..9f2a54a --- /dev/null +++ b/roots/test-tuple-metavar/conf.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent)) +extensions = ["sphinx_argparse_cli"] +nitpicky = True diff --git a/roots/test-tuple-metavar/index.rst b/roots/test-tuple-metavar/index.rst new file mode 100644 index 0000000..708ad9c --- /dev/null +++ b/roots/test-tuple-metavar/index.rst @@ -0,0 +1,3 @@ +.. sphinx_argparse_cli:: + :module: parser + :func: make diff --git a/roots/test-tuple-metavar/parser.py b/roots/test-tuple-metavar/parser.py new file mode 100644 index 0000000..e9f2682 --- /dev/null +++ b/roots/test-tuple-metavar/parser.py @@ -0,0 +1,10 @@ +from __future__ import annotations + +from argparse import ArgumentParser + + +def make() -> ArgumentParser: + parser = ArgumentParser(prog="tool") + parser.add_argument("--pair", nargs=2, metavar=("A", "B"), help="select a pair") + parser.add_argument("--val", metavar="VAL", help="single val") + return parser diff --git a/src/sphinx_argparse_cli/_logic.py b/src/sphinx_argparse_cli/_logic.py index d847ea2..51f0758 100644 --- a/src/sphinx_argparse_cli/_logic.py +++ b/src/sphinx_argparse_cli/_logic.py @@ -268,7 +268,12 @@ def _mk_option_line(self, action: Action, prefix: str) -> list_item: self._mk_option_name(line, prefix, opt) if not is_flag: line += Text(" ") - line += literal(text=as_key.upper()) + metavar_text = ( + " ".join(meta.upper() for meta in action.metavar) + if isinstance(action.metavar, tuple) + else as_key.upper() + ) + line += literal(text=metavar_text) else: self._mk_option_name(line, prefix, as_key) @@ -282,6 +287,7 @@ def _mk_option_line(self, action: Action, prefix: str) -> list_item: line += content if ( "no_default_values" not in self.options + and action.default is not None and action.default != SUPPRESS and not re.match(r".*[ (]default[s]? .*", (action.help or "")) and not isinstance(action, _StoreTrueAction | _StoreFalseAction) diff --git a/tests/complex.txt b/tests/complex.txt index 10b5772..8ac0892 100644 --- a/tests/complex.txt +++ b/tests/complex.txt @@ -17,10 +17,8 @@ complex options * **"--no-help"** * **"--outdir"** "OUT_DIR", **"-o"** "OUT_DIR" - output directory - (default: "None") * **"--in-dir"** "IN_DIR", **"-i"** "IN_DIR" - input directory - (default: "None") complex Exclusive @@ -44,7 +42,7 @@ a-first-desc complex first positional arguments ---------------------------------- -* **"one"** - first positional argument (default: "None") +* **"one"** - first positional argument * **"pos_two"** - second positional argument (default: "1") @@ -68,7 +66,7 @@ complex second complex second positional arguments ----------------------------------- -* **"one"** - first positional argument (default: "None") +* **"one"** - first positional argument * **"pos_two"** - second positional argument (default: "green") diff --git a/tests/complex_pre_310.txt b/tests/complex_pre_310.txt index 23a73cc..ca1ce68 100644 --- a/tests/complex_pre_310.txt +++ b/tests/complex_pre_310.txt @@ -17,10 +17,8 @@ complex optional arguments * **"--no-help"** * **"--outdir"** "OUT_DIR", **"-o"** "OUT_DIR" - output directory - (default: "None") * **"--in-dir"** "IN_DIR", **"-i"** "IN_DIR" - input directory - (default: "None") complex Exclusive @@ -44,7 +42,7 @@ a-first-desc complex first positional arguments ---------------------------------- -* **"one"** - first positional argument (default: "None") +* **"one"** - first positional argument * **"pos_two"** - second positional argument (default: "1") @@ -68,7 +66,7 @@ complex second complex second positional arguments ----------------------------------- -* **"one"** - first positional argument (default: "None") +* **"one"** - first positional argument * **"pos_two"** - second positional argument (default: "green") diff --git a/tests/test_logic.py b/tests/test_logic.py index 168bd5f..4cdb210 100644 --- a/tests/test_logic.py +++ b/tests/test_logic.py @@ -366,8 +366,9 @@ def test_nargs(build_outcome: str) -> None: assert "pos_optional" in build_outcome assert "pos_zero_or_more" in build_outcome assert "pos_one_or_more" in build_outcome - assert "KEY" in build_outcome - assert "VALUE" in build_outcome + assert "KEY VALUE" in build_outcome + assert "(default: " in build_outcome # default_val is not None, should show + assert 'default: "None"' not in build_outcome @pytest.mark.sphinx(buildername="text", testroot="choices") @@ -381,3 +382,11 @@ def test_actions(build_outcome: str) -> None: assert "increase verbosity" in build_outcome assert "paths to include" in build_outcome assert "a required optional argument" in build_outcome + + +@pytest.mark.sphinx(buildername="text", testroot="tuple-metavar") +def test_tuple_metavar(build_outcome: str) -> None: + assert '"A B"' in build_outcome or "A B" in build_outcome + assert "select a pair" in build_outcome + assert "default: None" not in build_outcome + assert '"VAL"' in build_outcome