简体   繁体   中英

Python argparse doesn't show up help message correctly

I have to parse arguments where 4 of them have to be tied with each other, and last 2 have to be exclusive

group 1 sub_exclusive_1 has 4 arguments where all of them must be defined if any of them have been defined.

group 2 sub_exclusive_2 has 2 arguments where only 1 of them can be defined but only if none from group 1 have been defined.

parser = argparse.ArgumentParser(description='Main Description', epilog='Main Epilog')
group_exclusive = parser.add_argument_group('Exclusive')
root_exclusive = group_exclusive.add_mutually_exclusive_group()

sub_exclusive_1 = root_exclusive.add_argument_group()
sub_exclusive_1.add_argument("--firstList", action='store', help = "Help for firstList")
sub_exclusive_1.add_argument("--secondList", action='store', help = "Help for secondList")
sub_exclusive_1.add_argument("--thirdList", action='store', help = "Help for thirdList")
sub_exclusive_1.add_argument("--fourthList", action='store', help = "Help for fourthList")

sub_exclusive_2 = root_exclusive.add_mutually_exclusive_group()
sub_exclusive_2.add_argument("--last", action='store_true', help = "Help for Last")
sub_exclusive_2.add_argument("--first", action='store_true', help = "Help for First")

the problems are:

  1. Cannot tie group 1 arguments with each other.

  2. When setting sub_exclusive_1 as add_argument_group instead of add_mutually_exclusive_group , firstList ... fourthList are not shown in the help section when running program with -h option.

Any solution ?

Group 1 should not be four separate arguments, but a single option with 4 arguments:

add_argument("--arg", nargs=4)

Then command --arg1 2 --arg2 3 --arg3 5 --arg4 7 would become command --arg 2 3 5 7 ; you would need to adjust your code accordingly. One option is to adjust the values stored in the namespace after parsing:

args = p.parse_args()
# Unpack the 4-tuple into the destinations used by your original parser
args.arg1, args.arg2, args.arg3, args.arg4 = args.arg

Another is to define a custom action for --arg which immediately assigns the 4 values to the correct destinations in the namespace.

Then you can define an exclusive group containing --arg , --first , and --last .

The print_help that I get from your code (which you should have shown) is

In [420]: parser.print_help()
usage: ipython3 [-h] [--firstList FIRSTLIST] [--secondList SECONDLIST]
                [--thirdList THIRDLIST] [--fourthList FOURTHLIST]
                [[--last | --first]

optional arguments:
  -h, --help  show this help message and exit

Exclusive:
  --last      Help for Last
  --first     Help for First

All the arguments appear in the usage , but only exclusive_group appears in the help. And the brackets on this group in the usage are messed up.

argparse does not provide a mechanism to do what you want. There are some proposed patches that might get you there, but nothing now.

A 'argument group' is just a help lines display mechanism. It does not affect the usage formatting, and does not affect parsing. In addition, argument groups cannot be nested - the arguments are accepted, but do not appear in the help.

A mutually exclusive group can be nested in an argument group (for help line display purposes). But the effect is to just show its arguments in that group.

If you want 'first','second', etc to occur together, either make them values of a nargs=4 argument, or test them after parsing. Something like:

 group = [args.first, args.second, args.third, args.fourth]
 if any([x is None for x in group]):
     parser.error('all of the inclusive group is required')

I could point you to the bug issue that deals with 'nested inclusive groups', but that's not going to help right now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM