Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argparse: how can I suppress the list of choices for "invalid choice" error?

How can I suppress or customize the argparse error message when a user passes in an argument outside of the specified choices?

I'm writing a script that requires the user to pass in a number (int) when they execute the program, which I've defined using the choices argument. I understand how to use the metavar argument to customize the --help text, but when the user passes in a value outside the range, the error field dumps every possible value from the range - not good for a large range!

Here's the code for an example script:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    "--ID",
    type=int,
    choices=range(1, 10),
    required=True,
    help="My helpful help text.",
    metavar="",
)
args = parser.parse_args()

And here's the output:

$ python3 foo.py --ID 12
usage: foo.py [-h] --ID 
foo.py: error: argument --ID: invalid choice: 12 (choose from 1, 2, 3, 4, 5, 6, 7, 8, 9)

In my actual script, I'd have choices=range(1,1000000). This would not lead to fun error messages if the user enters a number outside that range as they'd be presented with a dump of a million (minus 1) numbers to choose from!

How can I get the error message to read as something more friendly like:

$ python3 foo.py --ID 12
    usage: foo.py [-h] --ID 
    foo.py: error: argument --ID: invalid choice: 12 (choose from {1, 9})
like image 432
the_meter413 Avatar asked Nov 15 '25 13:11

the_meter413


1 Answers

You could use a dedicated Action:

import argparse

class MyIntRange(argparse.Action):
    def __call__(self, parser, namespace, values, option_steing=None):
        if values not in range(1,10):
            parser.exit(1, message=" should be in {1,10}")
        setattr(namespace, self.dest, values)

parser = argparse.ArgumentParser()
parser.add_argument(
    "--ID",
    type=int,
    action=MyIntRange,
    required=True,
    help="My helpful help text.",
    metavar="",
)
args = parser.parse_args()

like image 175
Vser Avatar answered Nov 17 '25 08:11

Vser



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!