Skip to content

Commit

Permalink
Merge pull request #1915 from pallets/command-name
Browse files Browse the repository at this point in the history
return resolved name, not original name
  • Loading branch information
davidism committed May 19, 2021
2 parents 329b100 + 0db91e2 commit 1b49159
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -20,6 +20,11 @@ Unreleased
regular options do from ``default``. :issue:`1886`
- Added documentation that custom parameter types may be passed
already valid values in addition to strings. :issue:`1898`
- Resolving commands returns the name that was given, not
``command.name``, fixing an unintended change to help text and
``default_map`` lookups. When using patterns like ``AliasedGroup``,
override ``resolve_command`` to change the name that is returned if
needed. :issue:`1895`


Version 8.0.0
Expand Down
6 changes: 5 additions & 1 deletion docs/advanced.rst
Expand Up @@ -35,7 +35,6 @@ it would accept ``pus`` as an alias (so long as it was unique):
.. click:example::
class AliasedGroup(click.Group):

def get_command(self, ctx, cmd_name):
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
Expand All @@ -48,6 +47,11 @@ it would accept ``pus`` as an alias (so long as it was unique):
return click.Group.get_command(self, ctx, matches[0])
ctx.fail(f"Too many matches: {', '.join(sorted(matches))}")

def resolve_command(self, ctx, args):
# always return the full command name
_, cmd, args = super().resolve_command(ctx, args)
return cmd.name, cmd, args

And it can then be used like this:

.. click:example::
Expand Down
5 changes: 5 additions & 0 deletions examples/aliases/aliases.py
Expand Up @@ -67,6 +67,11 @@ def get_command(self, ctx, cmd_name):
return click.Group.get_command(self, ctx, matches[0])
ctx.fail(f"Too many matches: {', '.join(sorted(matches))}")

def resolve_command(self, ctx, args):
# always return the command's name, not the alias
_, cmd, args = super().resolve_command(ctx, args)
return cmd.name, cmd, args


def read_config(ctx, param, value):
"""Callback that is used whenever --config is passed. We use this to
Expand Down
2 changes: 1 addition & 1 deletion src/click/core.py
Expand Up @@ -1717,7 +1717,7 @@ def resolve_command(
if split_opt(cmd_name)[0]:
self.parse_args(ctx, ctx.args)
ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name))
return cmd.name if cmd else None, cmd, args[1:]
return cmd_name if cmd else None, cmd, args[1:]

def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]:
"""Given a context and a command name, this returns a
Expand Down
14 changes: 14 additions & 0 deletions tests/test_commands.py
Expand Up @@ -285,6 +285,10 @@ class AliasedGroup(click.Group):
def get_command(self, ctx, cmd_name):
return push

def resolve_command(self, ctx, args):
_, command, args = super().resolve_command(ctx, args)
return command.name, command, args

cli = AliasedGroup()

@cli.command()
Expand All @@ -296,6 +300,16 @@ def push():
assert result.output.startswith("Usage: root push [OPTIONS]")


def test_group_add_command_name(runner):
cli = click.Group("cli")
cmd = click.Command("a", params=[click.Option(["-x"], required=True)])
cli.add_command(cmd, "b")
# Check that the command is accessed through the registered name,
# not the original name.
result = runner.invoke(cli, ["b"], default_map={"b": {"x": 3}})
assert result.exit_code == 0


def test_unprocessed_options(runner):
@click.command(context_settings=dict(ignore_unknown_options=True))
@click.argument("args", nargs=-1, type=click.UNPROCESSED)
Expand Down

0 comments on commit 1b49159

Please sign in to comment.