14.3.4.9 Callback example 6: variable arguments

###
14.3.4.9 Callback example 6: variable arguments

Things get hairy when you want an option to take a variable number of arguments. For this case, you must write a callback, as `optparse` doesn't provide any built-in capabilities for it. And you have to deal with certain intricacies of conventional Unix command-line parsing that `optparse` normally handles for you. In particular, callbacks should implement the conventional rules for bare -- and - arguments:

- either -- or - can be option arguments

- bare -- (if not the argument to some option): halt command-line processing and discard the --

- bare - (if not the argument to some option): halt command-line processing but keep the - (append it to `parser.largs`)

If you want an option that takes a variable number of arguments, there are several subtle, tricky issues to worry about. The exact implementation you choose will be based on which trade-offs you're willing to make for your application (which is why `optparse` doesn't support this sort of thing directly).

Nevertheless, here's a stab at a callback for an option with variable arguments:

    def vararg_callback(option, opt_str, value, parser):
        assert value is None
        done = 0
        value = []
        rargs = parser.rargs
        while rargs:
            arg = rargs[0]

            # Stop if we hit an arg like "--foo", "-a", "-fx", "--file=f",
            # etc.  Note that this also stops on "-3" or "-3.0", so if
            # your option takes numeric values, you will need to handle
            # this.
            if ((arg[:2] == "--" and len(arg) > 2) or
                (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-")):
                break
            else:
                value.append(arg)
                del rargs[0]

         setattr(parser.values, option.dest, value)

    [...]
    parser.add_option("-c", "--callback",
                      action="callback", callback=varargs)

The main weakness with this particular implementation is that negative numbers in the arguments following `"-c"` will be interpreted as further options (probably causing an error), rather than as arguments to `"-c"`. Fixing this is left as an exercise for the reader.