[getopt-sig] Parse arguments according to a usage message?
David Boddie
david@sleepydog.net
Wed, 20 Feb 2002 12:27:02 +0000
[Apologies to Greg: I meant to send this to the list as well, so he'll
get this message twice...]
On Wednesday 20 Feb 2002 2:43 am, Greg Ward wrote:
> On 18 February 2002, David Boddie said:
> > I wonder whether there is any mileage in using part of the class that I
> > mentioned in the "RFC: Option Parsing Libraries" thread in python-dev?
> >
> > http://www-solar.mcs.st-and.ac.uk/~davidb/Software/Python/cmdsyntax/
>
> Oooh, neat! What a cool idea. One thing to note is that you're
> addressing the wider issue of *argument* parsing, whereas most people
> are just interested in option parsing -- eg. Optik works by removing all
> options and their arguments, and passing back a list of whatever's left
> over. This is a fairly common model, and it works for me. But it
> means every Optik-based script has code like
>
> [...]
> (options, args) = parser.parse_args()
> if len(args) != 3:
> parser.error("wrong number of arguments")
I wrote two functions which I used to use for option finding in a command
line list, as from sys.argv[1:]. One would locate the option and any
following arguments, the other would remove what was found. Any left over
list entries were presumed to be arguments. This got very tiresome for
complicated command line syntaxes.
> For a simple fixed number of positional arguments, this is not a big
> deal, but it can be tiresome when you have a fairly complex syntax left
> over after options have been parsed. Your module, presumably, solves
> this nicely by incorporating positional arguments into its domain.
It requires that all mandatory arguments (as opposed to options) are
given in order by the user. The parser can be asked to either look for
optional arguments in the order that they were specified, or out of
order as long as they don't disturb positional arguments.
For example:
infile [-l logfile] [-v] outfile
would allow
myfile -l log.txt -v output.txt
myfile -v -l log.txt output.txt
but not
myfile -v output.txt -l log.txt
Arbitrary numbers of trailing arguments are not supported at the moment,
although the matching algorithms could easily be modified to return
trailing arguments back to the caller.
> There are also some fairly obvious limitations:
>
> * what about scripts with dozens of options? the traditional
> "[-v] [-q] [-o outfile]" notation is great for 3 or 4 options,
> but loses its appeal pretty quickly. (Try "man mpg123" for an
> example of what I mean.)
I added the usual -abcde syntax which assumes that all the options are
single character options and that at least one is required. They can be
specified in any order, too. If you run the test.py script with a
syntax string containing something like this then you'll see what
-abcde is converted to. You may well be horrified. <wink>
The disadvantage to my assumption is that it allows someone to specify
-f foo
but can't cope with the user input
-ffoo
as it expects -f instead.
For lots of options and following arguments, then it's necessary to
specify them all in full. I don't really see a way around this other than
to format the syntax string nicely over several lines.
> * no strong typing -- everything's a string, and I have to explicitly
> convert numeric option arguments and catch the errors
That's why I suggested that it's only part of a solution. I don't mind
manually casting the strings to something useful, possibly using a
dedicated function to cope with raising exceptions or filling in default
values if the value given is invalid. Ideally, something would do this
for you, but I don't see the need for me to reinvent that mechanism when
Optik, for example, already provides that facility.
> * how much say do I have in what happens to option arguments? eg.
> is there an equivalent to Optik's "append" action, where each
> occurence of a particular option appends that occurence's argument
> to a list, rather than replacing previous values?
Argument names (labels) should be unique within a given match of the
syntax definition. Note that
infile (--output-dir output)|(--output-file output)
contains the label "output" twice, but it will never be overwritten since
the user can't specify both the --output-dir and --output-file option as
the "|" character implies that one or the other must be given.
There's no facility for putting the values anywhere other than in a
dictionary at the moment.
> Must look at your code. Neat idea.
Thanks. If you just run the source through pydoc, or look at the
dcoumentation at the URL I gave, it'll give you an idea of what the
parser supports.
David
________________________________________________________________________
This email has been scanned for all viruses by the MessageLabs SkyScan
service. For more information on a proactive anti-virus service working
around the clock, around the globe, visit http://www.messagelabs.com
________________________________________________________________________