0

TLDR: Is there a way to check if any arguments in an argument group have been used? Without checking each argument individually?

I'm trying to achieve something similar to this question: Python argparse mutual exclusive group,

Essentially, trying to find the cleanest way to implement mutually exclusive argument groups.

test.py [-a xxx | [-b yyy -c zzz]]

Expanding on the previous linked question, I tried the following code block on python 3.10.2

import argparse
parser = argparse.ArgumentParser()

group= parser.add_argument_group('Model 2')
group_ex = group.add_mutually_exclusive_group()
group_ex.add_argument("-z", type=str, action = "store", default = "", help="test")

group_ex_1 = group_ex.add_argument_group("option 1")
group_ex.add_argument("-a", type=str, action = "store", default = "", help="test")

group_ex_2 = group_ex.add_argument_group("option 2")
group_ex_2.add_argument("-b", type=str, action = "store", default = "", help="test")
group_ex_2.add_argument("-c", type=str, action = "store", default = "", help="test")

args = parser.parse_args()

My goal was to be able to use group_ex_1 or group_ex_2, but not both, but that seems to not be possible and results in this. Note that argument groups "option 1" and "option 2" do not even appear in the --help output, but the options themselves do.

./test.py --help
usage: test.py [-h] [-z Z] [-a A] [-b B] [-c C]

options:
  -h, --help  show this help message and exit

Model 2:
  -z Z        test

Without adding an argument to group_ex, I receive this error.

  File "/usr/lib64/python3.10/argparse.py", line 396, in _format_actions_usage
    raise ValueError(f'empty group {group}')
ValueError: empty group <argparse._MutuallyExclusiveGroup object at 0x7f804595a2c0>

Seems reasonable to have mutually exclusive groups of arguments, but appears to not be possible. So I'm looking for an alternative.

Jens Petersen
  • 189
  • 2
  • 11
  • `argument_group` is primarily a `help` tool; it does nothing special during parsing. `multally_exclusive_group` is primarily used during parsing, while having some effect on the `usage`. Neither is designed for nesting, though a `mutually_exclusive_group` may be placed in an `argument_group` for help display purposes. – hpaulj Nov 23 '22 at 21:49
  • '-a' was added to the top group, `group_ex`. Was that typo? Anyways, `argument_groups` don't nest, not even with an MXG in between. – hpaulj Nov 23 '22 at 21:57
  • @hpaulj Yep. Fixed the typo and added the error message I get when I don't have that argument in place for the mutually exclusive group. – Jens Petersen Nov 24 '22 at 02:50
  • Are there any attributes for the individual argument groups that could help with checking? Like if group A has 5 arguments, and group B has 10 arguments, being able to implement a single check to see if one or more arguments were used in group A or group B, I could return an error saying to use arguments from one group or the other, but not any arguments from both. – Jens Petersen Nov 24 '22 at 03:00
  • 1
    Formatting `usage` has problems when a MXG does not have any arguments. The only thing you get out the parser is the `args` nameshape. `parsing` does not set any states in the parser. As I said, `argument_groups` play no role in parsing. – hpaulj Nov 24 '22 at 03:48
  • I might add that `parse_args` (or specifically `_parse_known_args` does maintain a `seen_actions` set, which is used at the end of parsing to see whether any `required` arguments are missing. But that's a local variable, and doesn't exist after `parse_args` is done. Also the entries in that set are not identified by `group`. – hpaulj Nov 24 '22 at 18:42

0 Answers0