summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.rst2
-rw-r--r--src/click/core.py20
-rw-r--r--tests/test_options.py19
3 files changed, 25 insertions, 16 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index c6094b7..7c6e4a7 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -22,6 +22,8 @@ Unreleased
adding underline. :pr:`2058`
- An option with ``count=True`` will not show "[x>=0]" in help text.
:issue:`2072`
+- Default values are not cast to the parameter type twice during
+ processing. :issue:`2085`
Version 8.0.1
diff --git a/src/click/core.py b/src/click/core.py
index 52b3022..6cdba37 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -2192,6 +2192,9 @@ class Parameter:
:param call: If the default is a callable, call it. Disable to
return the callable instead.
+ .. versionchanged:: 8.0.2
+ Type casting is no longer performed when getting a default.
+
.. versionchanged:: 8.0.1
Type casting can fail in resilient parsing mode. Invalid
defaults will not prevent showing help text.
@@ -2207,20 +2210,10 @@ class Parameter:
if value is None:
value = self.default
- if callable(value):
- if not call:
- # Don't type cast the callable.
- return value
-
+ if call and callable(value):
value = value()
- try:
- return self.type_cast_value(ctx, value)
- except BadParameter:
- if ctx.resilient_parsing:
- return value
-
- raise
+ return value
def add_to_parser(self, parser: OptionParser, ctx: Context) -> None:
raise NotImplementedError()
@@ -2305,8 +2298,7 @@ class Parameter:
return False
def process_value(self, ctx: Context, value: t.Any) -> t.Any:
- if value is not None:
- value = self.type_cast_value(ctx, value)
+ value = self.type_cast_value(ctx, value)
if self.required and self.value_is_missing(value):
raise MissingParameter(ctx=ctx, param=self)
diff --git a/tests/test_options.py b/tests/test_options.py
index 180468b..06a70b4 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -252,7 +252,7 @@ def test_multiple_default_composite_type():
assert isinstance(opt.type, click.Tuple)
assert opt.type.types == [click.INT, click.STRING]
ctx = click.Context(click.Command("test"))
- assert opt.get_default(ctx) == ((1, "a"),)
+ assert opt.type_cast_value(ctx, opt.get_default(ctx)) == ((1, "a"),)
def test_parse_multiple_default_composite_type(runner):
@@ -323,12 +323,27 @@ def test_intrange_default_help_text(type, expect):
def test_count_default_type_help():
"""A count option with the default type should not show >=0 in help."""
- option = click.Option(["--couunt"], count=True, help="some words")
+ option = click.Option(["--count"], count=True, help="some words")
context = click.Context(click.Command("test"))
result = option.get_help_record(context)[1]
assert result == "some words"
+def test_file_type_help_default():
+ """The default for a File type is a filename string. The string
+ should be displayed in help, not an open file object.
+
+ Type casting is only applied to defaults in processing, not when
+ getting the default value.
+ """
+ option = click.Option(
+ ["--in"], type=click.File(), default=__file__, show_default=True
+ )
+ context = click.Context(click.Command("test"))
+ result = option.get_help_record(context)[1]
+ assert __file__ in result
+
+
def test_toupper_envvar_prefix(runner):
@click.command()
@click.option("--arg")