Skip to content

Commit 81a482f

Browse files
committed
Merge branch 'main' into stable
2 parents 23780fa + 9c632c0 commit 81a482f

15 files changed

Lines changed: 2085 additions & 501 deletions

CHANGES.rst

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
11
.. currentmodule:: click
22

3-
Version 8.2.x
4-
-------------
5-
6-
Unreleased
7-
8-
- show correct auto complete value for nargs option in combination with flag option :issue:`2813`
3+
Version 8.3.0
4+
--------------
5+
6+
Released 2025-09-15
7+
8+
- **Improved flag option handling**: Reworked the relationship between ``flag_value``
9+
and ``default`` parameters for better consistency:
10+
11+
* The ``default`` parameter value is now preserved as-is and passed directly
12+
to CLI functions (no more unexpected transformations)
13+
* Exception: flag options with ``default=True`` maintain backward compatibility
14+
by defaulting to their ``flag_value``
15+
* The ``default`` parameter can now be any type (``bool``, ``None``, etc.)
16+
* Fixes inconsistencies reported in: :issue:`1992` :issue:`2514` :issue:`2610`
17+
:issue:`3024` :pr:`3030`
18+
- Allow ``default`` to be set on ``Argument`` for ``nargs = -1``. :issue:`2164`
19+
:pr:`3030`
20+
- Show correct auto complete value for ``nargs`` option in combination with flag
21+
option :issue:`2813`
22+
- Show correct auto complete value for nargs option in combination with flag option :issue:`2813`
23+
- Fix handling of quoted and escaped parameters in Fish autocompletion. :issue:`2995` :pr:`3013`
24+
- Lazily import ``shutil``. :pr:`3023`
25+
- Properly forward exception information to resources registered with
26+
``click.core.Context.with_resource()``. :issue:`2447` :pr:`3058`
27+
- Fix regression related to EOF handling in CliRunner. :issue:`2939`:pr:`2940`
928

1029
Version 8.2.2
1130
-------------
1231

1332
Released 2025-07-31
1433

15-
- Fix reconciliation of `default`, `flag_value` and `type` parameters for
34+
- Fix reconciliation of ``default``, ``flag_value`` and ``type`` parameters for
1635
flag options, as well as parsing and normalization of environment variables.
1736
:issue:`2952` :pr:`2956`
1837
- Fix typing issue in ``BadParameter`` and ``MissingParameter`` exceptions for the
1938
parameter ``param_hint`` that did not allow for a sequence of string where the
20-
underlying functino ``_join_param_hints`` allows for it. :issue:`2777` :pr:`2990`
39+
underlying function ``_join_param_hints`` allows for it. :issue:`2777` :pr:`2990`
2140
- Use the value of ``Enum`` choices to render their default value in help
2241
screen. Refs :issue:`2911` :pr:`3004`
2342
- Fix completion for the Z shell (``zsh``) for completion items containing

docs/options.md

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ If you want to define an alias for the second option only, then you will need to
314314

315315
## Flag Value
316316

317-
To have an flag pass a value to the underlying function set `flag_value`. This automatically sets `is_flag=True`. To set a default flag, set `default=True`. Setting flag values can be used to create patterns like this:
317+
To have an flag pass a value to the underlying function set `flag_value`. This automatically sets `is_flag=True`. To mark the flag as default, set `default=True`. Setting flag values can be used to create patterns like this:
318318

319319
```{eval-rst}
320320
.. click:example::
@@ -335,6 +335,26 @@ To have an flag pass a value to the underlying function set `flag_value`. This a
335335
invoke(info)
336336
```
337337

338+
````{note}
339+
The `default` value is given to the underlying function as-is. So if you set `default=None`, the value passed to the function is the `None` Python value. Same for any other type.
340+
341+
But there is a special case for flags. If a flag has a `flag_value`, then setting `default=True` is interpreted as *the flag should be activated by default*. So instead of the underlying function receiving the `True` Python value, it will receive the `flag_value`.
342+
343+
Which means, in example above, this option:
344+
345+
```python
346+
@click.option('--upper', 'transformation', flag_value='upper', default=True)
347+
```
348+
349+
is equivalent to:
350+
351+
```python
352+
@click.option('--upper', 'transformation', flag_value='upper', default='upper')
353+
```
354+
355+
Because the two are equivalent, it is recommended to always use the second form, and set `default` to the actual value you want to pass. And not use the special `True` case. This makes the code more explicit and predictable.
356+
````
357+
338358
## Values from Environment Variables
339359

340360
To pass in a value in from a specific environment variable use `envvar`.
@@ -386,10 +406,11 @@ Here are the rules used to parse environment variable values for flag options:
386406
- If the flag option has a `flag_value` argument, passing that value in the environment variable will activate the flag, in addition to all the cases described above
387407
- Any other value is interpreted as deactivating the flag
388408

389-
.. caution::
390-
For boolean flags with a pair of values, the only recognized environment variable is the one provided to the `envvar` argument.
409+
```{caution}
410+
For boolean flags with a pair of values, the only recognized environment variable is the one provided to the `envvar` argument.
391411
392-
So an option defined as `--flag\--no-flag`, with a `envvar="FLAG"` parameter, there is no magical `NO_FLAG=<anything>` variable that is recognized. Only the `FLAG=<anything>` environment variable is recognized.
412+
So an option defined as `--flag\--no-flag`, with a `envvar="FLAG"` parameter, there is no magical `NO_FLAG=<anything>` variable that is recognized. Only the `FLAG=<anything>` environment variable is recognized.
413+
```
393414

394415
Once the status of the flag has been determine to be activated or not, the `flag_value` is used as the value of the flag if it is activated. If the flag is not activated, the value of the flag is set to `None` by default.
395416

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "click"
3-
version = "8.2.2"
3+
version = "8.3.0"
44
description = "Composable command line interface toolkit"
55
readme = "README.md"
66
license = "BSD-3-Clause"

src/click/_utils.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from __future__ import annotations
2+
3+
import enum
4+
import typing as t
5+
6+
7+
class Sentinel(enum.Enum):
8+
"""Enum used to define sentinel values.
9+
10+
.. seealso::
11+
12+
`PEP 661 - Sentinel Values <https://peps.python.org/pep-0661/>`_.
13+
"""
14+
15+
UNSET = object()
16+
FLAG_NEEDS_VALUE = object()
17+
18+
def __repr__(self) -> str:
19+
return f"{self.__class__.__name__}.{self.name}"
20+
21+
22+
UNSET = Sentinel.UNSET
23+
"""Sentinel used to indicate that a value is not set."""
24+
25+
FLAG_NEEDS_VALUE = Sentinel.FLAG_NEEDS_VALUE
26+
"""Sentinel used to indicate an option was passed as a flag without a
27+
value but is not a flag option.
28+
29+
``Option.consume_value`` uses this to prompt or use the ``flag_value``.
30+
"""
31+
32+
T_UNSET = t.Literal[UNSET] # type: ignore[valid-type]
33+
"""Type hint for the :data:`UNSET` sentinel value."""
34+
35+
T_FLAG_NEEDS_VALUE = t.Literal[FLAG_NEEDS_VALUE] # type: ignore[valid-type]
36+
"""Type hint for the :data:`FLAG_NEEDS_VALUE` sentinel value."""

0 commit comments

Comments
 (0)