Repository: pallets/click (python)

Issue:
Option.is_bool_flag is set to True even if the option is not a flag
This is relevant only for Click 8.0.1, since the following line was introduced in PR https://github.com/pallets/click/pull/1913:

https://github.com/pallets/click/blob/af0af571cbbd921d3974a0ff9cf58a4b26bb852b/src/click/core.py#L2531

The solution is as easy as:

```python
self.is_bool_flag = self.is_flag and isinstance(self.type, types.BoolParamType)
```
Available to open a PR.

## Demonstration code
```python
import click

@click.command()
@click.option('--switch', type=bool)
def f(switch):
    print(switch)


if __name__ == '__main__':
    assert not f.params[0].is_flag
    assert f.params[0].is_bool_flag
    f('--switch'.split())
```
```
Error: Option '--switch' requires an argument.
```

Pull request description:
Fix `is_bool_flag` being set to True even when `is_flag` is False
Fixes #1925.

The test is probably overkill.


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index e647915..a2126f4 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,9 @@ Version 8.0.2
 
 Unreleased
 
+-   ``is_bool_flag`` is not set to ``True`` if ``is_flag`` is ``False``.
+    :issue:`1925`
+
 
 Version 8.0.1
 -------------
diff --git a/src/click/core.py b/src/click/core.py
index 5c7ed56..a89a3bf 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -2528,7 +2528,7 @@ class Option(Parameter):
             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


Test patch:
diff --git a/tests/test_options.py b/tests/test_options.py
index 323d1c4..bddd194 100644
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -4,6 +4,7 @@ import re
 import pytest
 
 import click
+from click import Option
 
 
 def test_prefixes(runner):
@@ -763,3 +764,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