Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/8.0.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Jul 4, 2021
2 parents ff72d7d + 76cc18d commit ce152bd
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 17 deletions.
8 changes: 8 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ Version 8.0.2

Unreleased

- ``is_bool_flag`` is not set to ``True`` if ``is_flag`` is ``False``.
:issue:`1925`
- Bash version detection is locale independent. :issue:`1940`
- Empty ``default`` value is not shown for ``multiple=True``.
:issue:`1969`
- Fix shell completion for arguments that start with a forward slash
such as absolute file paths. :issue:`1929`


Version 8.0.1
-------------
Expand Down
10 changes: 8 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ First time setup

.. code-block:: text
git remote add fork https://github.com/{username}/click
$ git remote add fork https://github.com/{username}/click
- Create a virtualenv.

Expand All @@ -107,6 +107,12 @@ First time setup
> env\Scripts\activate
- Upgrade pip and setuptools.

.. code-block:: text
$ python -m pip install --upgrade pip setuptools
- Install the development dependencies, then install Click in
editable mode.

Expand Down Expand Up @@ -138,7 +144,7 @@ Start coding
.. code-block:: text
$ git fetch origin
$ git checkout -b your-branch-name origin/7.x
$ git checkout -b your-branch-name origin/8.0.x
If you're submitting a feature addition or change, branch off of the
"main" branch.
Expand Down
2 changes: 2 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ Types

.. autoclass:: FloatRange

.. autoclass:: DateTime

.. autoclass:: Tuple

.. autoclass:: ParamType
Expand Down
9 changes: 7 additions & 2 deletions docs/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,18 @@ Example usage::
Showing Progress Bars
---------------------

.. versionadded:: 2.0

Sometimes, you have command line scripts that need to process a lot of data,
but you want to quickly show the user some progress about how long that
will take. Click supports simple progress bar rendering for that through
the :func:`progressbar` function.

.. note::

If you find that you have requirements beyond what Click's progress
bar supports, try using `tqdm`_.

.. _tqdm: https://tqdm.github.io/

The basic usage is very simple: the idea is that you have an iterable that
you want to operate on. For each item in the iterable it might take some
time to do processing. So say you have a loop like this::
Expand Down
6 changes: 3 additions & 3 deletions examples/completion/README
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ For Bash:

.. code-block:: bash

eval "$(_COMPLETION_COMPLETE=source_bash completion)"
eval "$(_COMPLETION_COMPLETE=bash_source completion)"

For Zsh:

.. code-block:: zsh

eval "$(_COMPLETION_COMPLETE=source_zsh completion)"
eval "$(_COMPLETION_COMPLETE=zsh_source completion)"

For Fish:

.. code-block:: fish

eval (env _COMPLETION_COMPLETE=source_fish completion)
eval (env _COMPLETION_COMPLETE=fish_source completion)

Now press tab (maybe twice) after typing something to see completions.
5 changes: 4 additions & 1 deletion examples/completion/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ def list_users(ctx, param, incomplete):
# of CompletionItem. You can match on whatever you want, including
# the help.
items = [("bob", "butcher"), ("alice", "baker"), ("jerry", "candlestick maker")]
out = []

for value, help in items:
if incomplete in value or incomplete in help:
yield CompletionItem(value, help=help)
out.append(CompletionItem(value, help=help))

return out


@group.command(help="Choose a user")
Expand Down
13 changes: 7 additions & 6 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2197,7 +2197,7 @@ def get_default(
self, ctx: Context, call: bool = True
) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
"""Get the default for the parameter. Tries
:meth:`Context.lookup_value` first, then the local default.
:meth:`Context.lookup_default` first, then the local default.
:param ctx: Current context.
:param call: If the default is a callable, call it. Disable to
Expand Down Expand Up @@ -2461,7 +2461,7 @@ class Option(Parameter):
def __init__(
self,
param_decls: t.Optional[t.Sequence[str]] = None,
show_default: bool = False,
show_default: t.Union[bool, str] = False,
prompt: t.Union[bool, str] = False,
confirmation_prompt: t.Union[bool, str] = False,
prompt_required: bool = True,
Expand Down Expand Up @@ -2528,7 +2528,7 @@ def __init__(
self.type = types.convert_type(None, flag_value)

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

# Counting
Expand Down Expand Up @@ -2590,7 +2590,7 @@ def _parse_decls(
for decl in decls:
if decl.isidentifier():
if name is not None:
raise TypeError("Name defined twice")
raise TypeError(f"Name '{name}' defined twice")
name = decl
else:
split_char = ";" if decl[:1] == "/" else "/"
Expand Down Expand Up @@ -2748,7 +2748,8 @@ def _write_opts(opts: t.Sequence[str]) -> str:
else:
default_string = str(default_value)

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

if isinstance(self.type, types._NumberRangeBase):
range_str = self.type._describe_range()
Expand All @@ -2760,7 +2761,7 @@ def _write_opts(opts: t.Sequence[str]) -> str:
extra.append(_("required"))

if extra:
extra_str = ";".join(extra)
extra_str = "; ".join(extra)
help = f"{help} [{extra_str}]" if help else f"[{extra_str}]"

return ("; " if any_prefix_is_slash else " / ").join(rv), help
Expand Down
13 changes: 10 additions & 3 deletions src/click/shell_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,10 @@ class BashComplete(ShellComplete):
def _check_version(self) -> None:
import subprocess

output = subprocess.run(["bash", "--version"], stdout=subprocess.PIPE)
match = re.search(r"version (\d)\.(\d)\.\d", output.stdout.decode())
output = subprocess.run(
["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE
)
match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode())

if match is not None:
major, minor = match.groups()
Expand Down Expand Up @@ -448,7 +450,12 @@ def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool:

def _start_of_option(value: str) -> bool:
"""Check if the value looks like the start of an option."""
return not value[0].isalnum() if value else False
if not value:
return False

c = value[0]
# Allow "/" since that starts a path.
return not c.isalnum() and c != "/"


def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool:
Expand Down
30 changes: 30 additions & 0 deletions tests/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest

import click
from click import Option


def test_prefixes(runner):
Expand Down Expand Up @@ -727,6 +728,16 @@ def test_do_not_show_no_default(runner):
assert "[default: None]" not in message


def test_do_not_show_default_empty_multiple():
"""When show_default is True and multiple=True is set, it should not
print empty default value in --help output.
"""
opt = click.Option(["-a"], multiple=True, help="values", show_default=True)
ctx = click.Context(click.Command("cli"))
message = opt.get_help_record(ctx)[1]
assert message == "values"


@pytest.mark.parametrize(
("args", "expect"),
[
Expand Down Expand Up @@ -763,3 +774,22 @@ def test_type_from_flag_value():
assert param.type is click.INT
param = click.Option(["-b", "x"], flag_value=8)
assert param.type is click.INT


@pytest.mark.parametrize(
("option", "expected"),
[
# Not boolean flags
pytest.param(Option(["-a"], type=int), False, id="int option"),
pytest.param(Option(["-a"], type=bool), False, id="bool non-flag [None]"),
pytest.param(Option(["-a"], default=True), False, id="bool non-flag [True]"),
pytest.param(Option(["-a"], default=False), False, id="bool non-flag [False]"),
pytest.param(Option(["-a"], flag_value=1), False, id="non-bool flag_value"),
# Boolean flags
pytest.param(Option(["-a"], is_flag=True), True, id="is_flag=True"),
pytest.param(Option(["-a/-A"]), True, id="secondary option [implicit flag]"),
pytest.param(Option(["-a"], flag_value=True), True, id="bool flag_value"),
],
)
def test_is_bool_flag_is_correctly_set(option, expected):
assert option.is_bool_flag is expected
8 changes: 8 additions & 0 deletions tests/test_shell_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ def test_path_types(type, expect):
assert c.type == expect


def test_absolute_path():
cli = Command("cli", params=[Option(["-f"], type=Path())])
out = _get_completions(cli, ["-f"], "/ab")
assert len(out) == 1
c = out[0]
assert c.value == "/ab"


def test_option_flag():
cli = Command(
"cli",
Expand Down

0 comments on commit ce152bd

Please sign in to comment.