1

Assuming I have the following parser:

def parse():
    p = ArgumentParser()
    p.add_argument('-c', 'client', help='')
    p.add_argument('-s', 'server', help='')
    args = vars(p.parse_args())
    return args

I have to call it with python my_script.py -s bla -c bla. I would like to add a third option, that will combine both of them, allowing me to call python my_script.py -x bla and to get {'s': 'bla, 'c': 'bla'} from the function, just like I would have got from the first call.

How can I do that?


I can do the opposite, i.e. create 2 args that will have the same name:

In [14]: p.add_argument('--x', dest='z') 
    ...: p.add_argument('--y', dest='z') 
    ...: p.parse_args('--x 1 --y 2'.split())                                                                                                
Out[14]: Namespace(z='2')

but that doesn't really help me...


This is not a dup. I don't want to pass a list. I already have the 2 options, and I want them to stay. I just want to have a third option that combines them. Using a list would make me dup my input, like this python my_script.py --list_param bla bla where I want python my_script.py --x bla

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • 1
    Why can't you just use a bunch of `if,then` logic after parsing the args? – Him Aug 13 '19 at 21:52
  • Possible duplicate of [argparse option for passing a list as option](https://stackoverflow.com/questions/15753701/argparse-option-for-passing-a-list-as-option) – Aero Blue Aug 13 '19 at 21:57
  • Just define the '-x' like the others, and after parsing assign its value to 'c' and 's' (with suitable conditions). – hpaulj Aug 13 '19 at 22:29

1 Answers1

1

There is no support in argparse directly for what you want, but you could get it by registering a custom action:

class BothAction(argparse.Action):

    def __call__(self, parser, namespace, val, option_string=None):
        setattr(namespace, "client", val)
        setattr(namespace, "server", val)
        del namespace.x

...

parser.register("action", "both", BothAction)
parser.add_argument('-x', action="both")

This can be polished, but I hope you get the basic idea.

wim
  • 338,267
  • 99
  • 616
  • 750
  • That is great!! I actually looked at the 'resolve' strategy for conflicts, and hoped something like this would be there. – CIsForCookies Aug 13 '19 at 22:28
  • Depending on how much you trust your users ability to self-debug, you may want to add some mutually-exclusive logic, like https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_mutually_exclusive_group – Cireo Aug 13 '19 at 22:31
  • not relevant here, but it is a nice option I use from time to time – CIsForCookies Aug 14 '19 at 04:44