Python argparse integer condition (>=12)

Question:

I need to request that an argument is >= 12 using argparse.

I cannot find a way to obtain this result using argparse, it seems there’s no way to set rules to a given value but only full sets of accepted values like choices=[‘rock’, ‘paper’, ‘scissors’].

My code is:

import sys, argparse

parser = argparse.ArgumentParser()
parser.add_argument("-b", "--bandwidth", type=int, help="target bandwidth >=12")
args = parser.parse_args()
if args.bandwidth and args.bandwidth < 12:
    print "ERROR: minimum bandwidth is 12"
    sys.exit(1)

I wonder if there is a way to obtain this result directly with some argparse option.

Asked By: giuspen

||

Answers:

One way is to use a custom type.

def bandwidth_type(x):
    x = int(x)
    if x < 12:
        raise argparse.ArgumentTypeError("Minimum bandwidth is 12")
    return x

parser.add_argument("-b", "--bandwidth", type=bandwidth_type, help="target bandwidth >= 12")

Note: I think ArgumentTypeError is a more correct exception to raise than ArgumentError. However, ArgumentTypeError is not documented as a public class by argparse, and so it may not be considered correct to use in your own code. One option I like is to use argparse.error like alecxe does in his answer, although I would use a custom action instead of a type function to gain access to the parser object.

A more flexible option is a custom action, which provides access to the current parser and namespace object.

class BandwidthAction(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        if values < 12:
            parser.error("Minimum bandwidth for {0} is 12".format(option_string))
            #raise argparse.ArgumentError("Minimum bandwidth is 12")

        setattr(namespace, self.dest, values)

parser.add_argument("-b", "--bandwidth", action=BandwidthAction, type=int,
                     help="target bandwidth >= 12")
Answered By: chepner

you can try with something you introduce in your explanation :

import sys, argparse

parser = argparse.ArgumentParser()
parser.add_argument("-b", "--bandwidth", type=int, choices=range(12,100))
args = parser.parse_args()

for example, thus , its Argparse which will raise the error itself with invalid choice

Answered By: user1593705

You can call the parser error without creating custom types or separate functions. A simple change to your code example is enough:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-b", "--bandwidth", type=int, help="target bandwidth >=12")
args = parser.parse_args()
if args.bandwidth and args.bandwidth < 12:
    parser.error("Minimum bandwidth is 12")

This will cause the application to exit and display the parser error:

$ python test.py --bandwidth 11 
usage: test.py [-h] [-b BANDWIDTH]
test.py: error: Minimum bandwidth is 12
Answered By: jonatan

How about this?

import sys, argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    "-b", "--bandwidth", 
    type=lambda x: (int(x) > 11) and int(x) or sys.exit("Minimum bandwidth is 12"),
    help="target bandwidth >=12"
)

But plese note, I didn’t try it in a real code. Or you can change sys.exit to parser.error as wrote by @jonatan.

Answered By: Zhenhua Zhang
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.