Adding new actions is a bit trickier, because you have to understand that optparse has a couple of classifications for actions:
These are overlapping sets: some default ``store'' actions are store,
store_const, append, and count, while the default ``typed''
actions are store, append, and callback.
When you add an action, you need to categorize it by listing it in at least one of the following class attributes of Option (all are lists of strings):
ALWAYS_TYPED_ACTIONSstring, to options with no
explicit type whose action is listed in ALWAYS_TYPED_ACTIONS.
In order to actually implement your new action, you must override Option's take_action() method and add a case that recognizes your action.
For example, let's add an extend action. This is similar to the
standard append action, but instead of taking a single value from
the command-line and appending it to an existing list, extend will
take multiple values in a single comma-delimited string, and extend an
existing list with them. That is, if "-names" is an extend
option of type string, the command line
--names=foo,bar --names blah --names ding,dong
would result in a list
["foo", "bar", "blah", "ding", "dong"]
Again we define a subclass of Option:
class MyOption (Option):
ACTIONS = Option.ACTIONS + ("extend",)
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
def take_action(self, action, dest, opt, value, values, parser):
if action == "extend":
lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue)
else:
Option.take_action(
self, action, dest, opt, value, values, parser)
Features of note:
extend both expects a value on the command-line and stores that
value somewhere, so it goes in both STORE_ACTIONS and
TYPED_ACTIONS
string to
extend actions, we put the extend action in
ALWAYS_TYPED_ACTIONS as well
values is an instance of the optparse_parser.Values class,
which provides the very useful ensure_value() method.
ensure_value() is essentially getattr() with a safety valve;
it is called as
values.ensure_value(attr, value)
If the attr attribute of values doesn't exist or is None, then
ensure_value() first sets it to value, and then returns 'value.
This is very handy for actions like extend, append, and
count, all of which accumulate data in a variable and expect that
variable to be of a certain type (a list for the first two, an integer
for the latter). Using ensure_value() means that scripts using
your action don't have to worry about setting a default value for the
option destinations in question; they can just leave the default as
None and ensure_value() will take care of getting it right when
it's needed.