Search code examples
pythonargumentscommand-line-argumentsoptparse

parsing non GNU-standard options using optparse in python


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?


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).