Re: partial option parsing

David Goodger <[email protected]> Mon, 25 Nov 2002 20:02:59 -0500
Newsgroups gmane.comp.python.optik.user
Message-ID <BA083273.2C3EB%[email protected]>
Jack Moffitt wrote:
> I have a program that has many subcommands.  A lot of these
> subcommands take a common set of options for consistency.
> 
> Instead of reimplementing the same features for the common options
> within every command, I thought it would be nice to factor out the
> common options to some function like: parse_common_options().  After
> that, I would then parse whatever was leftover that were specific
> command options.
> 
> Unfortunately, there doesn't seem to be a way to partially parse
> options, and get a leftover set.

Correct; the option parser isn't set up that way.

> Am I missing something?  Is there a better way to do this?

Depending on the structure of your command line, you may be able to
solve this problem by approaching it in a different way.

Is the subcommand immediately after the command, with common and
specific options mixed up afterwards? ::

    command subcommand [options] [args]

Or is it like CVS, with the common options before the subcommand, and
the subcommand-specific options after? ::

    command [common opts] subcommand [subcommand-specific opts] [args]

If the subcommand-specific options can occur *before* the subcommand
itself, you're out of luck.  I don't think Optik/optparse can handle
this case.

The first case is easy:

1. Set up an OptionParser with the common options.

2. ``sys.argv[1]`` should have the subcommand.  (Be sure to check!)

3. Add subcommand-specific options to the Option Parser.

4. Process the rest of the command line::

       values, args = option_parser.parse_args(args=sys.argv[2:])

The second case is a little bit trickier:

1. Set up an OptionParser with the general options.

2. Call ``option_parser.disable_interspersed_args()``.  This will
   force the option parser to stop processing at the first non-option
   argument, which should be the subcommand.

3. Process the first part of the command line::

       values, rest = option_parser.parse_args(args=sys.argv[1:])

4. ``rest[0]`` should have the subcommand.

5. Create a new OptionParser for the subcommand-specific options.
   These options are completely independent of the first (common) set,
   and can even reuse option strings (although I'd advise against it).

6. Process the rest of the command line::

       values, args = option_parser.parse_args(args=rest[1:])

Another way to do what you want is to set up a single option parser
for all options all at once, common and subcommand-specific alike.
Use option groups to get nice help output.  Either ignore any unused
options or check for them and complain.  This may not work if some
options are reused by different subcommands in different ways.

-- 
David Goodger  <[email protected]>  Open-source projects:
  - Python Docutils: http://docutils.sourceforge.net/
    (includes reStructuredText: http://docutils.sf.net/rst.html)
  - The Go Tools Project: http://gotools.sourceforge.net/



-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T 
handheld. Power & Color in a compact size! 
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en