summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--CHANGES.rst7
-rw-r--r--requirements/dev.txt22
-rw-r--r--requirements/docs.txt10
-rw-r--r--requirements/tests.txt2
-rw-r--r--requirements/typing.txt2
-rw-r--r--src/click/core.py3
-rw-r--r--src/click/decorators.py2
-rw-r--r--src/click/shell_completion.py4
-rw-r--r--tests/test_options.py13
10 files changed, 43 insertions, 24 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5cc04f6..5744899 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,7 +2,7 @@ ci:
autoupdate_schedule: monthly
repos:
- repo: https://github.com/asottile/pyupgrade
- rev: v2.29.1
+ rev: v2.31.0
hooks:
- id: pyupgrade
args: ["--py37-plus"]
diff --git a/CHANGES.rst b/CHANGES.rst
index 43f1f51..804a200 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -26,6 +26,13 @@ Unreleased
- ``open_file`` recognizes ``Path("-")`` as a standard stream, the
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`
+- Fix a typo in the Bash completion script that affected file and
+ directory completion. If this script was generated by a previous
+ version, it should be regenerated. :issue:`2163`
Version 8.0.3
diff --git a/requirements/dev.txt b/requirements/dev.txt
index 6dbcdf0..f2fd68c 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -6,17 +6,15 @@
#
alabaster==0.7.12
# via sphinx
-attrs==21.2.0
+attrs==21.4.0
# via pytest
babel==2.9.1
# via sphinx
-backports.entry-points-selectable==1.1.1
- # via virtualenv
certifi==2021.10.8
# via requests
cfgv==3.3.1
# via pre-commit
-charset-normalizer==2.0.9
+charset-normalizer==2.0.10
# via requests
click==8.0.3
# via pip-tools
@@ -30,7 +28,7 @@ filelock==3.4.2
# via
# tox
# virtualenv
-identify==2.4.0
+identify==2.4.3
# via pre-commit
idna==3.3
# via requests
@@ -42,7 +40,7 @@ jinja2==3.0.3
# via sphinx
markupsafe==2.0.1
# via jinja2
-mypy==0.930
+mypy==0.931
# via -r requirements/typing.in
mypy-extensions==0.4.3
# via mypy
@@ -72,7 +70,7 @@ py==1.11.0
# via
# pytest
# tox
-pygments==2.10.0
+pygments==2.11.2
# via
# sphinx
# sphinx-tabs
@@ -84,7 +82,7 @@ pytz==2021.3
# via babel
pyyaml==6.0
# via pre-commit
-requests==2.26.0
+requests==2.27.1
# via sphinx
six==1.16.0
# via
@@ -99,7 +97,7 @@ sphinx==4.3.2
# sphinx-issues
# sphinx-tabs
# sphinxcontrib-log-cabinet
-sphinx-issues==1.2.0
+sphinx-issues==3.0.1
# via -r requirements/docs.in
sphinx-tabs==3.2.0
# via -r requirements/docs.in
@@ -126,13 +124,13 @@ tomli==2.0.0
# via
# mypy
# pep517
-tox==3.24.4
+tox==3.24.5
# via -r requirements/dev.in
typing-extensions==4.0.1
# via mypy
-urllib3==1.26.7
+urllib3==1.26.8
# via requests
-virtualenv==20.10.0
+virtualenv==20.13.0
# via
# pre-commit
# tox
diff --git a/requirements/docs.txt b/requirements/docs.txt
index 1b51a42..b6b291e 100644
--- a/requirements/docs.txt
+++ b/requirements/docs.txt
@@ -10,7 +10,7 @@ babel==2.9.1
# via sphinx
certifi==2021.10.8
# via requests
-charset-normalizer==2.0.9
+charset-normalizer==2.0.10
# via requests
docutils==0.16
# via
@@ -30,7 +30,7 @@ packaging==21.3
# sphinx
pallets-sphinx-themes==2.0.2
# via -r requirements/docs.in
-pygments==2.10.0
+pygments==2.11.2
# via
# sphinx
# sphinx-tabs
@@ -38,7 +38,7 @@ pyparsing==3.0.6
# via packaging
pytz==2021.3
# via babel
-requests==2.26.0
+requests==2.27.1
# via sphinx
snowballstemmer==2.2.0
# via sphinx
@@ -49,7 +49,7 @@ sphinx==4.3.2
# sphinx-issues
# sphinx-tabs
# sphinxcontrib-log-cabinet
-sphinx-issues==1.2.0
+sphinx-issues==3.0.1
# via -r requirements/docs.in
sphinx-tabs==3.2.0
# via -r requirements/docs.in
@@ -67,7 +67,7 @@ sphinxcontrib-qthelp==1.0.3
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
# via sphinx
-urllib3==1.26.7
+urllib3==1.26.8
# via requests
# The following packages are considered to be unsafe in a requirements file:
diff --git a/requirements/tests.txt b/requirements/tests.txt
index c272b15..abd1c24 100644
--- a/requirements/tests.txt
+++ b/requirements/tests.txt
@@ -4,7 +4,7 @@
#
# pip-compile requirements/tests.in
#
-attrs==21.2.0
+attrs==21.4.0
# via pytest
iniconfig==1.1.1
# via pytest
diff --git a/requirements/typing.txt b/requirements/typing.txt
index a674922..99380e4 100644
--- a/requirements/typing.txt
+++ b/requirements/typing.txt
@@ -4,7 +4,7 @@
#
# pip-compile requirements/typing.in
#
-mypy==0.930
+mypy==0.931
# via -r requirements/typing.in
mypy-extensions==0.4.3
# via mypy
diff --git a/src/click/core.py b/src/click/core.py
index 0459ccd..a89dab2 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
@@ -2678,7 +2679,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/src/click/decorators.py b/src/click/decorators.py
index f1cc005..7930a16 100644
--- a/src/click/decorators.py
+++ b/src/click/decorators.py
@@ -14,7 +14,7 @@ from .globals import get_current_context
from .utils import echo
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
-FC = t.TypeVar("FC", t.Callable[..., t.Any], Command)
+FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command])
def pass_context(f: F) -> F:
diff --git a/src/click/shell_completion.py b/src/click/shell_completion.py
index cad080d..1e9df6f 100644
--- a/src/click/shell_completion.py
+++ b/src/click/shell_completion.py
@@ -102,10 +102,10 @@ _SOURCE_BASH = """\
IFS=',' read type value <<< "$completion"
if [[ $type == 'dir' ]]; then
- COMREPLY=()
+ COMPREPLY=()
compopt -o dirnames
elif [[ $type == 'file' ]]; then
- COMREPLY=()
+ COMPREPLY=()
compopt -o default
elif [[ $type == 'plain' ]]; then
COMPREPLY+=($value)
diff --git a/tests/test_options.py b/tests/test_options.py
index 739da4e..7367a32 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"),
[