6.20.5.1 Adding new types
To add new types, you need to define your own subclass of optparse's
Option class. This class has a couple of attributes that define optparse's types: TYPES and TYPE_CHECKER.
TYPES is a tuple of type names; in your subclass, simply define a
new tuple TYPES that builds on the standard one.
TYPE_CHECKER is a dictionary mapping type names to type-checking
functions. A type-checking function has the following signature:
def check_foo (option : Option, opt : string, value : string)
-> foo
You can name it whatever you like, and make it return any type you like. The value returned
by a type-checking function will wind up in the OptionValues instance
returned by OptionParser.parse_args(), or be passed to callbacks as
the value parameter.
Your type-checking function should raise OptionValueError if it
encounters any problems. OptionValueError takes a single string
argument, which is passed as-is to OptionParser's error()
method, which in turn prepends the program name and the string ``error:'' and prints
everything to stderr before terminating the process.
Here's a silly example that demonstrates adding a ``complex'' option type to parse
Python-style complex numbers on the command line. (This is even sillier than it used to be,
because optparse 1.3 adds built-in support for complex numbers [purely
for completeness], but never mind.)
First, the necessary imports:
from copy import copy
from optparse import Option, OptionValueError
You need to define your type-checker first, since it's referred to later (in the TYPE_CHECKER class attribute of your Option
subclass):
def check_complex (option, opt, value):
try:
return complex(value)
except ValueError:
raise OptionValueError(
"option %s: invalid complex value: %r" % (opt, value))
Finally, the Option subclass:
class MyOption (Option):
TYPES = Option.TYPES + ("complex",)
TYPE_CHECKER = copy(Option.TYPE_CHECKER)
TYPE_CHECKER["complex"] = check_complex
(If we didn't make a copy() of Option.TYPE_CHECKER,
we would end up modifying the TYPE_CHECKER attribute of optparse's Option class. This being Python, nothing stops you from doing
that except good manners and common sense.)
That's it! Now you can write a script that uses the new option type just like any other optparse-based script, except you have to instruct your OptionParser
to use MyOption instead of Option:
parser = OptionParser(option_class=MyOption)
parser.add_option("-c", action="store", type="complex", dest="c")
Alternately, you can build your own option list and pass it to OptionParser;
if you don't use add_option() in the above way, you don't need to tell
OptionParser which option class to use:
option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)
|