I'm using argparse
to parse the inputs to my python3 program. I was recently asked to range check some of the numeric inputs, a seemingly good idea. Argparse has a facility to do just that.
The numeric inputs are port numbers, in the usual range 0-65535, so I altered my parse command line to :
import argparse
cmd_parser = argparse.ArgumentParser()
cmd_parser = add_argument('-p', help='Port number to connect to', dest='cmd_port', default=1234, type=int, choices=range(0,65536))
cmd_parser.parse_args(['-h'])
Now, however, when I request the help, I get flooded with all the possible values from argparse. eg.
optional arguments:
-h, --help show this help message and exit
-p {0,1,2,3,4,5,6,7,8,9,10,11,12,13 ...
65478,65479,65480,65481,65482,65483,65484,65485,65486,65487,65488,65489,
65490,65491,65492,65493,65494,65495,65496,65497,65498,65499,65500,65501,
65502,65503,65504,65505,65506,65507,65508,65509,65510,65511,65512,65513,
65514,65515,65516,65517,65518,65519,65520,65521,65522,65523,65524,65525,
65526,65527,65528,65529,65530,65531,65532,65533,65534,65535}
Port number to connect to
...
It lists every single port in that range. Is there a way to truncate this or make it realize its a range (0-65535) or for it to use ellipsis or something to make it a bit prettier? Is my only option to explicitly range check my inputs with if statements?
I've been googling this but I'm having trouble finding examples where people used argparse and specified choices. I also checked the documentation on argparse but didn't see anything useful. https://docs.python.org/2/library/argparse.html
Use custom action...
import argparse
class PortAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if not 0 < values < 2**16:
raise argparse.ArgumentError(self, "port numbers must be between 0 and 2**16")
setattr(namespace, self.dest, values)
cmd_parser = argparse.ArgumentParser()
cmd_parser.add_argument('-p',
help='Port number to connect to',
dest='cmd_port',
default=1234,
type=int,
action=PortAction,
metavar="{0..65535}")
An invalid port number will display the error message based on the raised ArgumentError. If you enter a value of 65536, the following line will be printed:
error: argument -p: port numbers must be between 0 and 2**16
The usage and help messages will be printed based on the metavar displayed
Just use int
as type in add_argument
, and manually verify it's in the permitted range. Or, use a type of your own, which has a constructor that does the checking for you, and a __int__
method for implicit conversion:
class portnumber:
def __init__(self, string):
self._val = int(string)
if (not self._val > 0) or (not self.val < 2**16):
raise argparse.ArgumentTypeError("port numbers must be integers between 0 and 2**16")
def __int__(self):
return self._val
...
parser.add_argument("-p",type=portnumber)
Supply an explicit metavar
argument instead of letting argparse
produce one for you.
cmd_parser.add_argument('-p',
help='Port number to connect to',
dest='cmd_port',
default=1234,
type=int,
choices=range(0,65536),
metavar="{0..65535}")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With