Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

argparse: Required add_mutually_exclusive_group parameters list as optional?

I know that argparse describes in its documentation that parameters starting with - or -- are considered optional:

In general, the argparse module assumes that flags like -f and --bar indicate optional arguments, which can always be omitted at the command line.

No matter if you define parameters as required or not, they will show up under "optional arguments" in argparse's help output:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--required_argument', action='store_true',  required=True)
parser.add_argument('--optional_argument', action='store_false', required=False)
parser.add_argument('positional_argument')
args = parser.parse_args()

This results in the following help output:

usage: demo.py [-h] --required_argument [--optional_argument] positional_argument

positional arguments:
  positional_argument

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

As you might notice, no matter if the arguments starting with - or -- are defined to be required or not, they are listed under "optional arguments". Only those square brackets in the "usage"-line indicate if it can be omitted or not.

I already know there is a workaround for that by using add_argument_group() like this:

import argparse

parser = argparse.ArgumentParser()
group1 = parser.add_argument_group(title='required arguments')
group1.add_argument('--required_argument', action='store_true',  required=True)
parser.add_argument('--optional_argument', action='store_false', required=False)
parser.add_argument('positional_argument')
args = parser.parse_args()
usage: demo.py [-h] --required_argument [--optional_argument] positional_argument

positional arguments:
  positional_argument

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

required arguments:
  --required_argument

But how to achieve a similar thing in case you have mutually exclusive arguments? Let's assume you need to provide one of two arguments, but not both at the same time. I know, there are better options like in this example, but for the sake of it: When you need the user to use either --enable or --disable: One needs to be provided, but both do not make sense.

If this is implemented like this, I do not know of a way to make it not end up under "optional arguments", since add_mutually_exclusive_group() is lacking support for the "title" and "description" arguments of add_argument_group():

Note that currently mutually exclusive argument groups do not support the title and description arguments of add_argument_group().

import argparse

parser = argparse.ArgumentParser()
group1 = parser.add_mutually_exclusive_group(required=True)
group1.add_argument('--enable',  action='store_true',  help='Enable something')
group1.add_argument('--disable', action='store_false', help='Disable something')
args = parser.parse_args()
usage: demo.py [-h] (--enable | --disable)

optional arguments:
  -h, --help  show this help message and exit
  --enable    Enable something
  --disable   Disable something

So, anybody knows a solution with argparse or is this a showstopper request and one must switch to something else like click?

like image 343
Judge Avatar asked Dec 04 '25 15:12

Judge


1 Answers

You can create group and rearrange the optional arguments and required arguments for clean look

import argparse

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() #removes the optional arguments section
group1 = parser.add_argument_group("Required arguments")
group1.add_argument('--enable',  action='store_true',  help='Enable something')
group1.add_argument('--disable', action='store_false', help='Disable something')
parser._action_groups.append(optional) # add optional arguments section again
args = parser.parse_args()

Output:

usage: argparse test.py [-h] (--enable | --disable)

Required arguments:
  --enable    Enable something
  --disable   Disable something

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

like image 51
Anurag Avatar answered Dec 07 '25 04:12

Anurag