Text blob from `--help`; descriptions from docstrings?
Related to: #188.
Running mycli --help outputs a wall of text separated from the documentation on arguments and options.
Could Argument/Option help fields be set by parsing Napoleon-style docstrings?
Here's an example of the issue:
class Commands:
@staticmethod
@cli.command()
def new(
name: str,
newest=typer.Option(False, hidden=True),
prompt: bool = False,
) -> None:
"""
Generates something.
Args:
name: The name to use
newest: Use the newest version
prompt: Prompt for full info
"""
mycli new --help
Usage: mycli new [OPTIONS] NAME
Generates something.
Args: name: The name of the project, including any dashes or capital
letters newest: Use the newest nightly release prompt: Prompt for full info
Arguments:
NAME [required]
Options:
--prompt / --no-prompt [default: False]
I also use napolean / google-style docstrings and would also love to see this feature implemented
If that's not feasible, is there at least a way to get typer to stop mangling docstrings when it includes them in help text? When I say mangling, i mean that when typer sees a docstring with a single newline character in it, it strips out the newline character, as in @dmyersturnbull's example, but when it encounters two newline characters in a row, it doesn't strip either of them
oh, i see now that it actually strips out ALL newline characters except the ones that separate the docstring summary from the rest of the docstring :(
Yes! This ^^^ I don't use that format but I do use a format. It would be nice if different formats were supported (reStructuredText for instance), but even if only one format was supported that would be awesome.
I had the same problem. Suppose this module is called cli.py
import typer
CLI = typer.Typer()
@CLI.command()
def greet() -> None:
"""
Greet someone.
Parameters
----------
param1 : str
description.
param2 : str
description.
param3 : int
description, by default typer.Option(...)
param4 : int
description, by default typer.Option(...)
param5 : int
description, by default typer.Option(...)
"""
print("Hello there!")
@CLI.command()
def greet_back() -> None:
"""
Greet Obi_wan back.
Parameters
----------
param1 : str
description.
param2 : str
description.
param3 : int
description, by default typer.Option(...)
param4 : int
description, by default typer.Option(...)
param5 : int
description, by default typer.Option(...)
"""
print("General Kenobi!")
if __name__ == "__main__":
CLI()
by running python cli.py greet --help (with typer version 0.6.1), I receive

But I would like to receive

What I did to avoid duplication, was to write this function
import inspect
from typing import Callable, Any
DOCSTRING_SECTIONS = {
# Numpy style docstring
"Parameters": True,
"Returns": True,
"Raises": True,
# Google style docstring
"Args:": True,
"Returns:": True,
"Raises:": True,
}
# reST (Sphinx) style docstring
SPHINX_PARAM = ":param"
SPHINX_RETURNS = ":returns"
SPHINX_RAISES = ":raises"
def get_help_from_docstring(command: Callable[..., Any]) -> str:
"""
Get help message from callable object.
Parameters
----------
command : Callable[..., Any]
Callable object (command, callback, ...).
Returns
-------
str
Docstring summary, if exists; empty string otherwise.
"""
docstring = inspect.getdoc(command)
if not docstring:
return ""
docstring_lines = docstring.strip().splitlines()
help_message = ""
for line in docstring_lines:
if DOCSTRING_SECTIONS.get(line.strip()) or line.strip().startswith(
(SPHINX_PARAM, SPHINX_RETURNS, SPHINX_RAISES)
):
break
help_message += line + "\n" if line else ""
return help_message
I believe this resolves the problem for the 3 principal docstring formats today.
To it to be added to the Typer source code, I believe it should change all the inspect.getdoc(object) occurrences in typer/main.py to get_help_from_docstring(object).
Of course, this does not solve the problem from #336