diff --git a/CHANGES.rst b/CHANGES.rst index f43ccb5b7..af3a025be 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -26,7 +26,7 @@ Unreleased parallel tests, and Flask smoke tests. :pr:`3151` :pr:`3177` - Show custom ``show_default`` string in prompts, matching the existing help text behavior. :issue:`2836` :pr:`2837` :pr:`3165` :pr:`3262` :pr:`3280` - :pr:`3328`` + :pr:`3328` - Fix ``default=True`` with boolean ``flag_value`` always returning the ``flag_value`` instead of ``True``. The ``default=True`` to ``flag_value`` substitution now only applies to non-boolean flags, where ``True`` acts as a diff --git a/docs/arguments.md b/docs/arguments.md index e5cfcdf52..90d37c156 100644 --- a/docs/arguments.md +++ b/docs/arguments.md @@ -8,7 +8,8 @@ Arguments are: * Are positional in nature. -* Similar to a limited version of {ref}`options ` that can take an arbitrary number of inputs +* Similar to a limited version of {ref}`options ` that + can take an arbitrary number of inputs * {ref}`Documented manually `. Useful and often used kwargs are: @@ -18,7 +19,9 @@ Useful and often used kwargs are: ## Basic Arguments -A minimal {class}`click.Argument` solely takes one string argument: the name of the argument. This will assume the argument is required, has no default, and is of the type `str`. +A minimal {class}`click.Argument` solely takes one string argument: +the name of the argument. This will assume the argument is required, +has no default, and is of the type `str`. Example: @@ -38,17 +41,27 @@ And from the command line: invoke(touch, args=['foo.txt']) ``` -An argument may be assigned a {ref}`parameter type `. If no type is provided, the type of the default value is used. If no default value is provided, the type is assumed to be {data}`STRING`. +An argument may be assigned a {ref}`parameter type `. +If no type is provided, the type of the default value is used. If no +default value is provided, the type is assumed to be {data}`STRING`. ```{admonition} Note on Required Arguments :class: note - It is possible to make an argument required by setting `required=True`. It is not recommended since we think command line tools should gracefully degrade into becoming no ops. We think this because command line tools are often invoked with wildcard inputs and they should not error out if the wildcard is empty. + It is possible to make an argument required by setting + `required=True`. It is not recommended since we think command line + tools should gracefully degrade into becoming no ops. We think this + because command line tools are often invoked with wildcard inputs + and they should not error out if the wildcard is empty. ``` ## Multiple Arguments -To set the number of argument use the `nargs` kwarg. It can be set to any positive integer and -1. Setting it to -1, makes the number of arguments arbitrary (which is called variadic) and can only be used once. The arguments are then packed as a tuple and passed to the function. +To set the number of argument use the `nargs` kwarg. It can be set to +any positive integer and -1. Setting it to -1, makes the number of +arguments arbitrary (which is called variadic) and can only be used +once. The arguments are then packed as a tuple and passed to the +function. ```{eval-rst} .. click:example:: @@ -71,12 +84,17 @@ And from the command line: ```{admonition} Note on Handling Files :class: note - This is not how you should handle files and files paths. This merely used as a simple example. See {ref}`handling-files` to learn more about how to handle files in parameters. + This is not how you should handle files and files paths. This + merely used as a simple example. See {ref}`handling-files` to learn + more about how to handle files in parameters. ``` ## Argument Escape Sequences -If you want to process arguments that look like options, like a file named `-foo.txt` or `--foo.txt` , you must pass the `--` separator first. After you pass the `--`, you may only pass arguments. This is a common feature for POSIX command line tools. +If you want to process arguments that look like options, like a file +named `-foo.txt` or `--foo.txt`, you must pass the `--` separator +first. After you pass the `--`, you may only pass arguments. This is a +common feature for POSIX command line tools. Example usage: @@ -97,7 +115,8 @@ And from the command line: invoke(touch, ['--', '-foo.txt', 'bar.txt']) ``` -If you don't like the `--` marker, you can set ignore_unknown_options to True to avoid checking unknown options: +If you don't like the `--` marker, you can set +`ignore_unknown_options` to `True` to avoid checking unknown options: ```{eval-rst} .. click:example:: @@ -120,7 +139,8 @@ And from the command line: ## Environment Variables -Arguments can use environment variables. To do so, pass the name(s) of the environment variable(s) via `envvar` in `click.argument`. +Arguments can use environment variables. To do so, pass the name(s) of +the environment variable(s) via `envvar` in `click.argument`. Checking one environment variable: diff --git a/docs/commands-and-groups.md b/docs/commands-and-groups.md index 8fc033bf7..1ce93601a 100644 --- a/docs/commands-and-groups.md +++ b/docs/commands-and-groups.md @@ -3,7 +3,10 @@ ```{currentmodule} click ``` -Commands and Groups are the building blocks for Click applications. {class}`Command` wraps a function to make it into a cli command. {class}`Group` wraps Commands and Groups to make them into applications. {class}`Context` is how groups and commands communicate. +Commands and Groups are the building blocks for Click applications. +{class}`Command` wraps a function to make it into a cli command. {class}`Group` +wraps Commands and Groups to make them into applications. {class}`Context` is +how groups and commands communicate. ```{contents} --- @@ -33,7 +36,8 @@ A simple command decorator takes no arguments. ### Renaming Commands -By default the command is the function name with underscores replaced by dashes. To change this pass the desired name into the first positional argument. +By default the command is the function name with underscores replaced by dashes. +To change this pass the desired name into the first positional argument. ```{eval-rst} .. click:example:: @@ -69,7 +73,9 @@ To mark a command as deprecated pass in `deprecated=True` ### Basic Group Example -A group wraps one or more commands. After being wrapped, the commands are nested under that group. You can see that on the help pages and in the execution. By default, invoking the group with no command shows the help page. +A group wraps one or more commands. After being wrapped, the commands are nested +under that group. You can see that on the help pages and in the execution. By +default, invoking the group with no command shows the help page. ```{eval-rst} .. click:example:: @@ -98,11 +104,13 @@ At the command level: invoke(greeting, args=['say-hello', '--help']) ``` -As you can see from the above example, the function wrapped by the group decorator executes unless it is interrupted (for example by calling the help). +As you can see from the above example, the function wrapped by the group +decorator executes unless it is interrupted (for example by calling the help). ### Renaming Groups -To have a name other than the decorated function name as the group name, pass it in as the first positional argument. +To have a name other than the decorated function name as the group name, pass it +in as the first positional argument. ```{eval-rst} .. click:example:: @@ -124,7 +132,11 @@ To have a name other than the decorated function name as the group name, pass it ### Group Invocation Without Command -By default, if a group is passed without a command, the group is not invoked and a command automatically passes `--help`. To change this, pass `invoke_without_command=True` to the group. The context object also includes information about whether or not the group invocation would go to a command nested under it. +By default, if a group is passed without a command, the group is not invoked and +a command automatically passes `--help`. To change this, pass +`invoke_without_command=True` to the group. The context object also includes +information about whether or not the group invocation would go to a command +nested under it. ```{eval-rst} .. click:example:: @@ -177,13 +189,19 @@ Command {ref}`parameters` attached to a command belong only to that command. invoke(greeting) ``` -Additionally parameters for a given group belong only to that group and not to the commands under it. What this means is that options and arguments for a specific command have to be specified *after* the command name itself, but *before* any other command names. +Additionally parameters for a given group belong only to that group and not to +the commands under it. What this means is that options and arguments for a +specific command have to be specified *after* the command name itself, but +*before* any other command names. -This behavior is observable with the `--help` option. Suppose we have a group called `tool` containing a command called `sub`. +This behavior is observable with the `--help` option. Suppose we have a group +called `tool` containing a command called `sub`. - `tool --help` returns the help for the whole program (listing subcommands). - `tool sub --help` returns the help for the `sub` subcommand. -- But `tool --help sub` treats `--help` as an argument for the main program. Click then invokes the callback for `--help`, which prints the help and aborts the program before click can process the subcommand. +- But `tool --help sub` treats `--help` as an argument for the main program. + Click then invokes the callback for `--help`, which prints the help and aborts + the program before click can process the subcommand. ### Arbitrary Nesting @@ -216,7 +234,10 @@ This behavior is observable with the `--help` option. Suppose we have a group ca ### Lazily Attaching Commands -Most examples so far have attached the commands to a group immediately, but commands may be registered later. This could be used to split commands into multiple Python modules. Regardless of how they are attached, the commands are invoked identically. +Most examples so far have attached the commands to a group immediately, but +commands may be registered later. This could be used to split commands into +multiple Python modules. Regardless of how they are attached, the commands are +invoked identically. ```{eval-rst} .. click:example:: @@ -246,8 +267,12 @@ The {class}`Context` object is how commands and groups communicate. ### Auto Envvar Prefix -Automatically built environment variables are supported for options only. To enable this feature, the `auto_envvar_prefix` parameter needs to be passed to the script that is invoked. Each command and parameter is then added as an uppercase underscore-separated variable. If you have a subcommand -called `run` taking an option called `reload` and the prefix is `WEB`, then the variable is `WEB_RUN_RELOAD`. +Automatically built environment variables are supported for options only. To +enable this feature, the `auto_envvar_prefix` parameter needs to be passed to +the script that is invoked. Each command and parameter is then added as an +uppercase underscore-separated variable. If you have a subcommand +called `run` taking an option called `reload` and the prefix is `WEB`, then the +variable is `WEB_RUN_RELOAD`. Example usage: diff --git a/docs/commands.md b/docs/commands.md index 771a9c284..9f4c6e8f9 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -3,7 +3,8 @@ ```{currentmodule} click ``` -In addition to the capabilities covered in the previous section, Groups have more advanced capabilities that leverage the Context. +In addition to the capabilities covered in the previous section, Groups have +more advanced capabilities that leverage the Context. ```{contents} --- diff --git a/docs/options.md b/docs/options.md index 45651abac..5c50d7450 100644 --- a/docs/options.md +++ b/docs/options.md @@ -7,7 +7,8 @@ ``` Adding options to commands can be accomplished with the {func}`option` -decorator. At runtime the decorator invokes the {class}`Option` class. Options in Click are distinct from {ref}`positional arguments `. +decorator. At runtime the decorator invokes the {class}`Option` class. Options +in Click are distinct from {ref}`positional arguments `. Useful and often used kwargs are: @@ -24,7 +25,8 @@ Useful and often used kwargs are: ## Option Decorator -The {func}`option()` decorator is usually passed two positional arguments: the option name and the decorated function argument name. +The {func}`option()` decorator is usually passed two positional arguments: the +option name and the decorated function argument name. ```{eval-rst} .. click:example:: @@ -40,7 +42,10 @@ The {func}`option()` decorator is usually passed two positional arguments: the o invoke(echo, args=['--help']) ``` -However, if the decorated function argument name is not passed in, then Click will try to infer it. A simple way to name the option so that Click will infer it correctly is by taking the function argument, adding two dashes to the front and converting underscores to dashes. +However, if the decorated function argument name is not passed in, then Click +will try to infer it. A simple way to name the option so that Click will infer +it correctly is by taking the function argument, adding two dashes to the front +and converting underscores to dashes. ```{eval-rst} .. click:example:: @@ -55,13 +60,17 @@ However, if the decorated function argument name is not passed in, then Click wi invoke(echo, args=['--string-to-echo', 'Hi!']) ``` -More formally, Click will try to infer the decorated function argument name as follows: +More formally, Click will try to infer the decorated function argument name as +follows: 1. If a positional argument is a valid [Python identifier](https://docs.python.org/3/reference/lexical_analysis.html#identifiers) (and thus does not have dashes), it is chosen. -2. If multiple positional arguments are prefixed with `--`, the first one declared is chosen. +2. If multiple positional arguments are prefixed with `--`, the first one + declared is chosen. 3. Otherwise, the first positional argument prefixed with `-` is chosen. -To get the argument name, the chosen positional argument is converted to lower case, a leading `-` or `--` is removed if found, and any remaining `-` characters are replaced with `_`. +To get the argument name, the chosen positional argument is converted to lower +case, a leading `-` or `--` is removed if found, and any remaining `-` +characters are replaced with `_`. ```{eval-rst} .. list-table:: Examples @@ -88,7 +97,10 @@ To get the argument name, the chosen positional argument is converted to lower c ## Basic Example -A simple {class}`click.Option` takes one option name. By default, it's assumed that the decorated function argument is not required and the expected type is `str`. If the decorated function takes a positional argument but the option is not passed with the command, then `None` is passed. +A simple {class}`click.Option` takes one option name. By default, it's assumed +that the decorated function argument is not required and the expected type is +`str`. If the decorated function takes a positional argument but the option is +not passed with the command, then `None` is passed. ```{eval-rst} .. click:example:: @@ -114,7 +126,8 @@ A simple {class}`click.Option` takes one option name. By default, it's assumed t ## Setting a Default -Instead of setting the `type`, you may set a default and Click will try to infer the type. +Instead of setting the `type`, you may set a default and Click will try to infer +the type. ```{eval-rst} .. click:example:: @@ -131,7 +144,9 @@ Instead of setting the `type`, you may set a default and Click will try to infer ## Multi Value Options -To make an option take multiple values, pass in `nargs`. Note you may pass in any positive integer, but not -1. The values are passed to the decorated function as a tuple. +To make an option take multiple values, pass in `nargs`. Note you may pass in +any positive integer, but not -1. The values are passed to the decorated +function as a tuple. ```{eval-rst} .. click:example:: @@ -156,7 +171,8 @@ To make an option take multiple values, pass in `nargs`. Note you may pass in an ``` By setting `nargs` to a specific number, each item in -the resulting tuple is of the same type. Alternatively, you might want to use different types for different indexes in +the resulting tuple is of the same type. Alternatively, you might want to use +different types for different indexes in the tuple. For this you can directly specify a tuple as `type`: ```{eval-rst} @@ -194,7 +210,10 @@ used. The above example is thus equivalent to this: ## Multiple Options -The multiple options format allows options to take an arbitrary number of arguments (which is called variadic). The arguments are passed to the decorated function as a tuple. If set, `default` must be a list or tuple. Setting a string as `default` will be interpreted as a list of characters. +The multiple options format allows options to take an arbitrary number of +arguments (which is called variadic). The arguments are passed to the decorated +function as a tuple. If set, `default` must be a list or tuple. Setting a string +as `default` will be interpreted as a list of characters. ```{eval-rst} .. click:example:: @@ -213,7 +232,9 @@ The multiple options format allows options to take an arbitrary number of argume ## Counting -To count the occurrence of an option, set `count=True`. If the option is not passed on the command line, then the count is 0. Counting is commonly used for verbosity. +To count the occurrence of an option, set `count=True`. If the option is not +passed on the command line, then the count is 0. Counting is commonly used for +verbosity. ```{eval-rst} .. click:example:: @@ -233,7 +254,9 @@ To count the occurrence of an option, set `count=True`. If the option is not pas ## Boolean -Boolean options (boolean flags) take the values `True` or `False`. The simplest case sets the default value to `False` if the flag is not passed, and `True` if it is. +Boolean options (boolean flags) take the values `True` or `False`. The simplest +case sets the default value to `False` if the flag is not passed, and `True` if +it is. ```{eval-rst} .. click:example:: @@ -256,7 +279,8 @@ Boolean options (boolean flags) take the values `True` or `False`. The simplest ``` -To implement this more explicitly, declare `--{on-option}/--{off-option}`. Click will automatically set `is_flag=True`. +To implement this more explicitly, declare `--{on-option}/--{off-option}`. Click +will automatically set `is_flag=True`. ```{eval-rst} .. click:example:: @@ -280,11 +304,15 @@ To implement this more explicitly, declare `--{on-option}/--{off-option}`. Click Use cases for this more explicit pattern include: -* The default can be dynamic so the user can explicitly specify the option with either on or off option, or pass in no option to use the dynamic default. +* The default can be dynamic so the user can explicitly specify the option with + either on or off option, or pass in no option to use the dynamic default. * Shell scripts sometimes want to be explicit even when it's the default -* Shell aliases can set a flag, then an invocation can add a negation of the flag +* Shell aliases can set a flag, then an invocation can add a negation of the + flag -If a forward slash(`/`) is contained in your option name already, you can split the parameters using `;`. In Windows `/` is commonly used as the prefix character. +If a forward slash(`/`) is contained in your option name already, you can split +the parameters using `;`. In Windows `/` is commonly used as the prefix +character. ```{eval-rst} .. click:example:: @@ -298,7 +326,8 @@ If a forward slash(`/`) is contained in your option name already, you can split ```{versionchanged} 6.0 ``` -If you want to define an alias for the second option only, then you will need to use leading whitespace to disambiguate the format string. +If you want to define an alias for the second option only, then you will need to +use leading whitespace to disambiguate the format string. ```{eval-rst} .. click:example:: @@ -320,7 +349,9 @@ If you want to define an alias for the second option only, then you will need to ## Flag Value -To have a flag pass a value to the decorated 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: +To have a flag pass a value to the decorated 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: ```{eval-rst} .. click:example:: @@ -483,20 +514,32 @@ If a list is passed to `envvar`, the first environment variable found is picked. Variable names are: - [Case-insensitive on Windows but not on other platforms](https://github.com/python/cpython/blob/aa9eb5f757ceff461e6e996f12c89e5d9b583b01/Lib/os.py#L777-L789). - - Not stripped of whitespace and should match the exact name provided to the `envvar` argument. + - Not stripped of whitespace and should match the exact name provided to the + `envvar` argument. -For flag options, there are two concepts to consider: the activation of the flag driven by the environment variable, and the value of the flag if it is activated. +For flag options, there are two concepts to consider: the activation of the flag +driven by the environment variable, and the value of the flag if it is +activated. -The values read from environment variables are always strings and will require extra processing. We need to transform these strings into boolean values that will determine if the flag is activated or not. +The values read from environment variables are always strings and will require +extra processing. We need to transform these strings into boolean values that +will determine if the flag is activated or not. Here are the rules used to parse environment variable values for flag options: - `true`, `1`, `yes`, `on`, `t`, `y` are interpreted as activating the flag - - `false`, `0`, `no`, `off`, `f`, `n` are interpreted as deactivating the flag - - The presence of the environment variable without value is interpreted as deactivating the flag + - `false`, `0`, `no`, `off`, `f`, `n` are interpreted as deactivating the + flag + - The presence of the environment variable without value is interpreted as + deactivating the flag - Empty strings are interpreted as deactivating the flag - - Values are case-insensitive, so the `True`, `TRUE`, `tRuE` strings are all interpreted as activating the flag - - Values are stripped of leading and trailing whitespace before being interpreted, so the `" True "` string is transformed to `"true"` and thus activates the flag - - 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 + - Values are case-insensitive, so the `True`, `TRUE`, `tRuE` strings are all + interpreted as activating the flag + - Values are stripped of leading and trailing whitespace before being + interpreted, so the `" True "` string is transformed to `"true"` and thus + activates the flag + - 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 - Any other value is interpreted as deactivating the flag ```{caution} @@ -505,12 +548,15 @@ For boolean flags with a pair of values, the only recognized environment variabl So an option defined as `--flag\--no-flag`, with a `envvar="FLAG"` parameter, there is no magical `NO_FLAG=` variable that is recognized. Only the `FLAG=` environment variable is recognized. ``` -If the flag is activated, its value is set to `flag_value`. Otherwise, the value defaults to `None`. +If the flag is activated, its value is set to `flag_value`. Otherwise, the value +defaults to `None`. ## Multiple Options from Environment Values As options can accept multiple values, pulling in such values from -environment variables (which are strings) is a bit more complex. Click handles this by deferring customization of the behavior to the `type`. For both `multiple` and `nargs` with values other than +environment variables (which are strings) is a bit more complex. Click handles +this by deferring customization of the behavior to the `type`. For both +`multiple` and `nargs` with values other than `1`, Click will invoke the {meth}`ParamType.split_envvar_value` method to perform the splitting. @@ -541,7 +587,9 @@ every colon (`:`), and for Windows, splitting on every semicolon (`;`). ## Other Prefix Characters -Click can deal with prefix characters besides `-` for options, including `/` and `+`, as well as others. Note that alternative prefix characters are generally used very sparingly if at all within POSIX. +Click can deal with prefix characters besides `-` for options, including `/` and +`+`, as well as others. Note that alternative prefix characters are generally +used very sparingly if at all within POSIX. ```{eval-rst} .. click:example:: @@ -557,7 +605,8 @@ Click can deal with prefix characters besides `-` for options, including `/` and invoke(chmod, args=['-w']) ``` -There are special considerations for using `/` as prefix character. See {ref}`option-boolean-flag` for more. +There are special considerations for using `/` as prefix character. See +{ref}`option-boolean-flag` for more. (optional-value)= diff --git a/docs/testing.md b/docs/testing.md index c7390adbe..73f88f547 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -4,7 +4,8 @@ .. currentmodule:: click.testing ``` -Click provides the {ref}`click.testing ` module to help you invoke command line applications and check their behavior. +Click provides the {ref}`click.testing ` module to help you invoke +command line applications and check their behavior. These tools should only be used for testing since they change the entire interpreter state for simplicity. They are not thread-safe! @@ -20,7 +21,9 @@ The examples use [pytest](https://docs.pytest.org/en/stable/) style tests. The key pieces are: - {class}`CliRunner` - used to invoke commands as command line scripts. - - {class}`Result` - returned from {meth}`CliRunner.invoke`. Captures output data, exit code, optional exception, and captures the output as bytes and binary data. + - {class}`Result` - returned from {meth}`CliRunner.invoke`. Captures output + data, exit code, optional exception, and captures the output as bytes and + binary data. ```{code-block} python :caption: hello.py @@ -48,7 +51,8 @@ def test_hello_world(): ## Subcommands -A subcommand name must be specified in the `args` parameter {meth}`CliRunner.invoke`: +A subcommand name must be specified in the `args` parameter +{meth}`CliRunner.invoke`: ```{code-block} python :caption: sync.py @@ -81,7 +85,8 @@ def test_sync(): ## Context Settings -Additional keyword arguments passed to {meth}`CliRunner.invoke` will be used to construct the initial {class}`Context object `. +Additional keyword arguments passed to {meth}`CliRunner.invoke` will be used to +construct the initial {class}`Context object `. For example, setting a fixed terminal width equal to 60: ```{code-block} python @@ -114,7 +119,8 @@ def test_sync(): ## File System Isolation -The {meth}`CliRunner.isolated_filesystem` context manager sets the current working directory to a new, empty folder. +The {meth}`CliRunner.isolated_filesystem` context manager sets the current +working directory to a new, empty folder. ```{code-block} python :caption: cat.py @@ -167,7 +173,8 @@ def test_cat_with_path_specified(): ## Input Streams -The test wrapper can provide input data for the input stream (stdin). This is very useful for testing prompts. +The test wrapper can provide input data for the input stream (stdin). This is +very useful for testing prompts. ```{code-block} python :caption: prompt.py diff --git a/src/click/_termui_impl.py b/src/click/_termui_impl.py index 0c6e3753f..c9f1e1c53 100644 --- a/src/click/_termui_impl.py +++ b/src/click/_termui_impl.py @@ -380,9 +380,8 @@ def pager(generator: cabc.Iterable[str], color: bool | None = None) -> None: # Split using POSIX mode (the default) so that quote characters are # stripped from tokens and quoted Windows paths are preserved. - # posix=False was rejected (PR #1477) because it retains quotes in - # tokens, and the shlex.quote approach was also reverted (PR #1543). - # See also: issue #1026, PR #2775. + # Non-POSIX mode retains quotes in tokens, and wrapping tokens + # with shlex.quote re-introduces quoting issues on Windows. pager_cmd_parts = shlex.split(os.environ.get("PAGER", "")) if pager_cmd_parts: if WIN: @@ -623,7 +622,7 @@ def edit_files(self, filenames: cabc.Iterable[str]) -> None: try: # Split in POSIX mode (the default) for the same reasons as # in pager(): strips quotes from tokens and preserves quoted - # Windows paths. See issue #1026, PR #1477. + # Windows paths. c = subprocess.Popen( args=shlex.split(editor) + list(filenames), env=environ, diff --git a/src/click/core.py b/src/click/core.py index 0170d60f8..d940dd80e 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -2916,31 +2916,29 @@ def to_info_dict(self) -> dict[str, t.Any]: def get_default( self, ctx: Context, call: bool = True ) -> t.Any | t.Callable[[], t.Any] | None: - """For non-boolean flag options, ``default=True`` is treated as a - sentinel meaning "activate this flag by default" and is resolved to - :attr:`flag_value`. This resolution is performed lazily here (rather - than eagerly in :meth:`__init__`) to prevent callable ``flag_value`` - values (like classes) from being instantiated prematurely. + """Return the default value for this option. - For example, with ``--upper/--lower`` feature switches where - ``flag_value="upper"`` and ``default=True``, the default resolves - to ``"upper"``. + For non-boolean flag options, ``default=True`` is treated as a sentinel + meaning "activate this flag by default" and is resolved to + :attr:`flag_value`. For example, with ``--upper/--lower`` feature + switches where ``flag_value="upper"`` and ``default=True``, the default + resolves to ``"upper"``. .. caution:: - This substitution only applies to **non-boolean** flags + This substitution only applies to non-boolean flags (:attr:`is_bool_flag` is ``False``). For boolean flags, ``True`` is - not a sentinel but a legitimate Python value, so ``default=True`` is - returned as-is. Without this distinction, ``flag_value=False, - default=True`` would silently always return ``False``, regardless of - whether the flag was passed or not. + a legitimate Python value and ``default=True`` is returned as-is. .. versionchanged:: 8.3.3 ``default=True`` is no longer substituted with ``flag_value`` for - boolean flags, fixing negative boolean flags like ``flag_value=False, - default=True``. + boolean flags, fixing negative boolean flags like + ``flag_value=False, default=True``. """ value = super().get_default(ctx, call=False) + # Resolve default=True to flag_value lazily (here instead of + # __init__) to prevent callable flag_values (like classes) from + # being instantiated by the callable check below. if value is True and self.is_flag and not self.is_bool_flag: value = self.flag_value elif call and callable(value): diff --git a/src/click/testing.py b/src/click/testing.py index 0e2e53a0d..04e7f1d92 100644 --- a/src/click/testing.py +++ b/src/click/testing.py @@ -479,9 +479,6 @@ def _patched_pdb_init( arguments are honored and not overridden. Debuggers that do not subclass ``pdb.Pdb`` (pudb, debugpy) are not covered. - - See: https://github.com/pallets/click/issues/654 and - https://github.com/pallets/click/issues/824 """ if stdin is None: stdin = sys.__stdin__