:mod:`optparse` --- Parser for command line options
===================================================

.. module:: optparse
   :synopsis: Command-line option parsing library.
   :deprecated:
.. moduleauthor:: Greg Ward <gward@python.net>
.. sectionauthor:: Greg Ward <gward@python.net>

.. versionadded:: 2.3

.. deprecated:: 2.7
   The :mod:`optparse` module is deprecated and will not be developed further;
   development will continue with the :mod:`argparse` module.

**Source code:** :source:`Lib/optparse.py`

--------------

:mod:`optparse` is a more convenient, flexible, and powerful library for parsing
command-line options than the old :mod:`getopt` module.  :mod:`optparse` uses a
more declarative style of command-line parsing: you create an instance of
:class:`OptionParser`, populate it with options, and parse the command
line. :mod:`optparse` allows users to specify options in the conventional
GNU/POSIX syntax, and additionally generates usage and help messages for you.

Here's an example of using :mod:`optparse` in a simple script::

   from optparse import OptionParser
   [...]
   parser = OptionParser()
   parser.add_option("-f", "--file", dest="filename",
                     help="write report to FILE", metavar="FILE")
   parser.add_option("-q", "--quiet",
                     action="store_false", dest="verbose", default=True,
                     help="don't print status messages to stdout")

   (options, args) = parser.parse_args()

With these few lines of code, users of your script can now do the "usual thing"
on the command-line, for example::

   <yourscript> --file=outfile -q

As it parses the command line, :mod:`optparse` sets attributes of the
``options`` object returned by :meth:`parse_args` based on user-supplied
command-line values.  When :meth:`parse_args` returns from parsing this command
line, ``options.filename`` will be ``"outfile"`` and ``options.verbose`` will be
``False``.  :mod:`optparse` supports both long and short options, allows short
options to be merged together, and allows options to be associated with their
arguments in a variety of ways.  Thus, the following command lines are all
equivalent to the above example::

   <yourscript> -f outfile --quiet
   <yourscript> --quiet --file outfile
   <yourscript> -q -foutfile
   <yourscript> -qfoutfile

Additionally, users can run one of  ::

   <yourscript> -h
   <yourscript> --help

and :mod:`optparse` will print out a brief summary of your script's options:

.. code-block:: text

   Usage: <yourscript> [options]

   Options:
     -h, --help            show this help message and exit
     -f FILE, --file=FILE  write report to FILE
     -q, --quiet           don't print status messages to stdout

where the value of *yourscript* is determined at runtime (normally from
``sys.argv[0]``).


.. _optparse-background:

Background
----------

:mod:`optparse` was explicitly designed to encourage the creation of programs
with straightforward, conventional command-line interfaces.  To that end, it
supports only the most common command-line syntax and semantics conventionally
used under Unix.  If you are unfamiliar with these conventions, read this
section to acquaint yourself with them.


.. _optparse-terminology:

Terminology
^^^^^^^^^^^

argument
   a string entered on the command-line, and passed by the shell to ``execl()``
   or ``execv()``.  In Python, arguments are elements of ``sys.argv[1:]``
   (``sys.argv[0]`` is the name of the program being executed).  Unix shells
   also use the term "word".

   It is occasionally desirable to substitute an argument list other than
   ``sys.argv[1:]``, so you should read "argument" as "an element of
   ``sys.argv[1:]``, or of some other list provided as a substitute for
   ``sys.argv[1:]``".

option
   an argument used to supply extra information to guide or customize the
   execution of a program.  There are many different syntaxes for options; the
   traditional Unix syntax is a hyphen ("-") followed by a single letter,
   e.g. ``-x`` or ``-F``.  Also, traditional Unix syntax allows multiple
   options to be merged into a single argument, e.g. ``-x -F`` is equivalent
   to ``-xF``.  The GNU project introduced ``--`` followed by a series of
   hyphen-separated words, e.g. ``--file`` or ``--dry-run``.  These are the
   only two option syntaxes provided by :mod:`optparse`.

   Some other option syntaxes that the world has seen include:

   * a hyphen followed by a few letters, e.g. ``-pf`` (this is *not* the same
     as multiple options merged into a single argument)

   * a hyphen followed by a whole word, e.g. ``-file`` (this is technically
     equivalent to the previous syntax, but they aren't usually seen in the same
     program)

   * a plus sign followed by a single letter, or a few letters, or a word, e.g.
     ``+f``, ``+rgb``

   * a slash followed by a letter, or a few letters, or a word, e.g. ``/f``,
     ``/file``

   These option syntaxes are not supported by :mod:`optparse`, and they never
   will be.  This is deliberate: the first three are non-standard on any
   environment, and the last only makes sense if you're exclusively targeting
   VMS, MS-DOS, and/or Windows.

option argument
   an argument that follows an option, is closely associated with that option,
   and is consumed from the argument list when that option is. With
   :mod:`optparse`, option arguments may either be in a separate argument from
   their option:

   .. code-block:: text

      -f foo
      --file foo

   or included in the same argument:

   .. code-block:: text

      -ffoo
      --file=foo

   Typically, a given option either takes an argument or it doesn't. Lots of
   people want an "optional option arguments" feature, meaning that some options
   will take an argument if they see it, and won't if they don't.  This is
   somewhat controversial, because it makes parsing ambiguous: if ``-a`` takes
   an optional argument and ``-b`` is another option entirely, how do we
   interpret ``-ab``?  Because of this ambiguity, :mod:`optparse` does not
   support this feature.

positional argument
   something leftover in the argument list after options have been parsed, i.e.
   after options and their arguments have been parsed and removed from the
   argument list.

required option
   an option that must be supplied on the command-line; note that the phrase
   "required option" is self-contradictory in English.  :mod:`optparse` doesn't
   prevent you from implementing required options, but doesn't give you much
   help at it either.

For example, consider this hypothetical command-line::

   prog -v --report report.txt foo bar

``-v`` and ``--report`` are both options.  Assuming that ``--report``
takes one argument, ``report.txt`` is an option argument.  ``foo`` and
``bar`` are positional arguments.


.. _optparse-what-options-for:

What are options for?
^^^^^^^^^^^^^^^^^^^^^

Options are used to provide extra information to tune or customize the execution
of a program.  In case it wasn't clear, options are usually *optional*.  A
program should be able to run just fine with no options whatsoever.  (Pick a
random program from the Unix or GNU toolsets.  Can it run without any options at
all and still make sense?  The main exceptions are ``find``, ``tar``, and
``dd``\ ---all of which are mutant oddballs that have been rightly criticized
for their non-standard syntax and confusing interfaces.)

Lots of people want their programs to have "required options".  Think about it.
If it's required, then it's *not optional*!  If there is a piece of information
that your program absolutely requires in order to run successfully, that's what
positional arguments are for.

As an example of good command-line interface design, consider the humble ``cp``
utility, for copying files.  It doesn't make much sense to try to copy files
without supplying a destination and at least one source. Hence, ``cp`` fails if
you run it with no arguments.  However, it has a flexible, useful syntax that
does not require any options at all::

   cp SOURCE DEST
   cp SOURCE ... DEST-DIR

You can get pretty far with just that.  Most ``cp`` implementations provide a
bunch of options to tweak exactly how the files are copied: you can preserve
mode and modification time, avoid following symlinks, ask before clobbering
existing files, etc.  But none of this distracts from the core mission of
``cp``, which is to copy either one file to another, or several files to another
directory.


.. _optparse-what-positional-arguments-for:

What are positional arguments for?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Positional arguments are for those pieces of information that your program
absolutely, positively requires to run.

A good user interface should have as few absolute requirements as possible.  If
your program requires 17 distinct pieces of information in order to run
successfully, it doesn't much matter *how* you get that information from the
user---most people will give up and walk away before they successfully run the
program.  This applies whether the user interface is a command-line, a
configuration file, or a GUI: if you make that many demands on your users, most
of them will simply give up.

In short, try to minimize the amount of information that users are absolutely
required to supply---use sensible defaults whenever possible.  Of course, you
also want to make your programs reasonably flexible.  That's what options are
for.  Again, it doesn't matter if they are entries in a config file, widgets in
the "Preferences" dialog of a GUI, or command-line options---the more options
you implement, the more flexible your program is, and the more complicated its
implementation becomes.  Too much flexibility has drawbacks as well, of course;
too many options can overwhelm users and make your code much harder to maintain.


.. _optparse-tutorial:

Tutorial
--------

While :mod:`optparse` is quite flexible and powerful, it's also straightforward
to use in most cases.  This section covers the code patterns that are common to
any :mod:`optparse`\ -based program.

First, you need to import the OptionParser class; then, early in the main
program, create an OptionParser instance::

   from optparse import OptionParser
   [...]
   parser = OptionParser()

Then you can start defining options.  The basic syntax is::

   parser.add_option(opt_str, ...,
                     attr=value, ...)

Each option has one or more option strings, such as ``-f`` or ``--file``,
and several option attributes that tell :mod:`optparse` what to expect and what
to do when it encounters that option on the command line.

Typically, each option will have one short option string and one long option
string, e.g.::

   parser.add_option("-f", "--file", ...)

You're free to define as many short option strings and as many long option
strings as you like (including zero), as long as there is at least one option
string overall.

The option strings passed to :meth:`OptionParser.add_option` are effectively
labels for the
option defined by that call.  For brevity, we will frequently refer to
*encountering an option* on the command line; in reality, :mod:`optparse`
encounters *option strings* and looks up options from them.

Once all of your options are defined, instruct :mod:`optparse` to parse your
program's command line::

   (options, args) = parser.parse_args()

(If you like, you can pass a custom argument list to :meth:`parse_args`, but
that's rarely necessary: by default it uses ``sys.argv[1:]``.)

:meth:`parse_args` returns two values:

* ``options``, an object containing values for all of your options---e.g. if
  ``--file`` takes a single string argument, then ``options.file`` will be the
  filename supplied by the user, or ``None`` if the user did not supply that
  option

* ``args``, the list of positional arguments leftover after parsing options

This tutorial section only covers the four most important option attributes:
:attr:`~Option.action`, :attr:`~Option.type`, :attr:`~Option.dest`
(destination), and :attr:`~Option.help`. Of these, :attr:`~Option.action` is the
most fundamental.


.. _optparse-understanding-option-actions:

Understanding option actions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Actions tell :mod:`optparse` what to do when it encounters an option on the
command line.  There is a fixed set of actions hard-coded into :mod:`optparse`;
adding new actions is an advanced topic covered in section
:ref:`optparse-extending-optparse`.  Most actions tell :mod:`optparse` to store
a value in some variable---for example, take a string from the command line and
store it in an attribute of ``options``.

If you don't specify an option action, :mod:`optparse` defaults to ``store``.


.. _optparse-store-action:

The store action
^^^^^^^^^^^^^^^^

The most common option action is ``store``, which tells :mod:`optparse` to take
the next argument (or the remainder of the current argument), ensure that it is
of the correct type, and store it to your chosen destination.

For example::

   parser.add_option("-f", "--file",
                     action="store", type="string", dest="filename")

Now let's make up a fake command line and ask :mod:`optparse` to parse it::

   args = ["-f", "foo.txt"]
   (options, args) = parser.parse_args(args)

When :mod:`optparse` sees the option string ``-f``, it consumes the next
argument, ``foo.txt``, and stores it in ``options.filename``.  So, after this
call to :meth:`parse_args`, ``options.filename`` is ``"foo.txt"``.

Some other option types supported by :mod:`optparse` are ``int`` and ``float``.
Here's an option that expects an integer argument::

   parser.add_option("-n", type="int", dest="num")

Note that this option has no long option string, which is perfectly acceptable.
Also, there's no explicit action, since the default is ``store``.

Let's parse another fake command-line.  This time, we'll jam the option argument
right up against the option: since ``-n42`` (one argument) is equivalent to
``-n 42`` (two arguments), the code ::

   (options, args) = parser.parse_args(["-n42"])
   print options.num

will print ``42``.

If you don't specify a type, :mod:`optparse` assumes ``string``.  Combined with
the fact that the default action is ``store``, that means our first example can
be a lot shorter::

   parser.add_option("-f", "--file", dest="filename")

If you don't supply a destination, :mod:`optparse` figures out a sensible
default from the option strings: if the first long option string is
``--foo-bar``, then the default destination is ``foo_bar``.  If there are no
long option strings, :mod:`optparse` looks at the first short option string: the
default destination for ``-f`` is ``f``.

:mod:`optparse` also includes built-in ``long`` and ``complex`` types.  Adding
types is covered in section :ref:`optparse-extending-optparse`.


.. _optparse-handling-boolean-options:

Handling boolean (flag) options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Flag options---set a variable to true or false when a particular option is seen
---are quite common.  :mod:`optparse` supports them with two separate actions,
``store_true`` and ``store_false``.  For example, you might have a ``verbose``
flag that is turned on with ``-v`` and off with ``-q``::

   parser.add_option("-v", action="store_true", dest="verbose")
   parser.add_option("-q", action="store_false", dest="verbose")

Here we have two different options with the same destination, which is perfectly
OK.  (It just means you have to be a bit careful when setting default values---
see below.)

When :mod:`optparse` encounters ``-v`` on the command line, it sets
``options.verbose`` to ``True``; when it encounters ``-q``,
``options.verbose`` is set to ``False``.


.. _optparse-other-actions:

Other actions
^^^^^^^^^^^^^

Some other actions supported by :mod:`optparse` are:

``"store_const"``
   store a constant value

``"append"``
   append this option's argument to a list

``"count"``
   increment a counter by one

``"callback"``
   call a specified function

These are covered in section :ref:`optparse-reference-guide`, Reference Guide
and section :ref:`optparse-option-callbacks`.


.. _optparse-default-values:

Default values
^^^^^^^^^^^^^^

All of the above examples involve setting some variable (the "destination") when
certain command-line options are seen.  What happens if those options are never
seen?  Since we didn't supply any defaults, they are all set to ``None``.  This
is usually fine, but sometimes you want more control.  :mod:`optparse` lets you
supply a default value for each destination, which is assigned before the
command line is parsed.

First, consider the verbose/quiet example.  If we want :mod:`optparse` to set
``verbose`` to ``True`` unless ``-q`` is seen, then we can do this::

   parser.add_option("-v", action="store_true", dest="verbose", default=True)
   parser.add_option("-q", action="store_false", dest="verbose")

Since default values apply to the *destination* rather than to any particular
option, and these two options happen to have the same destination, this is
exactly equivalent::

   parser.add_option("-v", action="store_true", dest="verbose")
   parser.add_option("-q", action="store_false", dest="verbose", default=True)

Consider this::

   parser.add_option("-v", action="store_true", dest="verbose", default=False)
   parser.add_option("-q", action="store_false", dest="verbose", default=True)

Again, the default value for ``verbose`` will be ``True``: the last default
value supplied for any particular destination is the one that counts.

A clearer way to specify default values is the :meth:`set_defaults` method of
OptionParser, which you can call at any time before calling :meth:`parse_args`::

   parser.set_defaults(verbose=True)
   parser.add_option(...)
   (options, args) = parser.parse_args()

As before, the last value specified for a given option destination is the one
that counts.  For clarity, try to use one method or the other of setting default
values, not both.


.. _optparse-generating-help:

Generating help
^^^^^^^^^^^^^^^

:mod:`optparse`'s ability to generate help and usage text automatically is
useful for creating user-friendly command-line interfaces.  All you have to do
is supply a :attr:`~Option.help` value for each option, and optionally a short
usage message for your whole program.  Here's an OptionParser populated with
user-friendly (documented) options::

   usage = "usage: %prog [options] arg1 arg2"
   parser = OptionParser(usage=usage)
   parser.add_option("-v", "--verbose",
                     action="store_true", dest="verbose", default=True,
                     help="make lots of noise [default]")
   parser.add_option("-q", "--quiet",
                     action="store_false", dest="verbose",
                     help="be vewwy quiet (I'm hunting wabbits)")
   parser.add_option("-f", "--filename",
                     metavar="FILE", help="write output to FILE")
   parser.add_option("-m", "--mode",
                     default="intermediate",
                     help="interaction mode: novice, intermediate, "
                          "or expert [default: %default]")

If :mod:`optparse` encounters either ``-h`` or ``--help`` on the
command-line, or if you just call :meth:`parser.print_help`, it prints the
following to standard output:

.. code-block:: text

   Usage: <yourscript> [options] arg1 arg2

   Options:
     -h, --help            show this help message and exit
     -v, --verbose         make lots of noise [default]
     -q, --quiet           be vewwy quiet (I'm hunting wabbits)
     -f FILE, --filename=FILE
                           write output to FILE
     -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                           expert [default: intermediate]

(If the help output is triggered by a help option, :mod:`optparse` exits after
printing the help text.)

There's a lot going on here to help :mod:`optparse` generate the best possible
help message:

* the script defines its own usage message::

     usage = "usage: %prog [options] arg1 arg2"

  :mod:`optparse` expands ``%prog`` in the usage string to the name of the
  current program, i.e. ``os.path.basename(sys.argv[0])``.  The expanded string
  is then printed before the detailed option help.

  If you don't supply a usage string, :mod:`optparse` uses a bland but sensible
  default: ``"Usage: %prog [options]"``, which is fine if your script doesn't
  take any positional arguments.

* every option defines a help string, and doesn't worry about line-wrapping---
  :mod:`optparse` takes care of wrapping lines and making the help output look
  good.

* options that take a value indicate this fact in their automatically-generated
  help message, e.g. for the "mode" option::

     -m MODE, --mode=MODE

  Here, "MODE" is called the meta-variable: it stands for the argument that the
  user is expected to supply to ``-m``/``--mode``.  By default,
  :mod:`optparse` converts the destination variable name to uppercase and uses
  that for the meta-variable.  Sometimes, that's not what you want---for
  example, the ``--filename`` option explicitly sets ``metavar="FILE"``,
  resulting in this automatically-generated option description::

     -f FILE, --filename=FILE

  This is important for more than just saving space, though: the manually
  written help text uses the meta-variable ``FILE`` to clue the user in that
  there's a connection between the semi-formal syntax ``-f FILE`` and the informal
  semantic description "write output to FILE". This is a simple but effective
  way to make your help text a lot clearer and more useful for end users.

.. versionadded:: 2.4
   Options that have a default value can include ``%default`` in the help
   string---\ :mod:`optparse` will replace it with :func:`str` of the option's
   default value.  If an option has no default value (or the default value is
   ``None``), ``%default`` expands to ``none``.

Grouping Options
++++++++++++++++

When dealing with many options, it is convenient to group these options for
better help output.  An :class:`OptionParser` can contain several option groups,
each of which can contain several options.

An option group is obtained using the class :class:`OptionGroup`:

.. class:: OptionGroup(parser, title, description=None)

   where

   * parser is the :class:`OptionParser` instance the group will be insterted in
     to
   * title is the group title
   * description, optional, is a long description of the group

:class:`OptionGroup` inherits from :class:`OptionContainer` (like
:class:`OptionParser`) and so the :meth:`add_option` method can be used to add
an option to the group.

Once all the options are declared, using the :class:`OptionParser` method
:meth:`add_option_group` the group is added to the previously defined parser.

Continuing with the parser defined in the previous section, adding an
:class:`OptionGroup` to a parser is easy::

    group = OptionGroup(parser, "Dangerous Options",
                        "Caution: use these options at your own risk.  "
                        "It is believed that some of them bite.")
    group.add_option("-g", action="store_true", help="Group option.")
    parser.add_option_group(group)

This would result in the following help output:

.. code-block:: text

   Usage: <yourscript> [options] arg1 arg2

   Options:
     -h, --help            show this help message and exit
     -v, --verbose         make lots of noise [default]
     -q, --quiet           be vewwy quiet (I'm hunting wabbits)
     -f FILE, --filename=FILE
                           write output to FILE
     -m MODE, --mode=MODE  interaction mode: novice, intermediate, or
                           expert [default: intermediate]

     Dangerous Options:
       Caution: use these options at your own risk.  It is believed that some
       of them bite.

       -g                  Group option.

A bit more complete example might involve using more than one group: still
extending the previous example::

    group = OptionGroup(parser, "Dangerous Options",
                        "Caution: use these options at your own risk.  "
                        "It is believed that some of them bite.")
    group.add_option("-g", action="store_true", help="Group option.")
    parser.add_option_group(group)

    group = OptionGroup(parser, "Debug Options")
    group.add_option("-d", "--debug", action="store_true",
                     help="Print debug information")
    group.add_option("-s", "--sql", action="store_true",
                     help="Print all SQL statements executed")
    group.add_option("-e", action="store_true", help="Print every action done")
    parser.add_option_group(group)

that results in the following output:

.. code-block:: text

   Usage: <yourscript> [options] arg1 arg2

   Options:
     -h, --help            show this help message and exit
     -v, --verbose         make lots of noise [default]
     -q, --quiet           be vewwy quiet (I'm hunting wabbits)
     -f FILE, --filename=FILE
                           write output to FILE
     -m MODE, --mode=MODE  interaction mode: novice, intermediate, or expert
                           [default: intermediate]

     Dangerous Options:
       Caution: use these options at your own risk.  It is believed that some
       of them bite.

       -g                  Group option.

     Debug Options:
       -d, --debug         Print debug information
       -s, --sql           Print all SQL statements executed
       -e                  Print every action done

Another interesting method, in particular when working programmatically with
option groups is:

.. method:: OptionParser.get_option_group(opt_str)

   Return the :class:`OptionGroup` to which the short or long option
   string *opt_str* (e.g. ``'-o'`` or ``'--option'``) belongs. If
   there's no such :class:`OptionGroup`, return ``None``.

.. _optparse-printing-version-string:

Printing a version string
^^^^^^^^^^^^^^^^^^^^^^^^^

Similar to the brief usage string, :mod:`optparse` can also print a version
string for your program.  You have to supply the string as the ``version``
argument to OptionParser::

   parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

``%prog`` is expanded just like it is in ``usage``.  Apart from that,
``version`` can contain anything you like.  When you supply it, :mod:`optparse`
automatically adds a ``--version`` option to your parser. If it encounters
this option on the command line, it expands your ``version`` string (by
replacing ``%prog``), prints it to stdout, and exits.

For example, if your script is called ``/usr/bin/foo``::

   $ /usr/bin/foo --version
   foo 1.0

The following two methods can be used to print and get the ``version`` string:

.. method:: OptionParser.print_version(file=None)

   Print the version message for the current program (``self.version``) to
   *file* (default stdout).  As with :meth:`print_usage`, any occurrence
   of ``%prog`` in ``self.version`` is replaced with the name of the current
   program.  Does nothing if ``self.version`` is empty or undefined.

.. method:: OptionParser.get_version()

   Same as :meth:`print_version` but returns the version string instead of
   printing it.


.. _optparse-how-optparse-handles-errors:

How :mod:`optparse` handles errors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There are two broad classes of errors that :mod:`optparse` has to worry about:
programmer errors and user errors.  Programmer errors are usually erroneous
calls to :func:`OptionParser.add_option`, e.g. invalid option strings, unknown
option attributes, missing option attributes, etc.  These are dealt with in the
usual way: raise an exception (either :exc:`optparse.OptionError` or
:exc:`TypeError`) and let the program crash.

Handling user errors is much more important, since they are guaranteed to happen
no matter how stable your code is.  :mod:`optparse` can automatically detect
some user errors, such as bad option arguments (passing ``-n 4x`` where
``-n`` takes an integer argument), missing arguments (``-n`` at the end
of the command line, where ``-n`` takes an argument of any type).  Also,
you can call :func:`OptionParser.error` to signal an application-defined error
condition::

   (options, args) = parser.parse_args()
   [...]
   if options.a and options.b:
       parser.error("options -a and -b are mutually exclusive")

In either case, :mod:`optparse` handles the error the same way: it prints the
program's usage message and an error message to standard error and exits with
error status 2.

Consider the first example above, where the user passes ``4x`` to an option
that takes an integer::

   $ /usr/bin/foo -n 4x
   Usage: foo [options]

   foo: error: option -n: invalid integer value: '4x'

Or, where the user fails to pass a value at all::

   $ /usr/bin/foo -n
   Usage: foo [options]

   foo: error: -n option requires an argument

:mod:`optparse`\ -generated error messages take care always to mention the
option involved in the error; be sure to do the same when calling
:func:`OptionParser.error` from your application code.

If :mod:`optparse`'s default error-handling behaviour does not suit your needs,
you'll need to subclass OptionParser and override its :meth:`~OptionParser.exit`
and/or :meth:`~OptionParser.error` methods.


.. _optparse-putting-it-all-together:

Putting it all together
^^^^^^^^^^^^^^^^^^^^^^^

Here's what :mod:`optparse`\ -based scripts usually look like::

   from optparse import OptionParser
   [...]
   def main():
       usage = "usage: %prog [options] arg"
       parser = OptionParser(usage)
       parser.add_option("-f", "--file", dest="filename",
                         help="read data from FILENAME")
       parser.add_option("-v", "--verbose",
                         action="store_true", dest="verbose")
       parser.add_option("-q", "--quiet",
                         action="store_false", dest="verbose")
       [...]
       (options, args) = parser.parse_args()
       if len(args) != 1:
           parser.error("incorrect number of arguments")
       if options.verbose:
           print "reading %s..." % options.filename
       [...]

   if __name__ == "__main__":
       main()


.. _optparse-reference-guide:

Reference Guide
---------------


.. _optparse-creating-parser:

Creating the parser
^^^^^^^^^^^^^^^^^^^

The first step in using :mod:`optparse` is to create an OptionParser instance.

.. class:: OptionParser(...)

   The OptionParser constructor has no required arguments, but a number of
   optional keyword arguments.  You should always pass them as keyword
   arguments, i.e. do not rely on the order in which the arguments are declared.

   ``usage`` (default: ``"%prog [options]"``)
      The usage summary to print when your program is run incorrectly or with a
      help option.  When :mod:`optparse` prints the usage string, it expands
      ``%prog`` to ``os.path.basename(sys.argv[0])`` (or to ``prog`` if you
      passed that keyword argument).  To suppress a usage message, pass the
      special value :data:`optparse.SUPPRESS_USAGE`.

   ``option_list`` (default: ``[]``)
      A list of Option objects to populate the parser with.  The options in
      ``option_list`` are added after any options in ``standard_option_list`` (a
      class attribute that may be set by OptionParser subclasses), but before
      any version or help options. Deprecated; use :meth:`add_option` after
      creating the parser instead.

   ``option_class`` (default: optparse.Option)
      Class to use when adding options to the parser in :meth:`add_option`.

   ``version`` (default: ``None``)
      A version string to print when the user supplies a version option. If you
      supply a true value for ``version``, :mod:`optparse` automatically adds a
      version option with the single option string ``--version``.  The
      substring ``%prog`` is expanded the same as for ``usage``.

   ``conflict_handler`` (default: ``"error"``)
      Specifies what to do when options with conflicting option strings are
      added to the parser; see section
      :ref:`optparse-conflicts-between-options`.

   ``description`` (default: ``None``)
      A paragraph of text giving a brief overview of your program.
      :mod:`optparse` reformats this paragraph to fit the current terminal width
      and prints it when the user requests help (after ``usage``, but before the
      list of options).

   ``formatter`` (default: a new :class:`IndentedHelpFormatter`)
      An instance of optparse.HelpFormatter that will be used for printing help
      text.  :mod:`optparse` provides two concrete classes for this purpose:
      IndentedHelpFormatter and TitledHelpFormatter.

   ``add_help_option`` (default: ``True``)
      If true, :mod:`optparse` will add a help option (with option strings ``-h``
      and ``--help``) to the parser.

   ``prog``
      The string to use when expanding ``%prog`` in ``usage`` and ``version``
      instead of ``os.path.basename(sys.argv[0])``.

   ``epilog`` (default: ``None``)
      A paragraph of help text to print after the option help.

.. _optparse-populating-parser:

Populating the parser
^^^^^^^^^^^^^^^^^^^^^

There are several ways to populate the parser with options.  The preferred way
is by using :meth:`OptionParser.add_option`, as shown in section
:ref:`optparse-tutorial`.  :meth:`add_option` can be called in one of two ways:

* pass it an Option instance (as returned by :func:`make_option`)

* pass it any combination of positional and keyword arguments that are
  acceptable to :func:`make_option` (i.e., to the Option constructor), and it
  will create the Option instance for you

The other alternative is to pass a list of pre-constructed Option instances to
the OptionParser constructor, as in::

   option_list = [
       make_option("-f", "--filename",
                   action="store", type="string", dest="filename"),
       make_option("-q", "--quiet",
                   action="store_false", dest="verbose"),
       ]
   parser = OptionParser(option_list=option_list)

(:func:`make_option` is a factory function for creating Option instances;
currently it is an alias for the Option constructor.  A future version of
:mod:`optparse` may split Option into several classes, and :func:`make_option`
will pick the right class to instantiate.  Do not instantiate Option directly.)


.. _optparse-defining-options:

Defining options
^^^^^^^^^^^^^^^^

Each Option instance represents a set of synonymous command-line option strings,
e.g. ``-f`` and ``--file``.  You can specify any number of short or
long option strings, but you must specify at least one overall option string.

The canonical way to create an :class:`Option` instance is with the
:meth:`add_option` method of :class:`OptionParser`.

.. method:: OptionParser.add_option(option)
            OptionParser.add_option(*opt_str, attr=value, ...)

   To define an option with only a short option string::

      parser.add_option("-f", attr=value, ...)

   And to define an option with only a long option string::

      parser.add_option("--foo", attr=value, ...)

   The keyword arguments define attributes of the new Option object.  The most
   important option attribute is :attr:`~Option.action`, and it largely
   determines which other attributes are relevant or required.  If you pass
   irrelevant option attributes, or fail to pass required ones, :mod:`optparse`
   raises an :exc:`OptionError` exception explaining your mistake.

   An option's *action* determines what :mod:`optparse` does when it encounters
   this option on the command-line.  The standard option actions hard-coded into
   :mod:`optparse` are:

   ``"store"``
      store this option's argument (default)

   ``"store_const"``
      store a constant value

   ``"store_true"``
      store a true value

   ``"store_false"``
      store a false value

   ``"append"``
      append this option's argument to a list

   ``"append_const"``
      append a constant value to a list

   ``"count"``
      increment a counter by one

   ``"callback"``
      call a specified function

   ``"help"``
      print a usage message including all options and the documentation for them

   (If you don't supply an action, the default is ``"store"``.  For this action,
   you may also supply :attr:`~Option.type` and :attr:`~Option.dest` option
   attributes; see :ref:`optparse-standard-option-actions`.)

As you can see, most actions involve storing or updating a value somewhere.
:mod:`optparse` always creates a special object for this, conventionally called
``options`` (it happens to be an instance of :class:`optparse.Values`).  Option
arguments (and various other values) are stored as attributes of this object,
according to the :attr:`~Option.dest` (destination) option attribute.

For example, when you call ::

   parser.parse_args()

one of the first things :mod:`optparse` does is create the ``options`` object::

   options = Values()

If one of the options in this parser is defined with ::

   parser.add_option("-f", "--file", action="store", type="string", dest="filename")

and the command-line being parsed includes any of the following::

   -ffoo
   -f foo
   --file=foo
   --file foo

then :mod:`optparse`, on seeing this option, will do the equivalent of ::

   options.filename = "foo"

The :attr:`~Option.type` and :attr:`~Option.dest` option attributes are almost
as important as :attr:`~Option.action`, but :attr:`~Option.action` is the only
one that makes sense for *all* options.


.. _optparse-option-attributes:

Option attributes
^^^^^^^^^^^^^^^^^

The following option attributes may be passed as keyword arguments to
:meth:`OptionParser.add_option`.  If you pass an option attribute that is not
relevant to a particular option, or fail to pass a required option attribute,
:mod:`optparse` raises :exc:`OptionError`.

.. attribute:: Option.action

   (default: ``"store"``)

   Determines :mod:`optparse`'s behaviour when this option is seen on the
   command line; the available options are documented :ref:`here
   <optparse-standard-option-actions>`.

.. attribute:: Option.type

   (default: ``"string"``)

   The argument type expected by this option (e.g., ``"string"`` or ``"int"``);
   the available option types are documented :ref:`here
   <optparse-standard-option-types>`.

.. attribute:: Option.dest

   (default: derived from option strings)

   If the option's action implies writing or modifying a value somewhere, this
   tells :mod:`optparse` where to write it: :attr:`~Option.dest` names an
   attribute of the ``options`` object that :mod:`optparse` builds as it parses
   the command line.

.. attribute:: Option.default

   The value to use for this option's destination if the option is not seen on
   the command line.  See also :meth:`OptionParser.set_defaults`.

.. attribute:: Option.nargs

   (default: 1)

   How many arguments of type :attr:`~Option.type` should be consumed when this
   option is seen.  If > 1, :mod:`optparse` will store a tuple of values to
   :attr:`~Option.dest`.

.. attribute:: Option.const

   For actions that store a constant value, the constant value to store.

.. attribute:: Option.choices

   For options of type ``"choice"``, the list of strings the user may choose
   from.

.. attribute:: Option.callback

   For options with action ``"callback"``, the callable to call when this option
   is seen.  See section :ref:`optparse-option-callbacks` for detail on the
   arguments passed to the callable.

.. attribute:: Option.callback_args
               Option.callback_kwargs

   Additional positional and keyword arguments to pass to ``callback`` after the
   four standard callback arguments.

.. attribute:: Option.help

   Help text to print for this option when listing all available options after
   the user supplies a :attr:`~Option.help` option (such as ``--help``).  If
   no help text is supplied, the option will be listed without help text.  To
   hide this option, use the special value :data:`optparse.SUPPRESS_HELP`.

.. attribute:: Option.metavar

   (default: derived from option strings)

   Stand-in for the option argument(s) to use when printing help text.  See
   section :ref:`optparse-tutorial` for an example.


.. _optparse-standard-option-actions:

Standard option actions
^^^^^^^^^^^^^^^^^^^^^^^

The various option actions all have slightly different requirements and effects.
Most actions have several relevant option attributes which you may specify to
guide :mod:`optparse`'s behaviour; a few have required attributes, which you
must specify for any option using that action.

* ``"store"`` [relevant: :attr:`~Option.type`, :attr:`~Option.dest`,
  :attr:`~Option.nargs`, :attr:`~Option.choices`]

  The option must be followed by an argument, which is converted to a value
  according to :attr:`~Option.type` and stored in :attr:`~Option.dest`.  If
  :attr:`~Option.nargs` > 1, multiple arguments will be consumed from the
  command line; all will be converted according to :attr:`~Option.type` and
  stored to :attr:`~Option.dest` as a tuple.  See the
  :ref:`optparse-standard-option-types` section.

  If :attr:`~Option.choices` is supplied (a list or tuple of strings), the type
  defaults to ``"choice"``.

  If :attr:`~Option.type` is not supplied, it defaults to ``"string"``.

  If :attr:`~Option.dest` is not supplied, :mod:`optparse` derives a destination
  from the first long option string (e.g., ``--foo-bar`` implies
  ``foo_bar``). If there are no long option strings, :mod:`optparse` derives a
  destination from the first short option string (e.g., ``-f`` implies ``f``).

  Example::

     parser.add_option("-f")
     parser.add_option("-p", type="float", nargs=3, dest="point")

  As it parses the command line ::

     -f foo.txt -p 1 -3.5 4 -fbar.txt

  :mod:`optparse` will set ::

     options.f = "foo.txt"
     options.point = (1.0, -3.5, 4.0)
     options.f = "bar.txt"

* ``"store_const"`` [required: :attr:`~Option.const`; relevant:
  :attr:`~Option.dest`]

  The value :attr:`~Option.const` is stored in :attr:`~Option.dest`.

  Example::

     parser.add_option("-q", "--quiet",
                       action="store_const", const=0, dest="verbose")
     parser.add_option("-v", "--verbose",
                       action="store_const", const=1, dest="verbose")
     parser.add_option("--noisy",
                       action="store_const", const=2, dest="verbose")

  If ``--noisy`` is seen, :mod:`optparse` will set  ::

     options.verbose = 2

* ``"store_true"`` [relevant: :attr:`~Option.dest`]

  A special case of ``"store_const"`` that stores a true value to
  :attr:`~Option.dest`.

* ``"store_false"`` [relevant: :attr:`~Option.dest`]

  Like ``"store_true"``, but stores a false value.

  Example::

     parser.add_option("--clobber", action="store_true", dest="clobber")
     parser.add_option("--no-clobber", action="store_false", dest="clobber")

* ``"append"`` [relevant: :attr:`~Option.type`, :attr:`~Option.dest`,
  :attr:`~Option.nargs`, :attr:`~Option.choices`]

  The option must be followed by an argument, which is appended to the list in
  :attr:`~Option.dest`.  If no default value for :attr:`~Option.dest` is
  supplied, an empty list is automatically created when :mod:`optparse` first
  encounters this option on the command-line.  If :attr:`~Option.nargs` > 1,
  multiple arguments are consumed, and a tuple of length :attr:`~Option.nargs`
  is appended to :attr:`~Option.dest`.

  The defaults for :attr:`~Option.type` and :attr:`~Option.dest` are the same as
  for the ``"store"`` action.

  Example::

     parser.add_option("-t", "--tracks", action="append", type="int")

  If ``-t3`` is seen on the command-line, :mod:`optparse` does the equivalent
  of::

     options.tracks = []
     options.tracks.append(int("3"))

  If, a little later on, ``--tracks=4`` is seen, it does::

     options.tracks.append(int("4"))

  The ``append`` action calls the ``append`` method on the current value of the
  option.  This means that any default value specified must have an ``append``
  method.  It also means that if the default value is non-empty, the default
  elements will be present in the parsed value for the option, with any values
  from the command line appended after those default values::

     >>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults'])
     >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg'])
     >>> opts.files
     ['~/.mypkg/defaults', 'overrides.mypkg']

* ``"append_const"`` [required: :attr:`~Option.const`; relevant:
  :attr:`~Option.dest`]

  Like ``"store_const"``, but the value :attr:`~Option.const` is appended to
  :attr:`~Option.dest`; as with ``"append"``, :attr:`~Option.dest` defaults to
  ``None``, and an empty list is automatically created the first time the option
  is encountered.

* ``"count"`` [relevant: :attr:`~Option.dest`]

  Increment the integer stored at :attr:`~Option.dest`.  If no default value is
  supplied, :attr:`~Option.dest` is set to zero before being incremented the
  first time.

  Example::

     parser.add_option("-v", action="count", dest="verbosity")

  The first time ``-v`` is seen on the command line, :mod:`optparse` does the
  equivalent of::

     options.verbosity = 0
     options.verbosity += 1

  Every subsequent occurrence of ``-v`` results in  ::

     options.verbosity += 1

* ``"callback"`` [required: :attr:`~Option.callback`; relevant:
  :attr:`~Option.type`, :attr:`~Option.nargs`, :attr:`~Option.callback_args`,
  :attr:`~Option.callback_kwargs`]

  Call the function specified by :attr:`~Option.callback`, which is called as ::

     func(option, opt_str, value, parser, *args, **kwargs)

  See section :ref:`optparse-option-callbacks` for more detail.

* ``"help"``

  Prints a complete help message for all the options in the current option
  parser.  The help message is constructed from the ``usage`` string passed to
  OptionParser's constructor and the :attr:`~Option.help` string passed to every
  option.

  If no :attr:`~Option.help` string is supplied for an option, it will still be
  listed in the help message.  To omit an option entirely, use the special value
  :data:`optparse.SUPPRESS_HELP`.

  :mod:`optparse` automatically adds a :attr:`~Option.help` option to all
  OptionParsers, so you do not normally need to create one.

  Example::

     from optparse import OptionParser, SUPPRESS_HELP

     # usually, a help option is added automatically, but that can
     # be suppressed using the add_help_option argument
     parser = OptionParser(add_help_option=False)

     parser.add_option("-h", "--help", action="help")
     parser.add_option("-v", action="store_true", dest="verbose",
                       help="Be moderately verbose")
     parser.add_option("--file", dest="filename",
                       help="Input file to read data from")
     parser.add_option("--secret", help=SUPPRESS_HELP)

  If :mod:`optparse` sees either ``-h`` or ``--help`` on the command line,
  it will print something like the following help message to stdout (assuming
  ``sys.argv[0]`` is ``"foo.py"``):

  .. code-block:: text

     Usage: foo.py [options]

     Options:
       -h, --help        Show this help message and exit
       -v                Be moderately verbose
       --file=FILENAME   Input file to read data from

  After printing the help message, :mod:`optparse` terminates your process with
  ``sys.exit(0)``.

* ``"version"``

  Prints the version number supplied to the OptionParser to stdout and exits.
  The version number is actually formatted and printed by the
  ``print_version()`` method of OptionParser.  Generally only relevant if the
  ``version`` argument is supplied to the OptionParser constructor.  As with
  :attr:`~Option.help` options, you will rarely create ``version`` options,
  since :mod:`optparse` automatically adds them when needed.


.. _optparse-standard-option-types:

Standard option types
^^^^^^^^^^^^^^^^^^^^^

:mod:`optparse` has six built-in option types: ``"string"``, ``"int"``,
``"long"``, ``"choice"``, ``"float"`` and ``"complex"``.  If you need to add new
option types, see section :ref:`optparse-extending-optparse`.

Arguments to string options are not checked or converted in any way: the text on
the command line is stored in the destination (or passed to the callback) as-is.

Integer arguments (type ``"int"`` or ``"long"``) are parsed as follows:

* if the number starts with ``0x``, it is parsed as a hexadecimal number

* if the number starts with ``0``, it is parsed as an octal number

* if the number starts with ``0b``, it is parsed as a binary number

* otherwise, the number is parsed as a decimal number


The conversion is done by calling either :func:`int` or :func:`long` with the
appropriate base (2, 8, 10, or 16).  If this fails, so will :mod:`optparse`,
although with a more useful error message.

``"float"`` and ``"complex"`` option arguments are converted directly with
:func:`float` and :func:`complex`, with similar error-handling.

``"choice"`` options are a subtype of ``"string"`` options.  The
:attr:`~Option.choices` option attribute (a sequence of strings) defines the
set of allowed option arguments.  :func:`optparse.check_choice` compares
user-supplied option arguments against this master list and raises
:exc:`OptionValueError` if an invalid string is given.


.. _optparse-parsing-arguments:

Parsing arguments
^^^^^^^^^^^^^^^^^

The whole point of creating and populating an OptionParser is to call its
:meth:`parse_args` method::

   (options, args) = parser.parse_args(args=None, values=None)

where the input parameters are

``args``
   the list of arguments to process (default: ``sys.argv[1:]``)

``values``
   a :class:`optparse.Values` object to store option arguments in (default: a
   new instance of :class:`Values`) -- if you give an existing object, the
   option defaults will not be initialized on it

and the return values are

``options``
   the same object that was passed in as ``values``, or the optparse.Values
   instance created by :mod:`optparse`

``args``
   the leftover positional arguments after all options have been processed

The most common usage is to supply neither keyword argument.  If you supply
``values``, it will be modified with repeated :func:`setattr` calls (roughly one
for every option argument stored to an option destination) and returned by
:meth:`parse_args`.

If :meth:`parse_args` encounters any errors in the argument list, it calls the
OptionParser's :meth:`error` method with an appropriate end-user error message.
This ultimately terminates your process with an exit status of 2 (the
traditional Unix exit status for command-line errors).


.. _optparse-querying-manipulating-option-parser:

Querying and manipulating your option parser
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The default behavior of the option parser can be customized slightly, and you
can also poke around your option parser and see what's there.  OptionParser
provides several methods to help you out:

.. method:: OptionParser.disable_interspersed_args()

   Set parsing to stop on the first non-option.  For example, if ``-a`` and
   ``-b`` are both simple options that take no arguments, :mod:`optparse`
   normally accepts this syntax::

      prog -a arg1 -b arg2

   and treats it as equivalent to  ::

      prog -a -b arg1 arg2

   To disable this feature, call :meth:`disable_interspersed_args`.  This
   restores traditional Unix syntax, where option parsing stops with the first
   non-option argument.

   Use this if you have a command processor which runs another command which has
   options of its own and you want to make sure these options don't get
   confused.  For example, each command might have a different set of options.

.. method:: OptionParser.enable_interspersed_args()

   Set parsing to not stop on the first non-option, allowing interspersing
   switches with command arguments.  This is the default behavior.

.. method:: OptionParser.get_option(opt_str)

   Returns the Option instance with the option string *opt_str*, or ``None`` if
   no options have that option string.

.. method:: OptionParser.has_option(opt_str)

   Return true if the OptionParser has an option with option string *opt_str*
   (e.g., ``-q`` or ``--verbose``).

.. method:: OptionParser.remove_option(opt_str)

   If the :class:`OptionParser` has an option corresponding to *opt_str*, that
   option is removed.  If that option provided any other option strings, all of
   those option strings become invalid. If *opt_str* does not occur in any
   option belonging to this :class:`OptionParser`, raises :exc:`ValueError`.


.. _optparse-conflicts-between-options:

Conflicts between options
^^^^^^^^^^^^^^^^^^^^^^^^^

If you're not careful, it's easy to define options with conflicting option
strings::

   parser.add_option("-n", "--dry-run", ...)
   [...]
   parser.add_option("-n", "--noisy", ...)

(This is particularly true if you've defined your own OptionParser subclass with
some standard options.)

Every time you add an option, :mod:`optparse` checks for conflicts with existing
options.  If it finds any, it invokes the current conflict-handling mechanism.
You can set the conflict-handling mechanism either in the constructor::

   parser = OptionParser(..., conflict_handler=handler)

or with a separate call::

   parser.set_conflict_handler(handler)

The available conflict handlers are:

   ``"error"`` (default)
      assume option conflicts are a programming error and raise
      :exc:`OptionConflictError`

   ``"resolve"``
      resolve option conflicts intelligently (see below)


As an example, let's define an :class:`OptionParser` that resolves conflicts
intelligently and add conflicting options to it::

   parser = OptionParser(conflict_handler="resolve")
   parser.add_option("-n", "--dry-run", ..., help="do no harm")
   parser.add_option("-n", "--noisy", ..., help="be noisy")

At this point, :mod:`optparse` detects that a previously-added option is already
using the ``-n`` option string.  Since ``conflict_handler`` is ``"resolve"``,
it resolves the situation by removing ``-n`` from the earlier option's list of
option strings.  Now ``--dry-run`` is the only way for the user to activate
that option.  If the user asks for help, the help message will reflect that::

   Options:
     --dry-run     do no harm
     [...]
     -n, --noisy   be noisy

It's possible to whittle away the option strings for a previously-added option
until there are none left, and the user has no way of invoking that option from
the command-line.  In that case, :mod:`optparse` removes that option completely,
so it doesn't show up in help text or anywhere else. Carrying on with our
existing OptionParser::

   parser.add_option("--dry-run", ..., help="new dry-run option")

At this point, the original ``-n``/``--dry-run`` option is no longer
accessible, so :mod:`optparse` removes it, leaving this help text::

   Options:
     [...]
     -n, --noisy   be noisy
     --dry-run     new dry-run option


.. _optparse-cleanup:

Cleanup
^^^^^^^

OptionParser instances have several cyclic references.  This should not be a
problem for Python's garbage collector, but you may wish to break the cyclic
references explicitly by calling :meth:`~OptionParser.destroy` on your
OptionParser once you are done with it.  This is particularly useful in
long-running applications where large object graphs are reachable from your
OptionParser.


.. _optparse-other-methods:

Other methods
^^^^^^^^^^^^^

OptionParser supports several other public methods:

.. method:: OptionParser.set_usage(usage)

   Set the usage string according to the rules described above for the ``usage``
   constructor keyword argument.  Passing ``None`` sets the default usage
   string; use :data:`optparse.SUPPRESS_USAGE` to suppress a usage message.

.. method:: OptionParser.print_usage(file=None)

   Print the usage message for the current program (``self.usage``) to *file*
   (default stdout).  Any occurrence of the string ``%prog`` in ``self.usage``
   is replaced with the name of the current program.  Does nothing if
   ``self.usage`` is empty or not defined.

.. method:: OptionParser.get_usage()

   Same as :meth:`print_usage` but returns the usage string instead of
   printing it.

.. method:: OptionParser.set_defaults(dest=value, ...)

   Set default values for several option destinations at once.  Using
   :meth:`set_defaults` is the preferred way to set default values for options,
   since multiple options can share the same destination.  For example, if
   several "mode" options all set the same destination, any one of them can set
   the default, and the last one wins::

      parser.add_option("--advanced", action="store_const",
                        dest="mode", const="advanced",
                        default="novice")    # overridden below
      parser.add_option("--novice", action="store_const",
                        dest="mode", const="novice",
                        default="advanced")  # overrides above setting

   To avoid this confusion, use :meth:`set_defaults`::

      parser.set_defaults(mode="advanced")
      parser.add_option("--advanced", action="store_const",
                        dest="mode", const="advanced")
      parser.add_option("--novice", action="store_const",
                        dest="mode", const="novice")


.. _optparse-option-callbacks:

Option Callbacks
----------------

When :mod:`optparse`'s built-in actions and types aren't quite enough for your
needs, you have two choices: extend :mod:`optparse` or define a callback option.
Extending :mod:`optparse` is more general, but overkill for a lot of simple
cases.  Quite often a simple callback is all you need.

There are two steps to defining a callback option:

* define the option itself using the ``"callback"`` action

* write the callback; this is a function (or method) that takes at least four
  arguments, as described below


.. _optparse-defining-callback-option:

Defining a callback option
^^^^^^^^^^^^^^^^^^^^^^^^^^

As always, the easiest way to define a callback option is by using the
:meth:`OptionParser.add_option` method.  Apart from :attr:`~Option.action`, the
only option attribute you must specify is ``callback``, the function to call::

   parser.add_option("-c", action="callback", callback=my_callback)

``callback`` is a function (or other callable object), so you must have already
defined ``my_callback()`` when you create this callback option. In this simple
case, :mod:`optparse` doesn't even know if ``-c`` takes any arguments,
which usually means that the option takes no arguments---the mere presence of
``-c`` on the command-line is all it needs to know.  In some
circumstances, though, you might want your callback to consume an arbitrary
number of command-line arguments.  This is where writing callbacks gets tricky;
it's covered later in this section.

:mod:`optparse` always passes four particular arguments to your callback, and it
will only pass additional arguments if you specify them via
:attr:`~Option.callback_args` and :attr:`~Option.callback_kwargs`.  Thus, the
minimal callback function signature is::

   def my_callback(option, opt, value, parser):

The four arguments to a callback are described below.

There are several other option attributes that you can supply when you define a
callback option:

:attr:`~Option.type`
   has its usual meaning: as with the ``"store"`` or ``"append"`` actions, it
   instructs :mod:`optparse` to consume one argument and convert it to
   :attr:`~Option.type`.  Rather than storing the converted value(s) anywhere,
   though, :mod:`optparse` passes it to your callback function.

:attr:`~Option.nargs`
   also has its usual meaning: if it is supplied and > 1, :mod:`optparse` will
   consume :attr:`~Option.nargs` arguments, each of which must be convertible to
   :attr:`~Option.type`.  It then passes a tuple of converted values to your
   callback.

:attr:`~Option.callback_args`
   a tuple of extra positional arguments to pass to the callback

:attr:`~Option.callback_kwargs`
   a dictionary of extra keyword arguments to pass to the callback


.. _optparse-how-callbacks-called:

How callbacks are called
^^^^^^^^^^^^^^^^^^^^^^^^

All callbacks are called as follows::

   func(option, opt_str, value, parser, *args, **kwargs)

where

``option``
   is the Option instance that's calling the callback

``opt_str``
   is the option string seen on the command-line that's triggering the callback.
   (If an abbreviated long option was used, ``opt_str`` will be the full,
   canonical option string---e.g. if the user puts ``--foo`` on the
   command-line as an abbreviation for ``--foobar``, then ``opt_str`` will be
   ``"--foobar"``.)

``value``
   is the argument to this option seen on the command-line.  :mod:`optparse` will
   only expect an argument if :attr:`~Option.type` is set; the type of ``value`` will be
   the type implied by the option's type.  If :attr:`~Option.type` for this option is
   ``None`` (no argument expected), then ``value`` will be ``None``.  If :attr:`~Option.nargs`
   > 1, ``value`` will be a tuple of values of the appropriate type.

``parser``
   is the OptionParser instance driving the whole thing, mainly useful because
   you can access some other interesting data through its instance attributes:

   ``parser.largs``
      the current list of leftover arguments, ie. arguments that have been
      consumed but are neither options nor option arguments. Feel free to modify
      ``parser.largs``, e.g. by adding more arguments to it.  (This list will
      become ``args``, the second return value of :meth:`parse_args`.)

   ``parser.rargs``
      the current list of remaining arguments, ie. with ``opt_str`` and
      ``value`` (if applicable) removed, and only the arguments following them
      still there.  Feel free to modify ``parser.rargs``, e.g. by consuming more
      arguments.

   ``parser.values``
      the object where option values are by default stored (an instance of
      optparse.OptionValues).  This lets callbacks use the same mechanism as the
      rest of :mod:`optparse` for storing option values; you don't need to mess
      around with globals or closures.  You can also access or modify the
      value(s) of any options already encountered on the command-line.

``args``
   is a tuple of arbitrary positional arguments supplied via the
   :attr:`~Option.callback_args` option attribute.

``kwargs``
   is a dictionary of arbitrary keyword arguments supplied via
   :attr:`~Option.callback_kwargs`.


.. _optparse-raising-errors-in-callback:

Raising errors in a callback
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The callback function should raise :exc:`OptionValueError` if there are any
problems with the option or its argument(s).  :mod:`optparse` catches this and
terminates the program, printing the error message you supply to stderr.  Your
message should be clear, concise, accurate, and mention the option at fault.
Otherwise, the user will have a hard time figuring out what he did wrong.


.. _optparse-callback-example-1:

Callback example 1: trivial callback
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Here's an example of a callback option that takes no arguments, and simply
records that the option was seen::

   def record_foo_seen(option, opt_str, value, parser):
       parser.values.saw_foo = True

   parser.add_option("--foo", action="callback", callback=record_foo_seen)

Of course, you could do that with the ``"store_true"`` action.


.. _optparse-callback-example-2:

Callback example 2: check option order
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Here's a slightly more interesting example: record the fact that ``-a`` is
seen, but blow up if it comes after ``-b`` in the command-line.  ::

   def check_order(option, opt_str, value, parser):
       if parser.values.b:
           raise OptionValueError("can't use -a after -b")
       parser.values.a = 1
   [...]
   parser.add_option("-a", action="callback", callback=check_order)
   parser.add_option("-b", action="store_true", dest="b")


.. _optparse-callback-example-3:

Callback example 3: check option order (generalized)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you want to re-use this callback for several similar options (set a flag, but
blow up if ``-b`` has already been seen), it needs a bit of work: the error
message and the flag that it sets must be generalized.  ::

   def check_order(option, opt_str, value, parser):
       if parser.values.b:
           raise OptionValueError("can't use %s after -b" % opt_str)
       setattr(parser.values, option.dest, 1)
   [...]
   parser.add_option("-a", action="callback", callback=check_order, dest='a')
   parser.add_option("-b", action="store_true", dest="b")
   parser.add_option("-c", action="callback", callback=check_order, dest='c')


.. _optparse-callback-example-4:

Callback example 4: check arbitrary condition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Of course, you could put any condition in there---you're not limited to checking
the values of already-defined options.  For example, if you have options that
should not be called when the moon is full, all you have to do is this::

   def check_moon(option, opt_str, value, parser):
       if is_moon_full():
           raise OptionValueError("%s option invalid when moon is full"
                                  % opt_str)
       setattr(parser.values, option.dest, 1)
   [...]
   parser.add_option("--foo",
                     action="callback", callback=check_moon, dest="foo")

(The definition of ``is_moon_full()`` is left as an exercise for the reader.)


.. _optparse-callback-example-5:

Callback example 5: fixed arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Things get slightly more interesting when you define callback options that take
a fixed number of arguments.  Specifying that a callback option takes arguments
is similar to defining a ``"store"`` or ``"append"`` option: if you define
:attr:`~Option.type`, then the option takes one argument that must be
convertible to that type; if you further define :attr:`~Option.nargs`, then the
option takes :attr:`~Option.nargs` arguments.

Here's an example that just emulates the standard ``"store"`` action::

   def store_value(option, opt_str, value, parser):
       setattr(parser.values, option.dest, value)
   [...]
   parser.add_option("--foo",
                     action="callback", callback=store_value,
                     type="int", nargs=3, dest="foo")

Note that :mod:`optparse` takes care of consuming 3 arguments and converting
them to integers for you; all you have to do is store them.  (Or whatever;
obviously you don't need a callback for this example.)


.. _optparse-callback-example-6:

Callback example 6: variable arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Things get hairy when you want an option to take a variable number of arguments.
For this case, you must write a callback, as :mod:`optparse` doesn't provide any
built-in capabilities for it.  And you have to deal with certain intricacies of
conventional Unix command-line parsing that :mod:`optparse` normally handles for
you.  In particular, callbacks should implement the conventional rules for bare
``--`` and ``-`` arguments:

* either ``--`` or ``-`` can be option arguments

* bare ``--`` (if not the argument to some option): halt command-line
  processing and discard the ``--``

* bare ``-`` (if not the argument to some option): halt command-line
  processing but keep the ``-`` (append it to ``parser.largs``)

If you want an option that takes a variable number of arguments, there are
several subtle, tricky issues to worry about.  The exact implementation you
choose will be based on which trade-offs you're willing to make for your
application (which is why :mod:`optparse` doesn't support this sort of thing
directly).

Nevertheless, here's a stab at a callback for an option with variable
arguments::

    def vararg_callback(option, opt_str, value, parser):
        assert value is None
        value = []

        def floatable(str):
            try:
                float(str)
                return True
            except ValueError:
                return False

        for arg in parser.rargs:
            # stop on --foo like options
            if arg[:2] == "--" and len(arg) > 2:
                break
            # stop on -a, but not on -3 or -3.0
            if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
                break
            value.append(arg)

        del parser.rargs[:len(value)]
        setattr(parser.values, option.dest, value)

   [...]
   parser.add_option("-c", "--callback", dest="vararg_attr",
                     action="callback", callback=vararg_callback)


.. _optparse-extending-optparse:

Extending :mod:`optparse`
-------------------------

Since the two major controlling factors in how :mod:`optparse` interprets
command-line options are the action and type of each option, the most likely
direction of extension is to add new actions and new types.


.. _optparse-adding-new-types:

Adding new types
^^^^^^^^^^^^^^^^

To add new types, you need to define your own subclass of :mod:`optparse`'s
:class:`Option` class.  This class has a couple of attributes that define
:mod:`optparse`'s types: :attr:`~Option.TYPES` and :attr:`~Option.TYPE_CHECKER`.

.. attribute:: Option.TYPES

   A tuple of type names; in your subclass, simply define a new tuple
   :attr:`TYPES` that builds on the standard one.

.. attribute:: Option.TYPE_CHECKER

   A dictionary mapping type names to type-checking functions.  A type-checking
   function has the following signature::

      def check_mytype(option, opt, value)

   where ``option`` is an :class:`Option` instance, ``opt`` is an option string
   (e.g., ``-f``), and ``value`` is the string from the command line that must
   be checked and converted to your desired type.  ``check_mytype()`` should
   return an object of the hypothetical type ``mytype``.  The value returned by
   a type-checking function will wind up in the OptionValues instance returned
   by :meth:`OptionParser.parse_args`, or be passed to a callback as the
   ``value`` parameter.

   Your type-checking function should raise :exc:`OptionValueError` if it
   encounters any problems.  :exc:`OptionValueError` takes a single string
   argument, which is passed as-is to :class:`OptionParser`'s :meth:`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 :mod:`optparse` 1.3 added built-in support for
complex numbers, 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
:attr:`~Option.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 :func:`copy` of :attr:`Option.TYPE_CHECKER`, we would end
up modifying the :attr:`~Option.TYPE_CHECKER` attribute of :mod:`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 :mod:`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", type="complex")

Alternately, you can build your own option list and pass it to OptionParser; if
you don't use :meth:`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)


.. _optparse-adding-new-actions:

Adding new actions
^^^^^^^^^^^^^^^^^^

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

"store" actions
   actions that result in :mod:`optparse` storing a value to an attribute of the
   current OptionValues instance; these options require a :attr:`~Option.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 :attr:`~Option.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 categorize it by listing it in at least one
of the following class attributes of Option (all are lists of strings):

.. attribute:: Option.ACTIONS

   All actions must be listed in ACTIONS.

.. attribute:: Option.STORE_ACTIONS

   "store" actions are additionally listed here.

.. attribute:: Option.TYPED_ACTIONS

   "typed" actions are additionally listed here.

.. attribute:: Option.ALWAYS_TYPED_ACTIONS

   Actions that always take a type (i.e. whose options always take a value) are
   additionally listed here.  The only effect of this is that :mod:`optparse`
   assigns the default type, ``"string"``, to options with no explicit type
   whose action is listed in :attr:`ALWAYS_TYPED_ACTIONS`.

In order to actually implement your new action, you must override Option's
:meth:`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 :attr:`~Option.STORE_ACTIONS` and
  :attr:`~Option.TYPED_ACTIONS`.

* to ensure that :mod:`optparse` assigns the default type of ``"string"`` to
  ``"extend"`` actions, we put the ``"extend"`` action in
  :attr:`~Option.ALWAYS_TYPED_ACTIONS` as well.

* :meth:`MyOption.take_action` implements just this one new action, and passes
  control back to :meth:`Option.take_action` for the standard :mod:`optparse`
  actions.

* ``values`` is an instance of the optparse_parser.Values class, which provides
  the very useful :meth:`ensure_value` method. :meth:`ensure_value` is
  essentially :func:`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
  :meth:`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 :meth:`ensure_value` will take care of
  getting it right when it's needed.
