Skip to content

Commit

Permalink
Allow adding dynamic parameters to every Context
Browse files Browse the repository at this point in the history
  • Loading branch information
ofek committed Sep 28, 2024
1 parent 4a758f5 commit f8c5852
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Unreleased
- When generating a command's name from a decorated function's name, the
suffixes ``_command``, ``_cmd``, ``_group``, and ``_grp`` are removed.
:issue:`2322`
- Add ``dynamic_params`` property to ``Context``. :pr:`2784`


Version 8.1.8
Expand Down Expand Up @@ -619,7 +620,7 @@ Released 2018-09-25
- Wrap ``click.Choice``'s missing message. :issue:`202`, :pr:`1000`
- Add native ZSH autocompletion support. :issue:`323`, :pr:`865`
- Document that ANSI color info isn't parsed from bytearrays in Python
2. :issue:`334`
1. :issue:`334`
- Document byte-stripping behavior of ``CliRunner``. :issue:`334`,
:pr:`1010`
- Usage errors now hint at the ``--help`` option. :issue:`393`,
Expand Down
18 changes: 15 additions & 3 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ class Context:
value is not set, it defaults to the value from the parent
context. ``Command.show_default`` overrides this default for the
specific command.
:param dynamic_params: A list of :class:`Parameter` objects that the
attached command will use.
.. versionchanged:: 8.2
Added the ``dynamic_params`` parameter.
.. versionchanged:: 8.2
The ``protected_args`` attribute is deprecated and will be removed in
Expand Down Expand Up @@ -278,6 +283,7 @@ def __init__(
token_normalize_func: t.Callable[[str], str] | None = None,
color: bool | None = None,
show_default: bool | None = None,
dynamic_params: list[Parameter] | None = None,
) -> None:
#: the parent context or `None` if none exists.
self.parent = parent
Expand Down Expand Up @@ -425,6 +431,12 @@ def __init__(
#: Show option default values when formatting help text.
self.show_default: bool | None = show_default

if dynamic_params is None:
dynamic_params = []

#: Allow for dynamic parameters.
self.dynamic_params: list[Parameter] = dynamic_params

self._close_callbacks: list[t.Callable[[], t.Any]] = []
self._depth = 0
self._parameter_source: dict[str, ParameterSource] = {}
Expand Down Expand Up @@ -951,11 +963,11 @@ def get_usage(self, ctx: Context) -> str:
return formatter.getvalue().rstrip("\n")

def get_params(self, ctx: Context) -> list[Parameter]:
rv = self.params
help_option = self.get_help_option(ctx)
rv = [*self.params, *ctx.dynamic_params]

help_option = self.get_help_option(ctx)
if help_option is not None:
rv = [*rv, help_option]
rv.append(help_option)

return rv

Expand Down
14 changes: 14 additions & 0 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,17 @@ def cli():
assert rv.exit_code == 1
assert isinstance(rv.exception.__cause__, exc)
assert rv.exception.__cause__.args == ("catch me!",)


def test_dynamic_params(runner):
def callback(ctx, p, v):
ctx.dynamic_params.append(click.Option([f"--{v}"]))
return v

@click.command()
@click.option("--dyn", required=True, is_eager=True, callback=callback)
def command(dyn, **kwargs):
assert dyn in kwargs
assert kwargs[dyn] == "bar"

runner.invoke(command, ["--dyn", "foo", "--foo", "bar"])

0 comments on commit f8c5852

Please sign in to comment.