Skip to content

Commit

Permalink
Merge pull request #1913 from pallets/flag_value-type
Browse files Browse the repository at this point in the history
detect type from flag_value
  • Loading branch information
davidism committed May 19, 2021
2 parents b131f71 + ad52b19 commit ba9bb3c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 21 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Expand Up @@ -16,6 +16,8 @@ Unreleased
3.8. :issue:`1889`
- Arguments with ``nargs=-1`` only use env var value if no command
line values are given. :issue:`1903`
- Flag options guess their type from ``flag_value`` if given, like
regular options do from ``default``. :issue:`1886`


Version 8.0.0
Expand Down
32 changes: 15 additions & 17 deletions src/click/core.py
Expand Up @@ -13,6 +13,7 @@
from gettext import ngettext
from itertools import repeat

from . import types
from ._unicodefun import _verify_python_env
from .exceptions import Abort
from .exceptions import BadParameter
Expand All @@ -30,11 +31,6 @@
from .termui import confirm
from .termui import prompt
from .termui import style
from .types import _NumberRangeBase
from .types import BOOL
from .types import convert_type
from .types import IntRange
from .types import ParamType
from .utils import _detect_program_name
from .utils import _expand_args
from .utils import echo
Expand Down Expand Up @@ -2010,7 +2006,7 @@ class Parameter:
def __init__(
self,
param_decls: t.Optional[t.Sequence[str]] = None,
type: t.Optional[t.Union["ParamType", t.Any]] = None,
type: t.Optional[t.Union[types.ParamType, t.Any]] = None,
required: bool = False,
default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None,
callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None,
Expand All @@ -2035,8 +2031,7 @@ def __init__(
self.name, self.opts, self.secondary_opts = self._parse_decls(
param_decls or (), expose_value
)

self.type = convert_type(type, default)
self.type = types.convert_type(type, default)

# Default nargs to what the type tells us if we have that
# information available.
Expand Down Expand Up @@ -2439,6 +2434,9 @@ class Option(Parameter):
context.
:param help: the help string.
:param hidden: hide this option from help outputs.
.. versionchanged:: 8.0.1
``type`` is detected from ``flag_value`` if given.
"""

param_type_name = "option"
Expand All @@ -2456,7 +2454,7 @@ def __init__(
multiple: bool = False,
count: bool = False,
allow_from_autoenv: bool = True,
type: t.Optional[t.Union["ParamType", t.Any]] = None,
type: t.Optional[t.Union[types.ParamType, t.Any]] = None,
help: t.Optional[str] = None,
hidden: bool = False,
show_choices: bool = True,
Expand Down Expand Up @@ -2507,20 +2505,20 @@ def __init__(
if flag_value is None:
flag_value = not self.default

if is_flag and type is None:
# Re-guess the type from the flag value instead of the
# default.
self.type = types.convert_type(None, flag_value)

self.is_flag: bool = is_flag
self.is_bool_flag = isinstance(self.type, types.BoolParamType)
self.flag_value: t.Any = flag_value

if self.is_flag and isinstance(self.flag_value, bool) and type in [None, bool]:
self.type: "ParamType" = BOOL
self.is_bool_flag = True
else:
self.is_bool_flag = False

# Counting
self.count = count
if count:
if type is None:
self.type = IntRange(min=0)
self.type = types.IntRange(min=0)
if default_is_missing:
self.default = 0

Expand Down Expand Up @@ -2725,7 +2723,7 @@ def _write_opts(opts: t.Sequence[str]) -> str:

extra.append(_("default: {default}").format(default=default_string))

if isinstance(self.type, _NumberRangeBase):
if isinstance(self.type, types._NumberRangeBase):
range_str = self.type._describe_range()

if range_str:
Expand Down
5 changes: 1 addition & 4 deletions src/click/types.py
Expand Up @@ -1000,10 +1000,7 @@ def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> Pa
if ty is float:
return FLOAT

# Booleans are only okay if not guessed. For is_flag options with
# flag_value, default=True indicates which flag_value is the
# default.
if ty is bool and not guessed_type:
if ty is bool:
return BOOL

if guessed_type:
Expand Down
7 changes: 7 additions & 0 deletions tests/test_options.py
Expand Up @@ -756,3 +756,10 @@ def cli(opt, a, b):

result = runner.invoke(cli, args, standalone_mode=False, catch_exceptions=False)
assert result.return_value == expect


def test_type_from_flag_value():
param = click.Option(["-a", "x"], default=True, flag_value=4)
assert param.type is click.INT
param = click.Option(["-b", "x"], flag_value=8)
assert param.type is click.INT

0 comments on commit ba9bb3c

Please sign in to comment.