Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python click, make option value optional

I am working on a small command line tool using Python 2 and click. My tool either needs to write a value, read it, or do not change it. It would be nice if I could do the following:

mytool --r0=0xffff..........Set value r0 to 0xffff
mytool --r0......................Read value r0
mytool...............................Don't do anything with r0

Based on the documentation, it doesn't seem possible, but I could have missed it. So is it possible or do I have to find a different approach?

like image 423
flashburn Avatar asked Oct 18 '22 22:10

flashburn


1 Answers

Building on @Stephen Rauch's answer, I think I found a simpler solution

Code

class CommandWithOptionalFlagValues(click.Command):
    def parse_args(self, ctx, args):
        """ Translate any flag `--opt=value` as flag `--opt` with changed flag_value=value """
        # filter flags
        flags = [o for o in self.params if o.is_flag and not isinstance(o.flag_value, bool)]
        prefixes = {p: o for o in flags for p in o.opts if p.startswith('--')}
        for i, flag in enumerate(args):
            flag = flag.split('=')
            if flag[0] in prefixes and len(flag) > 1:
                prefixes[flag[0]].flag_value = flag[1]
                args[i] = flag[0]

        return super(CommandWithOptionalFlagValues, self).parse_args(ctx, args)

Test

@click.command(cls=CommandWithOptionalFlagValues)
@click.option('--r0', is_flag=True, help='set or use default r0 value', flag_value=3.0)
@click.option('--r1', is_flag=True, help='Enable r1')
def cli(r0, r1):
    click.echo('r0: {} r1: {}'.format(r0, r1))

cli(['--r1'])
cli(['--r0', '--r1'])
cli(['--r0=5.0'])

Result

r0: None r1: True
r0: 3.0 r1: True
r0: 5.0 r1: False
like image 156
abhitopia Avatar answered Oct 21 '22 05:10

abhitopia