Skip to content

Commit 1c81a47

Browse files
authored
🐛 fix: skip sub-commands whose help is SUPPRESS (#357)
A sub-command registered with `add_parser("secret", help=SUPPRESS)` is hidden from argparse's own `--help`, yet the directive rendered a `prog secret` section whose description read `==SUPPRESS==`, because the code took the pseudo action's help text verbatim. The sub-parser walk now skips sub-commands whose help is `SUPPRESS`, matching how suppressed arguments are already left out of option groups. The usage line still lists them in `{run,secret}`, because argparse prints that itself. 🙈
1 parent 786fd11 commit 1c81a47

6 files changed

Lines changed: 47 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
1313
literals.
1414
- Make `:hook:` intercept `parse_intermixed_args()` as well as `parse_args()`.
1515
- Keep ANSI color codes out of usage blocks when `PYTHON_COLORS=1` is set on Python 3.14 or newer.
16+
- Skip sub-commands added with `help=argparse.SUPPRESS` instead of rendering them with a `==SUPPRESS==` description.
1617

1718
## 1.13.1
1819

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from __future__ import annotations
2+
3+
import sys
4+
from pathlib import Path
5+
6+
sys.path.insert(0, str(Path(__file__).parent))
7+
extensions = ["sphinx_argparse_cli"]
8+
nitpicky = True
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.. sphinx_argparse_cli::
2+
:module: parser
3+
:func: make
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from __future__ import annotations
2+
3+
from argparse import SUPPRESS, ArgumentParser
4+
5+
6+
def make() -> ArgumentParser:
7+
parser = ArgumentParser(prog="prog", add_help=False)
8+
sub = parser.add_subparsers()
9+
sub.add_parser("run", help="run it", add_help=False)
10+
sub.add_parser("secret", help=SUPPRESS, add_help=False)
11+
return parser

src/sphinx_argparse_cli/_logic.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,10 @@ def _load_sub_parsers(
146146
aliases = parser_to_args[id(parser)]
147147
aliases.remove(name)
148148
# help is stored in a pseudo action
149-
help_msg = next((a.help for a in sub_parser._choices_actions if a.dest == name), None) or "" # noqa: SLF001
150-
yield aliases, help_msg, parser
149+
help_msg = next((a.help for a in sub_parser._choices_actions if a.dest == name), None) # noqa: SLF001
150+
if help_msg == SUPPRESS:
151+
continue
152+
yield aliases, help_msg or "", parser
151153

152154
if parser._subparsers: # noqa: SLF001
153155
sub_sub_parser: _SubParsersAction[ArgumentParser] = parser._subparsers._group_actions[0] # type: ignore[assignment] # noqa: SLF001

tests/test_logic.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,26 @@ def test_option_role_as_html(build_outcome: str, warning: StringIO) -> None:
273273
assert not warning.getvalue()
274274

275275

276+
@pytest.mark.sphinx(buildername="text", testroot="subparsers-suppressed")
277+
def test_suppressed_sub_command(build_outcome: str) -> None:
278+
assert (
279+
build_outcome
280+
== """prog - CLI interface
281+
********************
282+
283+
prog {run,secret} ...
284+
285+
286+
prog run
287+
========
288+
289+
run it
290+
291+
prog run
292+
"""
293+
)
294+
295+
276296
@pytest.mark.sphinx(buildername="text", testroot="python-colors")
277297
def test_usage_ignores_python_colors(build_outcome: str) -> None:
278298
assert (

0 commit comments

Comments
 (0)