Skip to content

Commit

Permalink
Add result callback invocation for subcommands
Browse files Browse the repository at this point in the history
  • Loading branch information
IamCathal committed Aug 5, 2020
1 parent 228ca13 commit 7b763f7
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Unreleased
matched name. This makes behavior such as help text and
``Context.invoked_subcommand`` consistent when using patterns like
``AliasedGroup``. :issue:`1422`
- Add result callback invocation for subcommands. :issue:`1178`


Version 7.1.2
Expand Down
16 changes: 4 additions & 12 deletions src/click/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ def format_options(self, ctx, formatter):
self.format_commands(ctx, formatter)

def resultcallback(self, replace=False):
"""Adds a result callback to the chain command. By default if a
"""Adds a result callback to the a command. By default if a
result callback is already registered this will chain them but
this can be disabled with the `replace` parameter. The result
callback is invoked with the return value of the subcommand
Expand Down Expand Up @@ -1258,15 +1258,10 @@ def _process_result(value):
return value

if not ctx.protected_args:
# If we are invoked without command the chain flag controls
# how this happens. If we are not in chain mode, the return
# value here is the return value of the command.
# If however we are in chain mode, the return value is the
# return value of the result processor invoked with an empty
# list (which means that no subcommand actually was executed).
# The return value is the return value of the result processor
# invoked with an empty list (which means that no subcommand
# was actually executed).
if self.invoke_without_command:
if not self.chain:
return Command.invoke(self, ctx)
with ctx:
Command.invoke(self, ctx)
return _process_result([])
Expand All @@ -1277,9 +1272,6 @@ def _process_result(value):
ctx.args = []
ctx.protected_args = []

# If we're not in chain mode, we only allow the invocation of a
# single command but we also inform the current context about the
# name of the command to invoke.
if not self.chain:
# Make sure the context is entered so we do not clean up
# resources until the result processor has worked.
Expand Down
17 changes: 17 additions & 0 deletions tests/test_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ def bdist(format):
assert result.output.splitlines() == ["bdist called 1", "sdist called 2"]


def test_resultcallback(runner):
@click.group(invoke_without_command=True)
def cli():
pass

@cli.command()
def sub():
return "Sub"

@cli.resultcallback()
def process_result(result):
print("Subcommands invoked:", result)

result = runner.invoke(cli, [])
assert result.output == "Subcommands invoked: []\n"


def test_chaining_with_arguments(runner):
@click.group(chain=True)
def cli():
Expand Down

0 comments on commit 7b763f7

Please sign in to comment.