Re: Implementing variable number of option arguments

Beni Cherniavsky <[email protected]> Sun, 07 Nov 2004 02:46:06 +0200
Newsgroups gmane.comp.python.optik.user
Message-ID <[email protected]>
Greg Ward wrote:
> I'm not completely sure what to do about the option value.  Clearly for
> nargs=1 or (1, 1) -- the default if nargs is not specified -- it should
> just be the single value.  Equally clearly, for nargs=(M, N) where N >=
> M > 1, it should be a tuple of all values consumed.  Two tricky cases
> remain:
> 
>   * nargs=(0, 1): this can never have more than one argument, so
>     I would opt for None or the argument itself
> 
>   * nargs=(0, N) or (1, N): since these could have multiple values, I
>     think it should always be a tuple -- possible an empty or singleton
>     tuple
> 
> Hmmm... I think it's actually pretty simple.  Say nargs=(M, N).  If N=1
> (the minimum), return None or the argument seen.  If N>1, return a
> tuple.  That seems like a good balance between simple to understand,
> simple to implement, and convenient to use.
> 
There is a simple check: nargs=(N, N) must do what nargs=N now does.
It stores the value for N=1 and a tuple for N>1.  So what you describe
is the only sensible way to extend it.

There is one questionable point where there is some freedom:
nargs=(0, 1) when no argument was given.  Storing `None` is equivallent
to the option not having been given at all (unless you gave a different
default value for it).  Now that is not very useful -- in most cases
you want the option with no argument to do something (e.g. ``ls
--color`` is like ``ls --color=auto``, not like ``ls``).  Providing a
different default is indeed a solution; note that it only works iff you
store `None` for no arguments even if a different default was given!
E.g. '--color' would have 'never' as the default.  The program would
have to explicitly treat `None` as 'auto'.

> Fourth, specifying leftover positional arguments.  I'm thinking along
> these lines:
> 
>   parser = OptionParser(usage="%prog [options] [name1 [name2 [name3]]]")
>   parser.add_option(...)
>   [...]
>   parser.parse_args(minargs=0, maxargs=3, type="string")
> 
> that is:
> 
>   * you specify constraints on positional args in the call to
>     parse_args()
> 
>   * use explicit minargs, maxargs values instead of a nargs-style tuple
>     -- it's much more common to take a range of positional args, after
>     all, so I expect 0 < minargs < maxargs to be a fairly common case,
>     unlike with options
> 
(0, N) seems good enough to me.  And (N, N) is akwardly more verbose
this way.  I don't see the gain that justifies 2 yet another options to
remember.

>   * 'type' is just like it is for an option, so you could specify mixed
>     types with a tuple, where the last type is extended to cover all
>     arguments seen
> 
> The current semantics (which would remain the default) are:
> 
>   parser.parse_args(minargs=0, maxargs=sys.maxint, type="string")
> 
Please use None instead of sys.maxint to represent infinity.  I know it
won't cause problems but it would be cleaner and more consistent with
Python traditions (e.g. in slices).



-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click