0

Say I have a function created not by def but by a partial() call (or even just by assignment). In the example below, how can I add bar as a click sub-command to the cli group? I can't use the decorator approach (as with foo). My failed approaches are shown below in-line.

import functools
import click


@click.group()
def cli():
    pass


@cli.command()
def foo(myname="foo"):
    print(f"I am {myname}")


bar = functools.partial(foo, myname="bar")

# this has no effect
# cli.command(bar)

# results in: AttributeError: 'functools.partial' object has no attribute 'name'
# cli.add_command(bar)

# results in: AttributeError: 'functools.partial' object has no attribute 'hidden'
# cli.add_command(bar, name="bar")

if __name__ == "__main__":
    cli()


UPDATE: Actually, it looks like the partial is the culprit here. This answer in a different but related thread, points out that partial objects are "missing certain attributes, specifically __module__ and __name__".

1 Answer 1

1

I think you're missing the fact that the @command decorator turns the foo function into a Command that uses the original foo as callback. The original function is still accessible as foo.callback but foo is a Command. Still, you can't use a partial object as callback because it lacks __name__, but you can work around that passing the name explicitly:

bar = functools.partial(foo.callback, myname="bar")
cli.command("bar")(bar)

# Alternative:
cli.add_command(click.Command("bar", callback=bar))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.