PolarBearITS PolarBearITS - 1 month ago 12
Python Question

Trouble implementing repeating elements in docopt

I'm using

docopt
to parse command line input in python. I have my docstring:

"""
Usage:
docoptTest.py [options]

Options:
-h --help show this help message and exit
-n --name <name> The name of the specified person
"""


Then I import docopt and parse the arguments and print them:

from docopt import docopt
args = docopt(__doc__)
print(args)

>>> python docoptTest.py -n asdf
{'--help': False,
'--name': 'asdf'}


I tried putting ellipses to allow to input more than one name:

-n --name <name>... The name of the specified person


But I got a usage error. Then I put the ellipses in the initial usage message:

"""
Usage:
docoptTest.py [-n | --name <name>...] [options]

Options:
-h --help show this help message and exit
-n --name The name of the specified person
"""


But the output thinks that
--name
is a flag.

>>> python docoptTest.py -n asdf asdf
{'--help': False,
'--name': True,
'<name>': ['asdf', 'asdf']}


How do I fix this?

Answer

This notation:

>>> python docoptTest.py -n asdf asdf

will probably not work with docopt, as each option takes only one argument. If you want to to do it like this, then you could use some kind of separator, for example a comma, and then split it yourself. The problem arises if you add an argument, then the parser wouldn't be able to distinguish the last asdf as an part of the option or an argument. Some people also put an = between the option and its argument.

Maybe you could try this instead:

Usage:
  docoptTest.py [-n|--name <name>]... [options]

Options:
  -h --help                show this help message and exit
  -n --name <name>         The name of the specified person

This is a quite common way of doing something very similar. The docopt dictionary would look like this:

$python docoptTest.py -n asdf -n ads
{'--help': False,
 '--name': ['asdf', 'ads']}
$python docoptTest.py --name asdf --name ads
{'--help': False,
 '--name': ['asdf', 'ads']}