forvas
forvas

Reputation: 10189

Is it possible to create a mutually exclusive group inside another one with argparse (Python)?

I am using argparse in Python, and I need to do this in console:

python3 my_program.py (-a | -b) | (-c | -d)

I read several forums and I guess the answer is no, but just in case. Is it possible?

Upvotes: 4

Views: 2391

Answers (1)

hpaulj
hpaulj

Reputation: 231615

You don't have to take anyone's word for it - try it.

import argparse
parser=argparse.ArgumentParser()
g = parser.add_mutually_exclusive_group()
g1 = g.add_mutually_exclusive_group()
g1.add_argument('-a')
g1.add_argument('-b')
g2 = g.add_mutually_exclusive_group()
g2.add_argument('-c')
g2.add_argument('-d')
print [a.dest for a in g._group_actions]
print [a.dest for a in g1._group_actions]
print [a.dest for a in g2._group_actions]
parser.print_help()

producing:

['a', 'b', 'c', 'd']  # actions in group g
['a', 'b']
['c', 'd']
usage: stack23292325.py [-h] [[-a A | -b B] [-c C | -d D]

g1 and g2 can be defined in another group g, but the net effect it to make the 4 actions mutually exclusive. Which, if you think about it, is logically correct.

The usage line is not quite correct. The first '[' comes from g, but there's no '|' or ']' for that group. The usage formatter has not concept of nesting groups. It just tries to format the 3 groups at though they were independent.

But you could write your own usage line.

This kind of nesting makes more sense is g is an argument_group. Then the actions will be placed in a distinct help group. The two kinds of groups are functionally quite different.

http://bugs.python.org/issue17218 uses this ability to nest a mutually_exclusive_group in an argument_group to add a 'title' and 'description' to the MXG. There's an example of this the argparse unittest file Lib/test/test_argparse.py.

Upvotes: 2

Related Questions