From d340b0c1202284a1b9d0ca892549208527d586ce Mon Sep 17 00:00:00 2001 From: Kevin Deldycke Date: Wed, 1 Apr 2026 18:42:50 +0200 Subject: [PATCH] Fix speculative speculative empty string check Closes #3298 --- src/click/core.py | 2 +- tests/test_options.py | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/click/core.py b/src/click/core.py index f0a624be3..6dc44f399 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -3110,7 +3110,7 @@ def get_help_extra(self, ctx: Context) -> types.OptionHelpExtra: )[1] elif self.is_bool_flag and not self.secondary_opts and not default_value: default_string = "" - elif default_value == "": + elif isinstance(default_value, str) and default_value == "": default_string = '""' else: default_string = str(default_value) diff --git a/tests/test_options.py b/tests/test_options.py index e335f3c1a..85f622459 100644 --- a/tests/test_options.py +++ b/tests/test_options.py @@ -1259,12 +1259,36 @@ def test_show_default_string(runner): assert "[default: (unlimited)]" in message -def test_show_default_with_empty_string(runner): - """When show_default is True and default is set to an empty string.""" - opt = click.Option(["--limit"], default="", show_default=True) +class _StrictEq: + """Object whose ``__eq__`` raises on string comparison (like semver.Version).""" + + def __eq__(self, other): + if isinstance(other, str): + raise ValueError("cannot compare to string") + return NotImplemented + + def __str__(self): + return "strict" + + +@pytest.mark.parametrize( + ("default", "expected"), + [ + ("", '[default: ""]'), + (_StrictEq(), "[default: strict]"), + ], + ids=["empty-string", "non-string-comparable-object"], +) +def test_show_default_with_empty_string(runner, default, expected): + """The empty-string check in help rendering must not break on objects + whose ``__eq__`` raises for string operands. + + Regression test for https://github.com/pallets/click/issues/3298. + """ + opt = click.Option(["--limit"], default=default, show_default=True) ctx = click.Context(click.Command("cli")) message = opt.get_help_record(ctx)[1] - assert '[default: ""]' in message + assert expected in message def test_do_not_show_no_default(runner):