Oct
16
2009

Passing optparse results as keyword arguments

The python optparse package is really handy for parsing command line arguments. When combining this with an extra main function idiom (to allow interactive usage or use as a module), I ran into a small problem – the following code does not run:

1
2
3
4
5
6
7
8
9
def main(foo, bar):
    print("foo: %s, bar: %s\n" % (foo, bar))
if __name__ == "__main__":
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("--foo", dest="foo")
    parser.add_option("--bar", dest="bar")
    (options, args) = parser.parse_args()
    main(**options)

This is the error message:

Traceback (most recent call last):
  File "foobar.py", line 9, in 
    main(**options)
TypeError: main() argument after ** must be a dictionary

The problem here is that the options result from OptionParser is instead of type optparse.Values, which is not derived from dict (huh?!). Quoting the Python language reference:

If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments.

Here are two ways to fix the problem:

1
2
3
4
#   ...
    (options, args) = parser.parse_args()
    main(foo=options.foo, bar=options.bar)  # Fix (a)
    main(**options.__dict__)                # Fix (b)

I know I prefer (b), especially if there are many options to pass on. Another work around is used by the pylit project (extending the optparse.Values class).

tags:
posted in Uncategorized by admin

Follow comments via the RSS Feed | Leave a comment | Trackback URL

Leave Your Comment

You must be logged in to post a comment.

 
Powered by Wordpress and MySQL. Theme by openark.org