summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--CHANGES.rst12
-rw-r--r--requirements/dev.txt2
-rw-r--r--requirements/docs.txt2
-rw-r--r--requirements/typing.txt2
-rw-r--r--src/click/core.py3
-rw-r--r--src/click/decorators.py8
-rw-r--r--tests/test_options.py18
8 files changed, 41 insertions, 8 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 105cfd2..472866d 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -8,7 +8,7 @@ repos:
- id: pyupgrade
args: ["--py37-plus"]
- repo: https://github.com/asottile/reorder_python_imports
- rev: v3.0.1
+ rev: v3.1.0
hooks:
- id: reorder-python-imports
args: ["--application-directories", "src"]
diff --git a/CHANGES.rst b/CHANGES.rst
index 7534412..3893438 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,6 +6,18 @@ Version 8.2.0
Unreleased
+Version 8.1.3
+-------------
+
+Released 2022-04-28
+
+- Use verbose form of ``typing.Callable`` for ``@command`` and
+ ``@group``. :issue:`2255`
+- Show error when attempting to create an option with
+ ``multiple=True, is_flag=True``. Use ``count`` instead.
+ :issue:`2246`
+
+
Version 8.1.2
-------------
diff --git a/requirements/dev.txt b/requirements/dev.txt
index 77f04f8..c9bcd60 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -20,7 +20,7 @@ filelock==3.6.0
# via
# tox
# virtualenv
-identify==2.4.12
+identify==2.5.0
# via pre-commit
nodeenv==1.6.0
# via pre-commit
diff --git a/requirements/docs.txt b/requirements/docs.txt
index 963d81e..2c10a6c 100644
--- a/requirements/docs.txt
+++ b/requirements/docs.txt
@@ -21,7 +21,7 @@ idna==3.3
# via requests
imagesize==1.3.0
# via sphinx
-jinja2==3.1.1
+jinja2==3.1.2
# via sphinx
markupsafe==2.1.1
# via jinja2
diff --git a/requirements/typing.txt b/requirements/typing.txt
index 910d804..2d97fef 100644
--- a/requirements/typing.txt
+++ b/requirements/typing.txt
@@ -5,7 +5,7 @@
#
# pip-compile-multi
#
-mypy==0.942
+mypy==0.950
# 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 a9a72c5..5abfb0f 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -2580,6 +2580,9 @@ class Option(Parameter):
if self.is_flag:
raise TypeError("'count' is not valid with 'is_flag'.")
+ if self.multiple and self.is_flag:
+ raise TypeError("'multiple' is not valid with 'is_flag', use 'count'.")
+
def to_info_dict(self) -> t.Dict[str, t.Any]:
info_dict = super().to_info_dict()
info_dict.update(
diff --git a/src/click/decorators.py b/src/click/decorators.py
index ef1b1a5..28618dc 100644
--- a/src/click/decorators.py
+++ b/src/click/decorators.py
@@ -149,7 +149,7 @@ def command(
def command(
- name: t.Union[str, t.Callable, None] = None,
+ name: t.Union[str, t.Callable[..., t.Any], None] = None,
cls: t.Optional[t.Type[Command]] = None,
**attrs: t.Any,
) -> t.Union[Command, t.Callable[..., Command]]:
@@ -182,7 +182,7 @@ def command(
appended to the end of the list.
"""
- func: t.Optional[t.Callable] = None
+ func: t.Optional[t.Callable[..., t.Any]] = None
if callable(name):
func = name
@@ -228,7 +228,7 @@ def command(
@t.overload
def group(
- __func: t.Callable,
+ __func: t.Callable[..., t.Any],
) -> Group:
...
@@ -242,7 +242,7 @@ def group(
def group(
- name: t.Union[str, t.Callable, None] = None, **attrs: t.Any
+ name: t.Union[str, t.Callable[..., t.Any], None] = None, **attrs: t.Any
) -> t.Union[Group, t.Callable[[F], Group]]:
"""Creates a new :class:`Group` with a function as callback. This
works otherwise the same as :func:`command` just that the `cls`
diff --git a/tests/test_options.py b/tests/test_options.py
index 2e1f291..d4090c7 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -904,3 +904,21 @@ def test_type_from_flag_value():
)
def test_is_bool_flag_is_correctly_set(option, expected):
assert option.is_bool_flag is expected
+
+
+@pytest.mark.parametrize(
+ ("kwargs", "message"),
+ [
+ ({"count": True, "multiple": True}, "'count' is not valid with 'multiple'."),
+ ({"count": True, "is_flag": True}, "'count' is not valid with 'is_flag'."),
+ (
+ {"multiple": True, "is_flag": True},
+ "'multiple' is not valid with 'is_flag', use 'count'.",
+ ),
+ ],
+)
+def test_invalid_flag_combinations(runner, kwargs, message):
+ with pytest.raises(TypeError) as e:
+ click.Option(["-a"], **kwargs)
+
+ assert message in str(e.value)