python - How can I create an argparse mutually exclusive group with multiple positional parameters? -


i'm trying parse command-line arguments such 3 possibilities below possible:

script script file1 file2 file3 … script -p pattern 

thus, list of files optional. if -p pattern option specified, nothing else can on command line. said in "usage" format, this:

script [-p pattern | file [file …]] 

i thought way python's argparse module this:

parser = argparse.argumentparser(prog=base) group = parser.add_mutually_exclusive_group() group.add_argument('-p', '--pattern', help="operate on files match glob pattern") group.add_argument('files', nargs="*", help="files operate on") args = parser.parse_args() 

but python complains positional argument needs optional:

traceback (most recent call last):   file "script", line 92, in <module>     group.add_argument('files', nargs="*", help="files operate on") … valueerror: mutually exclusive arguments must optional 

but argparse documentation says "*" argument nargs meant optional.

i haven't been able find other value nargs trick either. closest i've come using nargs="?", grabs 1 file, not optional list of number.

is possible compose kind of argument syntax using argparse?

short answer

add default * positional

long

the code raising error is,

    if action.required:         msg = _('mutually exclusive arguments must optional')         raise valueerror(msg) 

if add * parser, see required attribute set:

in [396]: a=p.add_argument('bar',nargs='*') in [397]: out[397]: _storeaction(option_strings=[], dest='bar', nargs='*', const=none, default=none, type=none, choices=none, help=none, metavar=none) in [398]: a.required out[398]: true 

while ? false. i'll have dig bit further in code see why difference. bug or overlooked 'feature', or there might reason. tricky thing 'optional' positionals no-answer answer, is, empty list of values valid.

in [399]: args=p.parse_args([]) in [400]: args out[400]: namespace(bar=[], ....) 

so mutually_exclusive has have way distinguish between default [] , real [].

for i'd suggest using --files, flagged argument rather positional 1 if expect argparse perform mutually exclusive testing.


the code sets required attribute of positional is:

    # mark positional arguments required if @ least 1     # required     if kwargs.get('nargs') not in [optional, zero_or_more]:         kwargs['required'] = true     if kwargs.get('nargs') == zero_or_more , 'default' not in kwargs:         kwargs['required'] = true 

so solution specify default *

in [401]: p=argparse.argumentparser() in [402]: g=p.add_mutually_exclusive_group() in [403]: g.add_argument('--foo') out[403]: _storeaction(option_strings=['--foo'], dest='foo', nargs=none, const=none, default=none, type=none, choices=none, help=none, metavar=none) in [404]: g.add_argument('files',nargs='*',default=none) out[404]: _storeaction(option_strings=[], dest='files', nargs='*', const=none, default=none, type=none, choices=none, help=none, metavar=none) in [405]: p.parse_args([]) out[405]: namespace(files=[], foo=none) 

the default []. parser able distinguish between default provide , 1 uses if none given.

oops - default=none wrong. passes add_argument , required test, produces mutually_exclusive error. details lie in how code distinguishes between user defined defaults , automatic ones. use none.

i don't see in documentation this. i'll have check bug/issues see topic has been discussed. it's come on before well.


Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -