get_argparse_help_string
The command-line interface to our program.
Command line help
The program's command-line help is reproduced here:
> program-name --help
usage: pdoc [-h] [--verbose] {subcommand} ...
A program that does something.
positional arguments:
{subcommand}
subcommand A subcommand
options:
-h, --help show this help message and exit
--verbose Increase verbosity of output
________________________________________________________________________
> program-name subcommand --help
usage: pdoc subcommand [-h] [--subarg SUBARG]
options:
-h, --help show this help message and exit
--subarg SUBARG An argument for the subcommand
1import argparse 2import textwrap 3 4 5def get_argparse_help_string( 6 name: str, parser: argparse.ArgumentParser, wrap: int = 80, wrap_indent: int = 8 7) -> str: 8 """Generate a docstring for an argparse parser that shows the help for the parser and all subparsers, recursively. 9 10 Based on an idea from <https://github.com/pdoc3/pdoc/issues/89> 11 12 Arguments: 13 * `name`: The name of the program 14 * `parser`: The parser 15 * `wrap`: The number of characters to wrap the help text to (0 to disable) 16 * `wrap_indent`: The number of characters to indent the wrapped text 17 """ 18 19 def get_parser_help_recursive( 20 parser: argparse.ArgumentParser, cmd: str = "", root: bool = True 21 ): 22 docstring = "" 23 if not root: 24 docstring += "\n" + "_" * 72 + "\n\n" 25 docstring += f"> {cmd} --help\n" 26 docstring += parser.format_help() 27 28 for action in parser._actions: 29 if isinstance(action, argparse._SubParsersAction): 30 for subcmd, subparser in action.choices.items(): 31 docstring += get_parser_help_recursive( 32 subparser, f"{cmd} {subcmd}", root=False 33 ) 34 return docstring 35 36 docstring = get_parser_help_recursive(parser, name) 37 38 if wrap > 0: 39 wrapped = [] 40 # From the textwrap docs: 41 # > If replace_whitespace is false, 42 # > newlines may appear in the middle of a line and cause strange output. 43 # > For this reason, text should be split into paragraphs 44 # > (using str.splitlines() or similar) which are wrapped separately. 45 for line in docstring.splitlines(): 46 if line: 47 wrapped += textwrap.wrap( 48 line, 49 width=wrap, 50 replace_whitespace=False, 51 subsequent_indent=" " * wrap_indent, 52 ) 53 else: 54 wrapped += [""] 55 return "\n".join(wrapped) 56 else: 57 return docstring 58 59 60def _make_parser() -> argparse.ArgumentParser: 61 """Return the ArgumentParser for this program.""" 62 parser = argparse.ArgumentParser(description="A program that does something.") 63 parser.add_argument( 64 "--verbose", action="store_true", help="Increase verbosity of output" 65 ) 66 subparsers = parser.add_subparsers() 67 subparser = subparsers.add_parser("subcommand", help="A subcommand") 68 subparser.add_argument("--subarg", help="An argument for the subcommand") 69 return parser 70 71 72__doc__ = f""" 73The command-line interface to our program. 74 75## Command line help 76 77The program's command-line help is reproduced here: 78 79```text 80{get_argparse_help_string("program-name", _make_parser())} 81``` 82"""
def
get_argparse_help_string( name: str, parser: argparse.ArgumentParser, wrap: int = 80, wrap_indent: int = 8) -> str:
6def get_argparse_help_string( 7 name: str, parser: argparse.ArgumentParser, wrap: int = 80, wrap_indent: int = 8 8) -> str: 9 """Generate a docstring for an argparse parser that shows the help for the parser and all subparsers, recursively. 10 11 Based on an idea from <https://github.com/pdoc3/pdoc/issues/89> 12 13 Arguments: 14 * `name`: The name of the program 15 * `parser`: The parser 16 * `wrap`: The number of characters to wrap the help text to (0 to disable) 17 * `wrap_indent`: The number of characters to indent the wrapped text 18 """ 19 20 def get_parser_help_recursive( 21 parser: argparse.ArgumentParser, cmd: str = "", root: bool = True 22 ): 23 docstring = "" 24 if not root: 25 docstring += "\n" + "_" * 72 + "\n\n" 26 docstring += f"> {cmd} --help\n" 27 docstring += parser.format_help() 28 29 for action in parser._actions: 30 if isinstance(action, argparse._SubParsersAction): 31 for subcmd, subparser in action.choices.items(): 32 docstring += get_parser_help_recursive( 33 subparser, f"{cmd} {subcmd}", root=False 34 ) 35 return docstring 36 37 docstring = get_parser_help_recursive(parser, name) 38 39 if wrap > 0: 40 wrapped = [] 41 # From the textwrap docs: 42 # > If replace_whitespace is false, 43 # > newlines may appear in the middle of a line and cause strange output. 44 # > For this reason, text should be split into paragraphs 45 # > (using str.splitlines() or similar) which are wrapped separately. 46 for line in docstring.splitlines(): 47 if line: 48 wrapped += textwrap.wrap( 49 line, 50 width=wrap, 51 replace_whitespace=False, 52 subsequent_indent=" " * wrap_indent, 53 ) 54 else: 55 wrapped += [""] 56 return "\n".join(wrapped) 57 else: 58 return docstring
Generate a docstring for an argparse parser that shows the help for the parser and all subparsers, recursively.
Based on an idea from https://github.com/pdoc3/pdoc/issues/89
Arguments:
name
: The name of the programparser
: The parserwrap
: The number of characters to wrap the help text to (0 to disable)wrap_indent
: The number of characters to indent the wrapped text