Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assertion when declaring required arguments with argparse and 'nargs=*' arguments

Here is the current code to parse the arguments :

parser = argparse.ArgumentParser()

parser.add_argument('-a', '--action', required=True, metavar='', nargs=1, help='{block|release|clear|show|show_extended|}')
parser.add_argument('-i', '--interface', required=True, metavar='', nargs=1, help='interface name')
parser.add_argument('-d', '--debug', action='store_true', help='debug prints')
parser.add_argument('--ips', metavar='ips', nargs='*', help='ip addresses to block')
parser.add_argument('--handles', metavar='handles', nargs='*', help='filters handles to delete (usually 800::xxx), run with [show] to see')
args = parser.parse_args()

when I try to execute it without typing -a or -i, I get an assertion :

Traceback (most recent call last):
  File "./block_traffic.py", line 112, in <module>
    args = parser.parse_args()
  File "/usr/lib/python2.7/argparse.py", line 1690, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1722, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1946, in _parse_known_args
    self.error(_('argument %s is required') % name)
  File "/usr/lib/python2.7/argparse.py", line 2362, in error
    self.print_usage(_sys.stderr)
  File "/usr/lib/python2.7/argparse.py", line 2324, in print_usage
    self._print_message(self.format_usage(), file)
  File "/usr/lib/python2.7/argparse.py", line 2280, in format_usage
    return formatter.format_help()
  File "/usr/lib/python2.7/argparse.py", line 281, in format_help
    help = self._root_section.format_help()
  File "/usr/lib/python2.7/argparse.py", line 211, in format_help
    func(*args)
  File "/usr/lib/python2.7/argparse.py", line 332, in _format_usage
    assert ' '.join(opt_parts) == opt_usage
AssertionError

I noticed the assertion exception is gone as I remove the nargs='*' argument (one of the two)

What I want is for the first 2 arguments to be mandatory, the last 2 to be optional (with undetermined number of arguments) and -d to be optional flag.

like image 277
SagiLow Avatar asked Dec 12 '25 13:12

SagiLow


2 Answers

argparse does not like metavar=''.

Either give them a name or remove the options - but don't leave them as empty strings.

like image 68
gus27 Avatar answered Dec 14 '25 01:12

gus27


Without '-a' or '-i' it raises an error, because you made them 'required'.

But while formatting the 'usage' part of the error message:

usage: PROG [-h] -a act -i INTERFACE [-d] [--ips [ips [ips ...]]]
            [--handles [handles [handles ...]]]

it encountered an error while wrapping that long usage to 2 lines. As noted by gus42 that was produced by the 2 metavar='' parameters. This is a known bug in the usage formatting. metavar with [] also produces this problem.

The usage above uses metavar='act' in the first case, and default None in the second. So you can shorten the metavar, but you can't suppress it entirely, at least not when the usage line is long enough to wrap.

like image 31
hpaulj Avatar answered Dec 14 '25 02:12

hpaulj



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!