Martin Thoma
Martin Thoma

Reputation: 136389

Can I have click commands for objects, using inheritance to de-duplicate code?

If you have a look at my lidtk repository, especially the classifiers, you can see that the following files are almost identical (current version in case this is fixed in future):

They all inherit from lidtk.LIDClassifier and they all have the commands

Usage: lidtk <<module name>> [OPTIONS] COMMAND [ARGS]...

  Use the <<module name>> language classifier.

Options:
  --help  Show this message and exit.

Commands:
  get_languages
  predict          
  print_languages
  wili             
  wili_k           
  wili_unk         

Is it possible to de-duplicate the click-code? I would like to use inheritance to de-duplicate the code.

Upvotes: 1

Views: 443

Answers (1)

fpbhb
fpbhb

Reputation: 1519

Glancing just shortly over your repo I think what you want is something like this:

import click

def group_factory(group, name, params):
    """This creates a subcommand 'name' under the existing click command
    group 'group' (which can be the main group), with sub-sub-commands
    'cmd1' and 'cmd2'. 'params' could be something to set the context
    for this group.
    """

    @group.group(name=name)
    def entry_point():
        pass

    @entry_point.command()
    @click.option("--foo")
    def cmd1(foo):
        print("CMD1", name, params, foo)

    @entry_point.command()
    @click.option("--bar")
    def cmd2(bar):
        print("CMD2", name, params, bar)

    return entry_point

You can either use the return value of group_factory as a main entry point in a set of different scripts:

if __name__ == "__main__":
    ep = group_factory(click, "", "something")
    ep()

... or you can use group_factory to repeatedly build the same sub-command hierarchy under some top-level command under different names (and with different params):

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

group_factory(cli, "a", 1)
group_factory(cli, "b", 2)
group_factory(cli, "c", 3)

Upvotes: 1

Related Questions