summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2021-05-19 10:39:53 -0700
committerDavid Lord <davidism@gmail.com>2021-05-19 10:49:02 -0700
commit0db91e220517c767e1e81fd37d1dd7ce83fa77b7 (patch)
tree2196bcf99033d23889da55c1735a89c242c06e04
parent329b1001755452c96dcefcf4a3c799a2463710e0 (diff)
downloadclick-0db91e220517c767e1e81fd37d1dd7ce83fa77b7.tar.gz
return resolved name, not original name
-rw-r--r--CHANGES.rst5
-rw-r--r--docs/advanced.rst6
-rw-r--r--examples/aliases/aliases.py5
-rw-r--r--src/click/core.py2
-rw-r--r--tests/test_commands.py14
5 files changed, 30 insertions, 2 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index b59fc44..6d807d1 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -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
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 7f17e0c..3df492a 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -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:
@@ -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::
diff --git a/examples/aliases/aliases.py b/examples/aliases/aliases.py
index c3da657..af3caa6 100644
--- a/examples/aliases/aliases.py
+++ b/examples/aliases/aliases.py
@@ -67,6 +67,11 @@ class AliasedGroup(click.Group):
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
diff --git a/src/click/core.py b/src/click/core.py
index 63506ba..3a7533b 100644
--- a/src/click/core.py
+++ b/src/click/core.py
@@ -1717,7 +1717,7 @@ class MultiCommand(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
diff --git a/tests/test_commands.py b/tests/test_commands.py
index 79f87fa..9ebf612 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -285,6 +285,10 @@ def test_aliased_command_canonical_name(runner):
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()
@@ -296,6 +300,16 @@ def test_aliased_command_canonical_name(runner):
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)