Would it be possible to support arguments in addtion to options?
sdstewar opened this issue · 5 comments
I have a use case where I'd like to accept a list of items contained in a file given by -f or an arbitrary number of positional arguments. Unfortunately Click only allows this on arguments rather than options. So would it be possible to support a mix of mutually exclusive options and arguments?
click-option-group only works with options. It is currently not possible to mix mutually exclusive options and arguments inside an option group. It's hard to say right now if this feature is possible at all. I need to experiment with this.
That's what I figured but was hoping it'd be "Oh yeah, that's easy!" :)
Our internal dev has standardized on Click and I'm working updating some older tooling. I'll look for an alternative setup but think this would still be a nice feature to have.
BTW, loving the your package so far.
... it'd be "Oh yeah, that's easy!" :)
Things get complicated if we try to do something non-standard in Click. :)
I'll look for an alternative setup
An arbitrary number of positional arguments can be replaced to option with multiple=True
flag. In this case we need to repeat an option name again and again:
-i item1 -i item2 -i item3 ... -i itemN
Yes, I know, it looks verbose, but this is the only way to set an arbitrary number of option values in Click except maybe this (with additional parsing):
-i "item1 item2 item3 ... itemN"
-i item1,item2,item3,itemN
I created an almost working version for it based on latest pip package.
optgrp-arg.diff.txt
Checking with MutuallyExclusiveGroup it's clear that there are missing parts.
I added an option and an argument. If I specify the argument in the command-line, it's fine. But if I specify only the option, the group thinks that the argument is also specified.
I think the 2nd solution suggested by @espdev is pretty reasonable. Otherwise, [shameless plug] you may consider using Cloup (a set of click extensions):
from pathlib import Path
import cloup
from cloup.constraints import mutually_exclusive
@cloup.command()
@cloup.argument("items", nargs=-1, required=False)
@cloup.option("-f", "--file-path", type=cloup.file_path(exists=True))
@cloup.constraint(mutually_exclusive, ["items", "file_path"])
def cmd(items: Tuple[str], file_path: Path):
...
If at least one of the parameters has to be provided, you should use the require_any
constraint instead. See here for more.