views:

300

answers:

4

I have an application that allows you to send event data to a custom script. You simply lay out the command line arguments and assign what event data goes with what argument. The problem is that there is no real flexibility here. Every option you map out is going to be used, but not every option will necessarily have data. So when the application builds the string to send to the script, some of the arguments are blank and python's OptionParser errors out with "error: --someargument option requires an argument"

Being that there are over 200 points of data, it's not like I can write separate scripts to handle each combination of possible arguments (it would take 2^200 scripts). Is there a way to handle empty arguments in python's optionparser?

A: 

Yes, there is an argument to do so when you add the option:

from optparse import OptionParser
parser = OptionParser()
parser.add_option("--SomeData",action="store", dest="TheData", default='')

Give the default argument the value you want the option to have it is to be specified but optionally have an argument.

Mark Roddy
I am using the default option, but that only is used when --SomeData isn't specified in the commandline. If you do: --SomeData --SomeMoreData blah, then --SomeData errors because it wasn't passed a value.
directedition
@directedition sorry, I misunderstood your question. A post another answer with a solution that should work for you.
Mark Roddy
+1  A: 

I don't think optparse can do this. argparse is a different (non-standard) module that can handle situations like this where the options have optional values.

With optparse you have to either have to specify the option including it's value or leave out both.

sth
+1  A: 

Sorry, misunderstood the question with my first answer. You can accomplish the ability to have optional arguments to command line flags use the callback action type when you define an option. Use the following function as a call back (you will likely wish to tailor to your needs) and configure it for each of the flags that can optionally receive an argument:

import optparse

def optional_arg(arg_default):
    def func(option,opt_str,value,parser):
        if parser.rargs and not parser.rargs[0].startswith('-'):
            val=parser.rargs[0]
            parser.rargs.pop(0)
        else:
            val=arg_default
        setattr(parser.values,option.dest,val)
    return func

def main(args):
    parser=optparse.OptionParser()
    parser.add_option('--foo',action='callback',callback=optional_arg('empty'),dest='foo')
    parser.add_option('--file',action='store_true',default=False)
    return parser.parse_args(args)

if __name__=='__main__':
    import sys
    print main(sys.argv)



Running from the command line you'll see this:

# python parser.py
(<Values at 0x8e42d8: {'foo': None, 'file': False}>, [])

# python parser.py --foo
(<Values at 0x8e42d8: {'foo': 'empty', 'file': False}>, [])

# python parser.py --foo bar
(<Values at 0x8e42d8: {'foo': 'bar', 'file': False}>, [])
Mark Roddy
A: 

Optparse already allows you to pass the empty string as an option argument. So if possible, treat the empty string as "no value". For long options, any of the following work:

my_script --opt=   --anotheroption
my_script --opt='' --anotheroption
my_script --opt="" --anotheroption
my_script --opt '' --anotheroption
my_script --opt "" --anotheroption

For short-style options, you can use either of:

my_script -o '' --anotheroption
my_script -o "" --anotheroption

Caveat: this has been tested under Linux and should work the same under other Unixlike systems; Windows handles command line quoting differently and might not accept all of the variants listed above.

mhagger