Discussion:
[argparse] mutually exclusive group with 2 sets of options
Francois Lafont
2013-08-04 02:10:35 UTC
Permalink
Hi,

Is it possible with argparse to have this syntax for a script?

my-script (-a -b VALUE-B | -c -d VALUE-D)

I would like to do this with the argparse module.

Thanks in advance.
--
Fran?ois Lafont
Francois Lafont
2013-08-05 02:05:53 UTC
Permalink
Hello,

Up. ;-)
Post by Francois Lafont
Is it possible with argparse to have this syntax for a script?
my-script (-a -b VALUE-B | -c -d VALUE-D)
I would like to do this with the argparse module.
Thanks in advance.
I have found this post:
https://groups.google.com/forum/#!searchin/argparse-users/exclusive/argparse-users/-o6GOwhCjbQ/m-PfL4OxLAIJ

It was in 2011 and at that time, it was impossible to have the syntax above. I have the impression that it's impossible now yet. Am I wrong?

If it's impossible yet, I could try a hack. With some checks, I think I could have the "(-a -b VALUE-B | -c -d VALUE-D)" behavior but I would like this syntax appear in the help output too and I have no idea to do it.
--
Fran?ois Lafont
Joshua Landau
2013-08-05 03:53:43 UTC
Permalink
Post by Francois Lafont
Hello,
Up. ;-)
Post by Francois Lafont
Is it possible with argparse to have this syntax for a script?
my-script (-a -b VALUE-B | -c -d VALUE-D)
I would like to do this with the argparse module.
Thanks in advance.
https://groups.google.com/forum/#!searchin/argparse-users/exclusive/argparse-users/-o6GOwhCjbQ/m-PfL4OxLAIJ
It was in 2011 and at that time, it was impossible to have the syntax
above. I have the impression that it's impossible now yet. Am I wrong?
If it's impossible yet, I could try a hack. With some checks, I think I
could have the "(-a -b VALUE-B | -c -d VALUE-D)" behavior but I would like
this syntax appear in the help output too and I have no idea to do it.
If possible you could try docopt. That should be able to do it quite easily.

You could write literally:

My-Script

Usage:
my-script (-a -b VALUE-B | -c -d VALUE-D)

Options:
-b VALUE-B Description
-d VALUE-D Description

as the grammar, but:

My-Script

Usage:
my-script -a -b VALUE-B
my-script -c -d VALUE-D

Options:
-b VALUE-B Description
-d VALUE-D Description

would be preferred.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20130805/a2adf44a/attachment.html>
Miki Tebeka
2013-08-05 14:11:01 UTC
Permalink
Post by Francois Lafont
Is it possible with argparse to have this syntax for a script?
my-script (-a -b VALUE-B | -c -d VALUE-D)
I would like to do this with the argparse module.
You can probably do something similar using sub commands (http://docs.python.org/2/library/argparse.html#sub-commands).
Joseph L. Casale
2013-08-05 17:11:30 UTC
Permalink
Post by Miki Tebeka
You can probably do something similar using sub commands
(http://docs.python.org/2/library/argparse.html#sub-commands).
The problem here is that argparse does not pass the subparser into the
parsed args and shared args between subparsers need to be declared
each time. Come execution time, when you have shared args you end
up testing for various incantations of the invoked code, you're better
off omitting subparsers and performing conditional tests after parsing
for incompatible combinations.

It's a waste of typing to write out a mode followed by params to achieve
the ops goal, I've hit the same limitation. Certainly a weakness of argparse
in my opinion. It's also a tough sell to force a user to install a package just
for the cli if you go with docopt. I'd love to see argparse expand or docopt
get included...

jlc
Francois Lafont
2013-08-05 22:13:16 UTC
Permalink
Post by Miki Tebeka
You can probably do something similar using sub commands (http://docs.python.org/2/library/argparse.html#sub-commands).
Yes, but this is not the same syntax. I want this syntax :

my-script (-a -b VALUE-B | -c -d VALUE-D)

I don't want this syntax:

my-script (subcommad-a -b VALUE-B | subcommand-c -d VALUE-D)

In fact, in this post, I have simplified my question to put the stress just on my problem. In the real life, my script already uses the subcommands (and no problem with that). But I need to have mutually exclusive groups with 2 *sets* of options for compatibility reasons with another programs.
--
Fran?ois Lafont
Rafael Durán Castañeda
2013-08-05 20:01:22 UTC
Permalink
Post by Francois Lafont
Hi,
Is it possible with argparse to have this syntax for a script?
my-script (-a -b VALUE-B | -c -d VALUE-D)
I would like to do this with the argparse module.
Thanks in advance.
I think you are looking for exclusive groups:

http://docs.python.org/2.7/library/argparse.html#argparse.add_mutually_exclusive_group

HTH
Joseph L. Casale
2013-08-05 22:15:47 UTC
Permalink
Post by Rafael Durán Castañeda
http://docs.python.org/2.7/library/argparse.html#argparse.add_mutually_excl
usive_group
No. That links first doc line in that method shows the very point we are all discussing:

"Create a mutually exclusive group. argparse will make sure that only one
of the arguments in the mutually exclusive group was present on the
command line:"

Op requires more than one per group, this method "make sure that only one
of the arguments" is accepted.

jlc
Francois Lafont
2013-08-05 22:34:16 UTC
Permalink
Post by Rafael Durán Castañeda
http://docs.python.org/2.7/library/argparse.html#argparse.add_mutually_exclusive_group
Yes... but no. The doc explains you can do this:

my-script (-b VALUE-B | -d VALUE-D)

ie mutally exclusive group with *just* *one* option incompatible with another one.

But, apparently, you can't do that:

my-script (-a -b VALUE-B | -c -d VALUE-D)

ie mutually exclusive group with one *set* of option*s* incompatible with another *set* of option*s*. This is why I have posted my message. I have read the documentation before to post it. ;-)

I know docopt but I prefer argparse. My script have subcommands and some of them have common options, so I appreciate the parser objects and the inheritance between parser objects (with parents parameter of argparse.ArgumentParser class).
--
Fran?ois Lafont
Francois Lafont
2013-08-06 23:18:17 UTC
Permalink
Hi,

On relfection, it's clear that:

1. the "(-a -b VALUE-B | -c -d VALUE-D)" syntax is not
implemented by the argparse module;

2. and get this syntax with "argparse + hacking" is not very clean.

So, finally I'll use the docopt module version 0.6.1.
For the inheritance of common options, I'll used something like
that (even if I prefer the oriented object side of the argparse
module):



[the main file]
#-----------------------------------
import importlib
import sys
from docopt import docopt

help_message ="""
Usage:
my-script (-h | --help)
my-script <command> [<args>...]

Options:
-h, --help
Show this help message and exit.

Available commands:
command1 Description1...
command2 Description2...

See 'my-script <command> -h' for more information on a specific command.
"""

if __name__ == '__main__':

args = docopt(help_message, options_first=True)
command = args['<command>']

try:
m = importlib.import_module('mymodule.' + command)
except ImportError:
print("Sorry, the %s command doesn't exist. See 'my-script -h'.") % (command,)
sys.exit(1)

args = docopt(m.help_message, options_first=False)
m.run(args)
#-----------------------------------



[a file for each specific command, mymodule/command1.py etc.]
#-----------------------------------
import mymodule.common as common

help_message = """
Usage:
my-script subcommand1 (-h | --help)
my-script subcommand1 %s -w <warning> -c <critical>

Options:
%s
-w <warning>, --warning=<warning>
Some help.
-c <critical>, --critical=<critical>
Some help.
""" % (common.common_syntax, common.common_help,)


def run(args):
pass
#-----------------------------------



[and a file for the common syntax, mymodule/common.py]
#-----------------------------------
common_syntax = """-H <host-address> -t <timeout>
(--v2c -C <community> | -l <login> -x <passwd> -X <privpass> -L <protocols>)"""

common_help = """ -h, --help
Show this help message and exit.
-H <host-address>, --host=<host-address>
Some help.
-t <timeout>, --timeout=<timeout>
Some help.
--v2c
Some help.
-C <community>, --community=<community>
Set the community password for SNMP V2c.
# etc.
# etc.
"""
#-----------------------------------

Thank you all.
--
Fran?ois Lafont
Francois Lafont
2013-08-06 23:36:42 UTC
Permalink
Post by Francois Lafont
For the inheritance of common options, I'll used something like
that (even if I prefer the oriented object side of the argparse
But I admit that this is a very simple and intelligent module. ;-)
--
Fran?ois Lafont
Loading...