How to parse positional arguments with leading minus sign (negative numbers) using argparse
Solution 1
You need to insert a --
into your command-line arguments:
$ python example.py --test -- -1,2,3,4
Namespace(positional='-1,2,3,4', test=True)
The double-dash stops argparse looking for any more optional switches; it's the defacto standard way of handling exactly this use case for command-line tools.
Solution 2
From the documentation:
The parse_args() method attempts to give errors whenever the user has clearly made a mistake, but some situations are inherently ambiguous. For example, the command-line argument -1 could either be an attempt to specify an option or an attempt to provide a positional argument. The parse_args() method is cautious here: positional arguments may only begin with - if they look like negative numbers and there are no options in the parser that look like negative numbers:
Since -1,2,3,4
does not look like a negative number you must "escape" it with the --
as in most *nix systems.
An other solution would be to use nargs
for the positional and pass the numbers as space separated:
#test.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('positional', nargs='*') #'+' for one or more numbers
print parser.parse_args()
Output:
$ python test.py -1 2 3 -4 5 6
Namespace(positional=['-1', '2', '3', '-4', '5', '6'])
A third way to obtain what you want is to use parse_known_args
instead of parse_args
.
You do not add the positional argument to the parser and parse it manually instead:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--test', action='store_true')
parsed, args = parser.parse_known_args()
print parsed
print args
Result:
$ python test.py --test -1,2,3,4
Namespace(test=True)
['-1,2,3,4']
This has the disadvantage that the help text will be less informative.
![Inactivist](https://i.stack.imgur.com/YF1Nw.jpg?s=256&g=1)
Inactivist
Eclectic programmer. (Re)Discovering Python. Loving it. Some things I'm working on: WhatEvah: Discover Twitter Influencers for your choice of search terms. Twitter-Streamer: Python-based utility using Twitter's Streaming API. Capture Twitter streams with minimal fuss. What you do with it is up to you. Sylvestr Eats Tweets: Realtime stats for various things mentioned on Twitter. Uses a variant of Twitter-Streamer to capture Twitter's Streaming API data. WhoPlussed: Google+ app to view top commenters on a Google+ post.
Updated on June 04, 2022Comments
-
Inactivist about 2 years
I would like to parse a required, positional argument containing a comma-separated list of integers. If the first integer contains a leading minus ('-') sign, argparse complains:
import argparse parser = argparse.ArgumentParser() parser.add_argument('positional') parser.add_argument('-t', '--test', action='store_true') opts = parser.parse_args() print opts $ python example.py --test 1,2,3,4 Namespace(positional='1,2,3,4', test=True) $ python example.py --test -1,2,3,4 usage: example.py [-h] [-t] positional example.py: error: too few arguments $ python example.py --test "-1,2,3,4" usage: example.py [-h] [-t] positional example.py: error: too few arguments
I've seen people suggest using some other character besides
-
as the flag character, but I'd rather not do that. Is there another way to configure argparse to allow both--test
and-1,2,3,4
as valid arguments? -
Inactivist over 11 yearsI saw the documentation, but was wondering if there were any tricks to alter the standard behavior. At this point, I think it would be better to require four separate positional arguments or use space delimiters than to use the
--
escape mechanism. Thanks for the help. -
Inactivist over 11 yearsAh, I was unaware of the 'standard' of having to use double-dash (still a *nix newbie of sorts, still learning...) Thanks for the info!
-
Bakuriu over 11 years@Inactivist I updated my answer with a third method to allow
-1,2,3,4
style positional. -
panzi over 10 yearsThat just gives me
error: unrecognized arguments: --
(argparse under Python 2.7.3) -
Martijn Pieters over 10 years@panzi: No such problems under Python 2.7.5.