From b2234d9f0439d973953bae4d9b0266351a352ddb Mon Sep 17 00:00:00 2001 From: Matthew Messinger Date: Tue, 14 Jan 2025 13:30:49 -0500 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=90=9B=20Fix=20default=20value=20hand?= =?UTF-8?q?ling=20in=20parameter=20help=20extraction=20when=20rich=20is=20?= =?UTF-8?q?installed=20Fixes=20#465?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves consitency with typer/core.py TyperArgument.get_help_record, which does not print the default value if it is None. --- typer/rich_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/typer/rich_utils.py b/typer/rich_utils.py index 7d603da2d7..46e2474ea7 100644 --- a/typer/rich_utils.py +++ b/typer/rich_utils.py @@ -285,9 +285,9 @@ def _get_parameter_help( # Default value # This uses Typer's specific param._get_default_string if isinstance(param, (TyperOption, TyperArgument)): - if param.show_default: - show_default_is_str = isinstance(param.show_default, str) - default_value = param._extract_default_help_str(ctx=ctx) + default_value = param._extract_default_help_str(ctx=ctx) + show_default_is_str = isinstance(param.show_default, str) + if show_default_is_str or (default_value is not None and (param.show_default or ctx.show_default)): default_str = param._get_default_string( ctx=ctx, show_default_is_str=show_default_is_str, From 5b8aa86bc54c6681aae64ed0c6c27e40da4bbc57 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:35:44 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20for?= =?UTF-8?q?mat=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- typer/rich_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/typer/rich_utils.py b/typer/rich_utils.py index 46e2474ea7..a563ddd2bf 100644 --- a/typer/rich_utils.py +++ b/typer/rich_utils.py @@ -287,7 +287,9 @@ def _get_parameter_help( if isinstance(param, (TyperOption, TyperArgument)): default_value = param._extract_default_help_str(ctx=ctx) show_default_is_str = isinstance(param.show_default, str) - if show_default_is_str or (default_value is not None and (param.show_default or ctx.show_default)): + if show_default_is_str or ( + default_value is not None and (param.show_default or ctx.show_default) + ): default_str = param._get_default_string( ctx=ctx, show_default_is_str=show_default_is_str, From 47b4609958aaa7a0efefd98baae989429e0a05d1 Mon Sep 17 00:00:00 2001 From: svlandeg Date: Fri, 22 Aug 2025 09:55:12 +0200 Subject: [PATCH 3/5] add test that breaks on master --- tests/test_rich_utils.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_rich_utils.py b/tests/test_rich_utils.py index c62e3512aa..ea3d1b8b43 100644 --- a/tests/test_rich_utils.py +++ b/tests/test_rich_utils.py @@ -50,3 +50,28 @@ def main() -> None: assert result.exit_code == 0 assert "Show this message" in result.stdout + + +def test_rich_doesnt_print_None_default(): + app = typer.Typer(rich_markup_mode="rich") + + @app.command() + def main( + name: str, + option_1: str = typer.Option( + "option_1_default", + ), + option_2: str = typer.Option( + ..., + ), + ): + print(f"Hello {name}") + print(option_1) + print(option_2) + + result = runner.invoke(app, ["--help"]) + assert "Usage" in result.stdout + assert "name" in result.stdout + assert "option-1" in result.stdout + assert "option-2" in result.stdout + assert result.stdout.count("[default: None]") == 0 From 6ce6cafc290e856d7cf59fe69fc4563490fee73c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 22 Aug 2025 07:55:21 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20for?= =?UTF-8?q?mat=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_rich_utils.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_rich_utils.py b/tests/test_rich_utils.py index ea3d1b8b43..70a693ec75 100644 --- a/tests/test_rich_utils.py +++ b/tests/test_rich_utils.py @@ -57,13 +57,13 @@ def test_rich_doesnt_print_None_default(): @app.command() def main( - name: str, - option_1: str = typer.Option( - "option_1_default", - ), - option_2: str = typer.Option( - ..., - ), + name: str, + option_1: str = typer.Option( + "option_1_default", + ), + option_2: str = typer.Option( + ..., + ), ): print(f"Hello {name}") print(option_1) From 5e06c17995fb514e907576470374dc4570d9260d Mon Sep 17 00:00:00 2001 From: svlandeg Date: Fri, 22 Aug 2025 10:06:18 +0200 Subject: [PATCH 5/5] fix coverage --- tests/test_rich_utils.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_rich_utils.py b/tests/test_rich_utils.py index 70a693ec75..fbcfdde4b8 100644 --- a/tests/test_rich_utils.py +++ b/tests/test_rich_utils.py @@ -66,8 +66,8 @@ def main( ), ): print(f"Hello {name}") - print(option_1) - print(option_2) + print(f"First: {option_1}") + print(f"Second: {option_2}") result = runner.invoke(app, ["--help"]) assert "Usage" in result.stdout @@ -75,3 +75,7 @@ def main( assert "option-1" in result.stdout assert "option-2" in result.stdout assert result.stdout.count("[default: None]") == 0 + result = runner.invoke(app, ["Rick", "--option-2=Morty"]) + assert "Hello Rick" in result.stdout + assert "First: option_1_default" in result.stdout + assert "Second: Morty" in result.stdout