Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python argparse with nargs behaviour incorrect

Here is my argparse sample say sample.py

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-p", nargs="+", help="Stuff")
args = parser.parse_args()
print args

Python - 2.7.3

I expect that the user supplies a list of arguments separated by spaces after the -p option. For example, if you run

$ sample.py -p x y 
Namespace(p=['x', 'y'])

But my problem is that when you run

$ sample.py -p x -p y
Namespace(p=['y'])

Which is neither here nor there. I would like one of the following

  • Throw an exception to the user asking him to not use -p twice instead just supply them as one argument
  • Just assume it is the same option and produce a list of ['x','y'].

I can see that python 2.7 is doing neither of them which confuses me. Can I get python to do one of the two behaviours documented above?

like image 305
Kannan Ekanath Avatar asked Jul 11 '26 09:07

Kannan Ekanath


1 Answers

Note: python 3.8 adds an action="extend" which will create the desired list of ['x','y']

To produce a list of ['x','y'] use action='append'. Actually it gives

Namespace(p=[['x'], ['y']])

For each -p it gives a list ['x'] as dictated by nargs='+', but append means, add that value to what the Namespace already has. The default action just sets the value, e.g. NS['p']=['x']. I'd suggest reviewing the action paragraph in the docs.

optionals allow repeated use by design. It enables actions like append and count. Usually users don't expect to use them repeatedly, or are happy with the last value. positionals (without the -flag) cannot be repeated (except as allowed by nargs).

How to add optional or once arguments? has some suggestions on how to create a 'no repeats' argument. One is to create a custom action class.

like image 73
hpaulj Avatar answered Jul 14 '26 00:07

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!