Search code examples
pythonpython-2.7command-line-interfacepython-click

Make a command available for two groups in python click?


I'm using click to write a cli program in Python, and I need to write something like this:

import click


@click.group()
def root():
    """root"""
    pass


@root.group()
def cli():
    """test"""
    pass


@root.group()
def cli2():
    """test"""
    pass


@cli.command('test1')
@cli2.command('test1')
def test1():
    """test2"""
    print 1234
    return


root()

but this will fail with:

TypeError: Attempted to convert a callback into a command twice.

How can I share the command between multiple groups?


Solution

  • The group.command() decorator is a short cut which performs two functions. One is to create a command, the other is to attach the command to a group.

    So, to share a command with multiple groups, you can decorate the command for one group like:

    @cli.command('test1')
    

    Then, since the command has already been created, you can simply add the click command object to other groups like:

    cli2.add_command(test1)
    

    Test Code:

    import click
    
    
    @click.group()
    def root():
        """root"""
        pass
    
    
    @root.group()
    def cli1():
        click.echo('cli1')
    
    
    @root.group()
    def cli2():
        click.echo('cli2')
    
    
    @cli1.command('test1')
    @click.argument('arg1')
    def test1(arg1):
        click.echo('test1: %s' % arg1)
    
    cli2.add_command(test1)
    
    root('cli2 test1 an_arg'.split())
    

    Results:

    cli2
    test1: an_arg