summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Kotlenga <k.kotlenga@sims.pl>2021-10-12 11:27:14 +0200
committerDavid Lord <davidism@gmail.com>2021-12-28 11:00:19 -0800
commit280827938a505b2a380ee96b16d2f431605bad83 (patch)
tree325a3ff3e391d5b5e8a9ffedf5d33471e1cffaa1
parent08a825d2fcc2d7704b883a97227d6e89839c6a12 (diff)
downloadclick-280827938a505b2a380ee96b16d2f431605bad83.tar.gz
Allow a callable default to have its own string representation
As it was before 78a62b37c956e71b32689a0d5c75a684aa9ab56d. A callable can also be an object with __call__ and __str__ defined, in which case it makes sense to use it. Don't try too hard to show something else instead, because the developer most likely knows what he (or she) is doing. https://github.com/pallets/click/issues/2099
-rw-r--r--CHANGES.rst2
-rw-r--r--src/click/core.py3
-rw-r--r--tests/test_options.py13
3 files changed, 17 insertions, 1 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 92f69dc..cfc9280 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -9,6 +9,8 @@ Unreleased
same as the string ``"-"``. :issue:`2106`
- The ``option`` and ``argument`` decorators preserve the type
annotation of the decorated function. :pr:`2155`
+- A callable default value can customize its help text by overriding
+ ``__str__`` instead of always showing ``(dynamic)``. :issue:`2099`
Version 8.0.3
diff --git a/src/click/core.py b/src/click/core.py
index 09d9c21..6d8cace 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -1,5 +1,6 @@
import enum
import errno
+import inspect
import os
import sys
import typing as t
@@ -2719,7 +2720,7 @@ class Option(Parameter):
default_string = f"({self.show_default})"
elif isinstance(default_value, (list, tuple)):
default_string = ", ".join(str(d) for d in default_value)
- elif callable(default_value):
+ elif inspect.isfunction(default_value):
default_string = _("(dynamic)")
elif self.is_bool_flag and self.secondary_opts:
# For boolean flags that have distinct True/False opts,
diff --git a/tests/test_options.py b/tests/test_options.py
index 2e34337..90616b7 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -305,6 +305,19 @@ def test_dynamic_default_help_text(runner):
assert "(current user)" in result.output
+def test_dynamic_default_help_special_method(runner):
+ class Value:
+ def __call__(self):
+ return 42
+
+ def __str__(self):
+ return "special value"
+
+ opt = click.Option(["-a"], default=Value(), show_default=True)
+ ctx = click.Context(click.Command("cli"))
+ assert "special value" in opt.get_help_record(ctx)[1]
+
+
@pytest.mark.parametrize(
("type", "expect"),
[