2

I'm trying to implement a python3 CLI using the docopt package. I'm trying to get my program accept multiple positional input files and, optionally a list of output files. A MWE for my docstring is:

__doc__ = """
    Usage:
        test.py [INPUT...] [-o OUTPUT...] [-t TEST]

    Options:
        -o OUTPUT..., --output OUTPUT...  #One output file for each INPUT file [default: DEFAULT]
        -t TEST, --test TEST              #A test option
"""

For example a programm call as

test.py FILE_A FILE_B -o OUTFILE_A OUTFILE B -t true

Should return a dict:

{'--output': ['OUTFILE_A', 'OUTFILE_B'],
 '--test': 'true',
 'INPUT': ['FILE_A', 'FILE_B']}

but for some reason it is always appended to the INPUT arguments:

{'--output': ['OUTFILE_A'],
 '--test': 'true',
 'INPUT': ['FILE_A', 'FILE_B', 'OUTFILE_B']}
Torilla
  • 307
  • 1
  • 10

1 Answers1

1

Options in Docopt unfortunately can only take one argument, so [-o OUTPUT...] will not work. The remaining elements will as you state be interpreted as additional arguments.

One way around this is to move the ellipsis outside the square brackets:

Usage:
    test.py [INPUT...] [-o OUTPUT]... [-t TEST]

and use it like this:

test.py FILE_A FILE_B -o OUTFILE_A -o OUTFILE_B

It doesn't look as good, but it works.

J. P. Petersen
  • 4,368
  • 3
  • 28
  • 29
  • Not just in Docopt, but in any POSIX-compatible command line program, there is supposed to be only one argument after an option. What's more, the order in which the options occur shouldn't matter. Programs that allow such things are not POSIX-compatible and do their command line parsing in a non-standard way. So the question is whether Docopt should follow the POSIX guidelines or not. A possible workaround is to use commands (keywords) instead of options, because their position matters. – SasQ Mar 25 '21 at 11:07