Question

For some reason, I have non standard command line options for my program. My program takes in a long option also with a single '-'. For example, a valid command line option would be '-f' / '-foo'. Both short and long options need to have an argument separated by space or an '='.

I am trying to parse this using the optparse, but I understand that optparse does not support non GNU-standard options. Is there a way to tweak optparse to do this?

Was it helpful?

Solution

Here's a mildly hackish way to do what you need.

Subclass Option and OptionParser and patch some of the methods:

from optparse import Option, OptionError, OptionParser

class MyOption(Option):
    def _set_opt_strings(self, opts):
        for opt in opts:
            if len(opt) < 2:
                raise OptionError(
                    "invalid option string %r: "
                    "must be at least two characters long" % opt, self)
            elif len(opt) == 2:
                self._short_opts.append(opt)
            else:
                self._long_opts.append(opt)

class MyOptionParser(OptionParser):
    def _process_args(self, largs, rargs, values):
        while rargs:
            arg = rargs[0]
            if arg == "--":
                del rargs[0]
                return
            elif arg[0:2] == "--":
                self._process_long_opt(rargs, values)
            elif arg[:1] == "-" and len(arg) > 1:
                if len(arg) > 2:
                    self._process_long_opt(rargs, values)
                else:
                    self._process_short_opts(rargs, values)
            elif self.allow_interspersed_args:
                largs.append(arg)
                del rargs[0]
            else:
                return 

Now you can do

parser = MyOptionParser()
parser.add_option(MyOption("-f", "-file", dest="filename",
                 help="write report to FILE", metavar="FILE"))
parser.add_option(MyOption("-q", "-quiet",
                 action="store_false", dest="verbose", default=True,
                 help="don't print status messages to stdout"))

With this, parser will accept -file as an option (and will not accept e.g. -fq).

OTHER TIPS

From the optparse documentation

option:
an argument used to supply extra information to guide or customize the execution of a program. There are many different syntaxes for options; the traditional Unix syntax is a hyphen (“-”) followed by a single letter, e.g. -x or -F. Also, traditional Unix syntax allows multiple options to be merged into a single argument, e.g. -x -F is equivalent to -xF. The GNU project introduced -- followed by a series of hyphen-separated words, e.g. --file or --dry-run. These are the only two option syntaxes provided by optparse.

(emphasis added)

So no, you cannot specify other ways of handling arguments with optparse. You can, however, parse the arguments yourself by using argv from the sys module.

This is going to be more work, but it might look something like:

from sys import argv
for arg in argv:
    if arg.startswith("-") or arg.startswith("--"):
        # Parse the argument

I don't think there's any way to tweak optparse (though I don't know for certain), but getopt is your alternative that will handle C style command-line options.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top