Search code examples
pythonparsingargparse

argparse key=value parameters


This first link has the same question in the first section, but it is unanswered (python argparse: parameter=value). And this second question is similar, but I can't seem to get it working for my particular case ( Using argparse to parse arguments of form "arg= val").

So my situation is this -- I am re-writing a Python wrapper which is used by many other scripts (I would prefer not to modify these other scripts). Currently, the Python wrapper is called with command line arguments of the form --key=value for a number of different arguments, but was parsed manually. I would like to parse them with argparse.

N.B. The argument names are unwieldy, so I am renaming using the dest option in add_argument.

parser = argparse.ArgumentParser(description='Wrappin Ronnie Reagan')
parser.add_argument("--veryLongArgName1", nargs=1, dest="arg1", required=True)
parser.add_argument("--veryLongArgName2", nargs=1,   dest="arg2")
parser.add_argument("--veryLongArgName3", nargs=1,  dest="arg3")
userOpts = vars(parser.parse_args())

Which, while apparently parsing the passed command lines correctly, displays this as the help:

usage: testing_argsparse.py [-h] --veryLongArgName1 ARG1
                        [--veryLongArgName2 ARG2]
                        [--veryLongArgName3 ARG3]
testing_argsparse.py: error: argument --veryLongArgName1 is required

But what I want is that all parameters are specified with the --key=value format, not --key value. i.e.

usage: testing_argsparse.py [-h] --veryLongArgName1=ARG1
                        [--veryLongArgName2=ARG2]
                        [--veryLongArgName3=ARG3]
testing_argsparse.py: error: argument --veryLongArgName1 is required

Solution

  • A little late but for anyone with a similar request as the OP you could use a custom HelpFormatter.

    class ArgFormatter(argparse.HelpFormatter):
        def _format_args(self, *args):
            result = super(ArgFormatter, self)._format_args(*args)
            return result and '%%%' + result
    
        def _format_actions_usage(self, *args):
            result = super(ArgFormatter, self)._format_actions_usage(*args)
            return result and result.replace(' %%%', '=')
    

    This can then be passed to ArgumentParser to give the wanted behavior.

    parser = argparse.ArgumentParser(
        description='Wrappin Ronnie Reagan',
        formatter_class=ArgFormatter)
    

    This intercepts the args (ARG1, ARG2, ...) and adds a custom prefix which is later replaced (along with the unwanted space) for an = symbol. The and in the return statements makes sure to only modify the result if it's non-empty.