Search code examples
pythondocopt

Docopt accepts multi args in middle?


I want my script accepts command line args like "cp" command does:

'''
Usage:
cp.py <source>... <directory>
cp.py -t <directory> <source>...
cp.py -s <source>... -t <directory>
'''

Those command line

$ python cp.py src/path/1 src/path/2 target/path
$ python cp.py -t target/path src/path/1 src/path/2
$ python cp.py -s src/path/1 src/path/2 -t target/path

will get the same result:

{'<source>':['src/path/1', 'src/path/2'],'<directory>': 'target/path'}

Thx very much. And sorry for my English:)


Solution

  • Currently not supported

    You are not the only one dreaming of such feature, see docopt issue #190 Repeating positional arguments followed by a single positional argument

    Ambiguity of repeating argument followed by an option

    Options following repeating positional argument make parsing ambiguous. Imagine a file, having the same name as command option - how you would specify it and what would you expect as result?

    Proposed alternatives (changing command line design)

    I will assume, you prefer to place target directory to the end to make it intuitive to user.

    Repeated options with values

    Usage:
        cp.py  (-s <source>)... -t <directory>
    

    This allows one target directory and multiple source.

    Put repeated argument as last one

    Usage:
        cp.py <directory> <source>...
    

    this breaks the preference of target being as last one, but is quite easy.

    Conclusions

    • Current docopt does not currently support the style, cp is using. One reason is that it is not easy, another that cp is sometime too complex and even ambiguous.
    • using repeated argument followed by options is always tricky, try to avoid that.
    • Options are to be optional, so using options, which are required is contradicting this rule for easy to use command line programs.
    • Currently, my preference would be using target argument as first positional one followed by repeated source positional arguments.
    • It would be nice, if docopt would allow multiple positional argument followed by fixed set of positional arguments, but this is currently not implemented.