Search code examples
pythonargparsecommand-line-interface

Can't get argparse to read quoted string with dashes in it?


Is there a way to make argparse recognize anything between two quotes as a single argument? It seems to keep seeing the dashes and assuming that it's the start of a new option

I have something like:

mainparser = argparse.ArgumentParser()
subparsers = mainparser.add_subparsers(dest='subcommand')
parser = subparsers.add_parser('queue')
parser.add_argument('-env', '--extraEnvVars', type=str,
                        help='String of extra arguments to be passed to model.')
...other arguments added to parser...

But when I run:

python Application.py queue -env "-s WHATEVER -e COOL STUFF"

It gives me:

Application.py queue: error: argument -env/--extraEnvVars: expected one argument

If I leave off the first dash, it works totally fine, but it's kind of crucial that I be able to pass in a string with dashes in it. I've tried escaping it with \ , which causes it to succeed but adds the \ to the argument string Does anyone know how to get around this? This happens whether or not -s is an argument in parser.

EDIT: I'm using Python 2.7.

EDIT2:

python Application.py -env " -env"

works perfectly fine, but

python Application.py -env "-env"

does not.

EDIT3: Looks like this is actually a bug that's being debated already: http://www.gossamer-threads.com/lists/python/bugs/89529, http://python.6.x6.nabble.com/issue9334-argparse-does-not-accept-options-taking-arguments-beginning-with-dash-regression-from-optp-td578790.html. It's only in 2.7 and not in optparse.

EDIT4: The current open bug report is: http://bugs.python.org/issue9334


Solution

  • You can start the argument with a space python tst.py -e ' -e blah' as a very simple workaround. Simply lstrip() the option to put it back to normal, if you like.

    Or, if the first "sub-argument" is not also a valid argument to the original function then you shouldn't need to do anything at all. That is, the only reason that python tst.py -e '-s hi -e blah' doesn't work is because -s is a valid option to tst.py.

    Also, the optparse module, now deprecated, works without any issue.