2

Using python's argparse module I want to pass parameters to prog two ways:

Method 1:

./filter.py filename --start_regex "^FOO" --end_regex "BAR$" --contains "XXX" --bunch_of_common_options

Method 2:

./filter.py filename --type "FOO_BAR_XXX" --bunch_of_common_options

Logically both are doing exactly the same, because there is a dict in filter.py that translates "FOO_BAR_XXX" type from method 2 to appropriate options for method 1.

I want to specify that, given:

groupA = (--start_regex, --end_regex --contains)

groupB = (--type)

groupA and groupB are:

  1. mutually exclusive, and
  2. groupA must have at least start_regex defined

Now, I'm aware of mutually_exclusive_group functionality, but it works only on single arguments (not groups of options), and sub-commands, but it looks like I would have to have some kind of dispatch option after prog.py, like "git clone --help", or "git push --help" (this post proves that)

Note that it's not elegant to say:

./filter.py with_type filename --type TYPE1
./filter.py without_type filename --start_regex "^FOO" --end_regex "BAR$" --contains "XXX" 

Or am I missing something?

Community
  • 1
  • 1
paroxyzm
  • 1,422
  • 2
  • 13
  • 29

1 Answers1

0

groups don't affect the parsing in any significant way. The regular argument groups just affect the help formatting (you might want to define such groups just for that purpose). Mutually exclusive groups affect the usage formatting (but you can make your own custom usage line), and issue an error message if they are violated. But you could just as well do that kind of test after parse_args, and even use argparse.error to produce a formatted error message. You could also do 'mutually inclusive' tests after.

There is a 'python issue' that explores putting an argument into more than one mutually exclusive group. In this case you could make 3 groups, one for each of the Group A arguments, and put the --type argument in each. That addition was easy; formatting a meaningful usage took more work. See the linked SO issue.

I think doing your own tests after is best choice.


A couple of other options:

Write a custom Action, or Actions. The 'regex_end' action, could for example, object if the namespace does not already have a 'regex_begin' value, or has a 'type' value. The 'type' action could check its format, and object if one of the others has been set already. But you'd be doing the same tests in the post-parse_args case.

A '--regex', nargs=3, metavar=('begin','end','content') argument. That could be mutually exclusive with --type. You could even designate the group as required.

hpaulj
  • 221,503
  • 14
  • 230
  • 353