6.21.5.2 Adding new actions

Adding new actions is a bit trickier, because you have to understand that optparse has a couple of classifications for actions:

``store'' actions
actions that result in optparse storing a value to an attribute of the current OptionValues instance; these options require a dest attribute to be supplied to the Option constructor
``typed'' actions
actions that take a value from the command line and expect it to be of a certain type; or rather, a string that can be converted to a certain type. These options require a type attribute to the Option constructor.

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 decide if it's a ``store'' action, a ``typed'' action, neither, or both. Three class attributes of Option (or your Option subclass) control this:

ACTIONS
all actions must be listed in ACTIONS
STORE_ACTIONS
``store'' actions are additionally listed here
TYPED_ACTIONS
``typed'' actions are additionally listed here

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",)

    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:

See About this document... for information on suggesting changes.