diff --git a/CHANGES.rst b/CHANGES.rst index 506877590..d722e17a5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,5 +1,16 @@ .. currentmodule:: click +Version 8.3.4 +------------- + +Unreleased + +- Fix :meth:`HelpFormatter.write_usage` to write the usage prefix when called + with no ``args``. Previously, an empty string was passed through + :func:`wrap_text`, which dropped the ``initial_indent`` and produced a + blank line. :issue:`3360` + + Version 8.3.3 ------------- diff --git a/src/click/formatting.py b/src/click/formatting.py index 0b64f831b..d42f6f242 100644 --- a/src/click/formatting.py +++ b/src/click/formatting.py @@ -158,6 +158,13 @@ def write_usage(self, prog: str, args: str = "", prefix: str | None = None) -> N usage_prefix = f"{prefix:>{self.current_indent}}{prog} " text_width = self.width - self.current_indent + if not args: + # Without args, ``wrap_text`` would drop the ``initial_indent`` + # because the text is empty, so write the prefix directly. + self.write(usage_prefix.rstrip()) + self.write("\n") + return + if text_width >= (term_len(usage_prefix) + 20): # The arguments will fit to the right of the prefix. indent = " " * term_len(usage_prefix) diff --git a/tests/test_formatting.py b/tests/test_formatting.py index c79f6577f..8e2892142 100644 --- a/tests/test_formatting.py +++ b/tests/test_formatting.py @@ -366,3 +366,22 @@ def test_help_formatter_write_text(): actual = formatter.getvalue() expected = " Lorem ipsum dolor sit amet,\n consectetur adipiscing elit\n" assert actual == expected + + +def test_help_formatter_write_usage_no_args(): + formatter = click.HelpFormatter() + formatter.write_usage("program") + assert formatter.getvalue() == "Usage: program\n" + + +def test_help_formatter_write_usage_no_args_custom_prefix(): + formatter = click.HelpFormatter() + formatter.write_usage("program", prefix="Try: ") + assert formatter.getvalue() == "Try: program\n" + + +def test_help_formatter_write_usage_no_args_indented(): + formatter = click.HelpFormatter() + formatter.current_indent = 10 + formatter.write_usage("program") + assert formatter.getvalue() == " Usage: program\n"