How to add group_argument to add_mutually_exclusive_group with python argparse

I am trying to implement the following:

$ prog.py -h usage: prog.py [-h] [-s | -m] [[-y [year]] | [[-1 | -3] [month] [year]]] 

However, no matter how I played with add_argument_group and add_mutually_exclusive_group,

 #!/usr/bin/env python import argparse def main(opt): print(opt) if __name__ == '__main__': parser = argparse.ArgumentParser() bar = parser.add_mutually_exclusive_group() bar.add_argument('-s', action='store_true', default=True) bar.add_argument('-m', action='store_true', default=False) #bar = parser.add_argument_group() bar = parser.add_mutually_exclusive_group() bar.add_argument('-y', metavar='year', type=int, dest='iy', nargs='?', default=0) baz = bar.add_argument_group() g_13 = baz.add_mutually_exclusive_group() g_13.add_argument('-1', dest='i1', help='Display single month output.', action='store_true', default=True) g_13.add_argument('-3', dest='i3', help='Display prev/current/next month output.', action='store_true', default=False) #aaa = bar.add_argument_group() baz.add_argument(metavar='month', type=int, choices=range(1, 13), dest='mo', nargs='?', default=1) baz.add_argument(metavar='year', type=int, dest='yr', nargs='?', default=2000) main(parser.parse_args()) 

I can only manage:

 $ prog.py -h usage: prog.py [-h] [-s | -m] [-y [year]] [-1 | -3] [month] [year] 

That is, I cannot group [-y [year]] and [[-1 | -3] [month] [year]] [[-1 | -3] [month] [year]] into a mutually exclusive group. I canโ€™t understand why. Can anyone help? Thanks.

+6
source share
1 answer

Argument groups simply help organize the display of help. They cannot be nested. Mutually exclusive groups validate arguments and change usage mapping. They can be nested, but the end result is the same as if you made one large group. http://bugs.python.org/issue11588 is trying to create a more general usage group.

At the same time, you can write a custom usage string and check the arguments after parsing if mutually exclusive groups do not give you enough control.


Here's a parser using the code I'm developing for http://bugs.python.org/issue11588

 parser = argparse.ArgumentParser(formatter_class=argparse.UsageGroupHelpFormatter) bar = parser.add_usage_group(kind='mxg', dest='s|m') bar.add_argument('-s', action='store_true', default=True) bar.add_argument('-m', action='store_true', default=False) bar = parser.add_usage_group(kind='mxg', dest='year|more') bar.add_argument('-y', metavar='year', type=int,...) baz = bar.add_usage_group(kind='any', dest='', joiner=' ', parens='[]') g_13 = baz.add_usage_group(kind='mxg', dest='1|3') g_13.add_argument('-1', dest='i1',...) g_13.add_argument('-3', dest='i3',...) baz.add_argument(metavar='month', type=int,...) baz.add_argument(metavar='year', type=int,...) 

This replaces mutually_exclusive_group with usage_group , which can be nested, and can check for other logical relationships besides "xor". "any" accepts any combination of its arguments, just as you expected "argument_group" to act.

Resulting use:

 usage: prog.py [-h] [-s | -m] [-y [year] | [[-1 | -3] month year]] [month] [year] 

The main mistake is to display the positioners, โ€œmonthโ€ and โ€œyearโ€. They are in the right place in the โ€œanyโ€ group, but they also appear in the usual final location for the positions.

It accepts input, such as:

 '' '-y 1943 -s '-1 12 1943' '12 1943' '12' '-3' '1943' gives an error, because it it is out of range for a month 

As you can see, expanding the concept of groups is not trivial. I think I'm on the right track, but there are still rough edges.

+5
source

Source: https://habr.com/ru/post/971897/


All Articles