paul j3 <ajipa...@gmail.com> added the comment:

Let's see if I can clarify somethings.  But first, I should say that I've 
worked with this code for so long, that I may miss things that could confuse a 
beginner.

A basic distinction is between "optionals" and "positionals".  I put those in 
quotes because that's not the same as "required or not".  Talk about "options" 
in commandline arguments goes way back (see getopt, and optparse).

An "optional" is identified by a flag string, such as "-f" or "--foo", short or 
long, single or double dash.  I prefer to call these "flagged arguments".  
"optionals" can occur in any order, and even repeatedly.

A "postional" is identified by position, without any sort of flag string.  In 
earlier parsers, these where the extras, the strings that weren't handled by 
"options".  These can only occur in the defined order.  

Conventionally, optionals come first, and positionals at the end.  That's how 
most "help/usage" messages display them.  But argparse tries to handle them in 
any order.

Both kinds can take a "nargs" parameter.  This specifies how many arguments (or 
strings) are required, either following the flag string, or as part of 
position.  Obviously if you don't specify the flag, you don't have to provide 
its arguments either.  

There's another point of confusion.  "parse.add_argument" creates an "Action", 
also called an "argument".  And each "action" has a 'nargs' that specifies how 
many "arguments" go along with it.  Sorry.


The default "nargs" value is "None", which means 1 string.  "?" means zro or 
one (optional, but in a different sense than flagged).  "*" means any number.  
"+" means one or more.  nargs could also be a number, e.g. "2".  There isn't 
anything that specifies "2 or more" or "2 or 3" (though that has been 
requested).  "?+*" are used in basically the same sense as in regex/re patterns.

There's another parameter, "action", which also controls the number of required 
strings.  With "store_true" no string is allowed after the flag, effectively 
"nargs=0" (this action makes no sense for positionals).  It's actually of 
subclass of "store_const", with a default "False" and const "True".

With a flagged argument, you may also specify a "required" parameter.  That's 
convenient, but does lead to confusing terminology.  "optionals" may be 
"required", and a "positional" with "?" is optional/not-required.  

Since "+" and "*" allow many strings, something has to define the end of that 
list.  That end is either the end of the input, or the next flag string. If you 
are just using flagged arguments this isn't a problem.  But with "positionals", 
it is hard to handle more than one open-end nargs.  Or to use such a 
"positional" after an open-ended "optional".  As with regex, these nargs are 
"greedy".  

In some ways, the documentation is more complicated than the code itself.  The 
code is well written, with different methods and classes handling different 
issues.  The code itself does not have a lot of complicated rules and 
conditions.  The complexity comes from how the different pieces interact.

"flagged vs positional", nargs, and "required" are separate specifications, 
though they do have significant interactions.


In your example:

    parser.add_argument("outdata", help="Path to output data file")
    parser.add_argument("plotTimes", nargs='*', help="Times to plot")
    parser.add_argument("outplot", help="Path to output plot file")

"outdata" takes one string.  "outplot" takes another.  "plotTimes" then gets 
anything left over in between.  An empty list of strings satisfies its "nargs". 
 The strings are actually allocated with a regex expression.

With `arg_argument('--foo', nargs='+')`,

    --foo one
    --foo one two three

are both allowed.  With "*",

     --foo

is also allowed.  For a "positional" omit the "--foo".  That means that a 
"positional" with "*" is always seen (which can require some special edge case 
handling).

----------
nosy: +paul.j3

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue43876>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to