diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index 78922b1..750e819 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -1,1758 +1,1758 @@
-:mod:`argparse` -- Parser for command line options, arguments and sub-commands
-==============================================================================
-
-.. module:: argparse
-   :synopsis: Command-line option and argument parsing library.
-.. moduleauthor:: Steven Bethard <steven.bethard@gmail.com>
-.. versionadded:: 2.7
-.. sectionauthor:: Steven Bethard <steven.bethard@gmail.com>
-
-
-The :mod:`argparse` module makes it easy to write user friendly command line
-interfaces. You define what arguments your program requires, and
-:mod:`argparse` will figure out how to parse those out of ``sys.argv``. The
-:mod:`argparse` module also automatically generates help and usage messages
-based on the arguments you have defined, and issues errors when users give your
-program invalid arguments.
-
-Example
--------
-
-As an example, the following code is a Python program that takes a list of
-integers and produces either the sum or the max::
-
-   import argparse
-
-   parser = argparse.ArgumentParser(description='Process some integers.')
-   parser.add_argument('integers', metavar='N', type=int, nargs='+',
-                      help='an integer for the accumulator')
-   parser.add_argument('--sum', dest='accumulate', action='store_const',
-                      const=sum, default=max,
-                      help='sum the integers (default: find the max)')
-
-   args = parser.parse_args()
-   print args.accumulate(args.integers)
-
-Assuming the Python code above is saved into a file called ``prog.py``, it can
-be run at the command line and provides useful help messages::
-
-   $ prog.py -h
-   usage: prog.py [-h] [--sum] N [N ...]
-
-   Process some integers.
-
-   positional arguments:
-    N           an integer for the accumulator
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --sum       sum the integers (default: find the max)
-
-When run with the appropriate arguments, it prints either the sum or the max of
-the command-line integers::
-
-   $ prog.py 1 2 3 4
-   4
-
-   $ prog.py 1 2 3 4 --sum
-   10
-
-If invalid arguments are passed in, it will issue an error::
-
-   $ prog.py a b c
-   usage: prog.py [-h] [--sum] N [N ...]
-   prog.py: error: argument N: invalid int value: 'a'
-
-The following sections walk you through this example.
-
-Creating a parser
-^^^^^^^^^^^^^^^^^
-
-Pretty much every script that uses the :mod:`argparse` module will start out by
-creating an :class:`ArgumentParser` object::
-
-   >>> parser = argparse.ArgumentParser(description='Process some integers.')
-
-The :class:`ArgumentParser` object will hold all the information necessary to
-parse the command line into a more manageable form for your program.
-
-
-Adding arguments
-^^^^^^^^^^^^^^^^
-
-Once you've created an :class:`ArgumentParser`, you'll want to fill it with
-information about your program arguments. You typically do this by making calls
-to the :meth:`add_argument` method.  Generally, these calls tell the
-:class:`ArgumentParser` how to take the strings on the command line and turn
-them into objects for you. This information is stored and used when
-:meth:`parse_args` is called. For example, if we add some arguments like this::
-
-   >>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
-   ...                     help='an integer for the accumulator')
-   >>> parser.add_argument('--sum', dest='accumulate', action='store_const',
-   ...                     const=sum, default=max,
-   ...                     help='sum the integers (default: find the max)')
-
-when we later call :meth:`parse_args`, we can expect it to return an object
-with two attributes, ``integers`` and ``accumulate``.  The ``integers``
-attribute will be a list of one or more ints, and the ``accumulate`` attribute
-will be either the ``sum`` function, if ``--sum`` was specified at the command
-line, or the ``max`` function if it was not.
-
-Parsing arguments
-^^^^^^^^^^^^^^^^^
-
-Once an :class:`ArgumentParser` has been initialized with appropriate calls to
-:meth:`add_argument`, it can be instructed to parse the command-line args by
-calling the :meth:`parse_args` method.  This will inspect the command-line,
-convert each arg to the appropriate type and then invoke the appropriate
-action.  In most cases, this means a simple namespace object will be built up
-from attributes parsed out of the command-line::
-
-   >>> parser.parse_args(['--sum', '7', '-1', '42'])
-   Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])
-
-In a script, :meth:`parse_args` will typically be called with no arguments, and
-the :class:`ArgumentParser` will automatically determine the command-line args
-from ``sys.argv``. That's pretty much it. You're now ready to go write some
-command line interfaces!
-
-
-ArgumentParser objects
-----------------------
-
-.. class:: ArgumentParser([description], [epilog], [prog], [usage], [add_help], [argument_default], [parents], [prefix_chars], [conflict_handler], [formatter_class])
-
-   Create a new :class:`ArgumentParser` object. Each parameter has its own more
-   detailed description below, but in short they are:
-
-   * description_ - Text to display before the argument help.
-
-   * epilog_ - Text to display after the argument help.
-
-   * add_help_ - Add a -h/--help option to the parser. (default: True)
-
-   * argument_default_ - Set the global default value for arguments.
-     (default: None)
-
-   * parents_ - A list of :class:ArgumentParser objects whose arguments should
-     also be included.
-
-   * prefix_chars_ - The set of characters that prefix optional arguments.
-     (default: '-')
-
-   * fromfile_prefix_chars_ - The set of characters that prefix files from
-     which additional arguments should be read. (default: None)
-
-   * formatter_class_ - A class for customizing the help output.
-
-   * conflict_handler_ - Usually unnecessary, defines strategy for resolving
-     conflicting optionals.
-
-   * prog_ - Usually unnecessary, the name of the program
-     (default: ``sys.argv[0]``)
-
-   * usage_ - Usually unnecessary, the string describing the program usage
-     (default: generated)
-
-   The following sections describe how each of these are used.
-
-
-description
-^^^^^^^^^^^
-
-Most calls to the ArgumentParser constructor will use the ``description=``
-keyword argument. This argument gives a brief description of what the program
-does and how it works. In help messages, the description is displayed between
-the command-line usage string and the help messages for the various arguments::
-
-   >>> parser = argparse.ArgumentParser(description='A foo that bars')
-   >>> parser.print_help()
-   usage: argparse.py [-h]
-
-   A foo that bars
-
-   optional arguments:
-    -h, --help  show this help message and exit
-
-By default, the description will be line-wrapped so that it fits within the
-given space. To change this behavior, see the formatter_class_ argument.
-
-
-epilog
-^^^^^^
-
-Some programs like to display additional description of the program after the
-description of the arguments. Such text can be specified using the ``epilog=``
-argument to ArgumentParser::
-
-   >>> parser = argparse.ArgumentParser(
-   ...     description='A foo that bars',
-   ...     epilog="And that's how you'd foo a bar")
-   >>> parser.print_help()
-   usage: argparse.py [-h]
-
-   A foo that bars
-
-   optional arguments:
-    -h, --help  show this help message and exit
-
-   And that's how you'd foo a bar
-
-As with the description_ argument, the ``epilog=`` text is by default
-line-wrapped, but this behavior can be adjusted with the formatter_class_
-argument to ArgumentParser.
-
-
-add_help
-^^^^^^^^
-
-By default, ArgumentParser objects add a ``-h/--help`` option which simply
-displays the parser's help message. For example, consider a file named
-``myprogram.py`` containing the following code::
-
-   import argparse
-   parser = argparse.ArgumentParser()
-   parser.add_argument('--foo', help='foo help')
-   args = parser.parse_args()
-
-If ``-h`` or ``--help`` is supplied is at the command-line, the ArgumentParser
-help will be printed::
-
-   $ python myprogram.py --help
-   usage: myprogram.py [-h] [--foo FOO]
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo FOO   foo help
-
-Occasionally, it may be useful to disable the addition of this help option.
-This can be achieved by passing ``False`` as the ``add_help=`` argument to
-ArgumentParser::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
-   >>> parser.add_argument('--foo', help='foo help')
-   >>> parser.print_help()
-   usage: PROG [--foo FOO]
-
-   optional arguments:
-    --foo FOO  foo help
-
-
-prefix_chars
-^^^^^^^^^^^^
-
-Most command-line options will use ``'-'`` as the prefix, e.g. ``-f/--foo``.
-Parsers that need to support additional prefix characters, e.g. for options
-like ``+f`` or ``/foo``, may specify them using the ``prefix_chars=`` argument
-to the ArgumentParser constructor::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
-   >>> parser.add_argument('+f')
-   >>> parser.add_argument('++bar')
-   >>> parser.parse_args('+f X ++bar Y'.split())
-   Namespace(bar='Y', f='X')
-
-The ``prefix_chars=`` argument defaults to ``'-'``. Supplying a set of
-characters that does not include ``'-'`` will cause ``-f/--foo`` options to be
-disallowed.
-
-
-fromfile_prefix_chars
-^^^^^^^^^^^^^^^^^^^^^
-
-Sometimes, e.g. for particularly long argument lists, it may make sense to
-keep the list of arguments in a file rather than typing it out at the command
-line. If the ``fromfile_prefix_chars=`` argument is given to the ArgumentParser
-constructor, then arguments that start with any of the specified characters
-will be treated as files, and will be replaced by the arguments they contain.
-For example::
-
-   >>> open('args.txt', 'w').write('-f\nbar')
-   >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
-   >>> parser.add_argument('-f')
-   >>> parser.parse_args(['-f', 'foo', '@args.txt'])
-   Namespace(f='bar')
-
-Arguments read from a file must by default be one per line (but see also
-:meth:`convert_arg_line_to_args`) and are treated as if they were in the same
-place as the original file referencing argument on the command line. So in the
-example above, the expression ``['-f', 'foo', '@args.txt']`` is considered
-equivalent to the expression ``['-f', 'foo', '-f', 'bar']``.
-
-The ``fromfile_prefix_chars=`` argument defaults to ``None``, meaning that
-arguments will never be treated as file references.
-
-argument_default
-^^^^^^^^^^^^^^^^
-
-Generally, argument defaults are specified either by passing a default to
-:meth:`add_argument` or by calling the :meth:`set_defaults` methods with a
-specific set of name-value pairs. Sometimes however, it may be useful to
-specify a single parser-wide default for arguments. This can be accomplished by
-passing the ``argument_default=`` keyword argument to ArgumentParser. For
-example, to globally suppress attribute creation on :meth:`parse_args` calls,
-we supply ``argument_default=SUPPRESS``::
-
-   >>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
-   >>> parser.add_argument('--foo')
-   >>> parser.add_argument('bar', nargs='?')
-   >>> parser.parse_args(['--foo', '1', 'BAR'])
-   Namespace(bar='BAR', foo='1')
-   >>> parser.parse_args([])
-   Namespace()
-
-
-parents
-^^^^^^^
-
-Sometimes, several parsers share a common set of arguments. Rather than
-repeating the definitions of these arguments, you can define a single parser
-with all the shared arguments and then use the ``parents=`` argument to
-ArgumentParser to have these "inherited". The ``parents=`` argument takes a
-list of ArgumentParser objects, collects all the positional and optional
-actions from them, and adds these actions to the ArgumentParser object being
-constructed::
-
-   >>> parent_parser = argparse.ArgumentParser(add_help=False)
-   >>> parent_parser.add_argument('--parent', type=int)
-
-   >>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
-   >>> foo_parser.add_argument('foo')
-   >>> foo_parser.parse_args(['--parent', '2', 'XXX'])
-   Namespace(foo='XXX', parent=2)
-
-   >>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
-   >>> bar_parser.add_argument('--bar')
-   >>> bar_parser.parse_args(['--bar', 'YYY'])
-   Namespace(bar='YYY', parent=None)
-
-Note that most parent parsers will specify ``add_help=False``. Otherwise, the
-ArgumentParser will see two ``-h/--help`` options (one in the parent and one in
-the child) and raise an error.
-
-
-formatter_class
-^^^^^^^^^^^^^^^
-
-ArgumentParser objects allow the help formatting to be customized by specifying
-an alternate formatting class. Currently, there are three such classes:
-``argparse.RawDescriptionHelpFormatter``, ``argparse.RawTextHelpFormatter`` and
-``argparse.ArgumentDefaultsHelpFormatter``. The first two allow more control
-over how textual descriptions are displayed, while the last automatically adds
-information about argument default values.
-
-By default, ArgumentParser objects line-wrap the description_ and epilog_ texts
-in command-line help messages::
-
-   >>> parser = argparse.ArgumentParser(
-   ...     prog='PROG',
-   ...     description='''this description
-   ...         was indented weird
-   ...             but that is okay''',
-   ...     epilog='''
-   ...             likewise for this epilog whose whitespace will
-   ...         be cleaned up and whose words will be wrapped
-   ...         across a couple lines''')
-   >>> parser.print_help()
-   usage: PROG [-h]
-
-   this description was indented weird but that is okay
-
-   optional arguments:
-    -h, --help  show this help message and exit
-
-   likewise for this epilog whose whitespace will be cleaned up and whose words
-   will be wrapped across a couple lines
-
-When you have description_ and epilog_ that is already correctly formatted and
-should not be line-wrapped, you can indicate this by passing
-``argparse.RawDescriptionHelpFormatter`` as the ``formatter_class=`` argument
-to ArgumentParser::
-
-   >>> parser = argparse.ArgumentParser(
-   ...     prog='PROG',
-   ...     formatter_class=argparse.RawDescriptionHelpFormatter,
-   ...     description=textwrap.dedent('''\
-   ...         Please do not mess up this text!
-   ...         --------------------------------
-   ...             I have indented it
-   ...             exactly the way
-   ...             I want it
-   ...         '''))
-   >>> parser.print_help()
-   usage: PROG [-h]
-
-   Please do not mess up this text!
-   --------------------------------
-      I have indented it
-      exactly the way
-      I want it
-
-   optional arguments:
-    -h, --help  show this help message and exit
-
-If you want to maintain whitespace for all sorts of help text (including
-argument descriptions), you can use ``argparse.RawTextHelpFormatter``.
-
-The other formatter class available,
-``argparse.ArgumentDefaultsHelpFormatter``, will add information about the
-default value of each of the arguments::
-
-   >>> parser = argparse.ArgumentParser(
-   ...     prog='PROG',
-   ...     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
-   >>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
-   >>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
-   >>> parser.print_help()
-   usage: PROG [-h] [--foo FOO] [bar [bar ...]]
-
-   positional arguments:
-    bar         BAR! (default: [1, 2, 3])
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo FOO   FOO! (default: 42)
-
-
-conflict_handler
-^^^^^^^^^^^^^^^^
-
-ArgumentParser objects do not allow two actions with the same option string.
-By default, ArgumentParser objects will raise an exception if you try to create
-an argument with an option string that is already in use::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-f', '--foo', help='old foo help')
-   >>> parser.add_argument('--foo', help='new foo help')
-   Traceback (most recent call last):
-    ..
-   ArgumentError: argument --foo: conflicting option string(s): --foo
-
-Sometimes (e.g. when using parents_) it may be useful to simply override any
-older arguments with the same option string. To get this behavior, the value
-``'resolve'`` can be supplied to the ``conflict_handler=`` argument of
-ArgumentParser::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
-   >>> parser.add_argument('-f', '--foo', help='old foo help')
-   >>> parser.add_argument('--foo', help='new foo help')
-   >>> parser.print_help()
-   usage: PROG [-h] [-f FOO] [--foo FOO]
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    -f FOO      old foo help
-    --foo FOO   new foo help
-
-Note that ArgumentParser objects only remove an action if all of its option
-strings are overridden. So, in the example above, the old ``-f/--foo`` action
-is retained as the ``-f`` action, because only the ``--foo`` option string was
-overridden.
-
-
-prog
-^^^^
-
-By default, ArgumentParser objects use ``sys.argv[0]`` to determine how to
-display the name of the program in help messages. This default is almost always
-what you want because it will make the help messages match what your users have
-typed at the command line. For example, consider a file named ``myprogram.py``
-with the following code::
-
-   import argparse
-   parser = argparse.ArgumentParser()
-   parser.add_argument('--foo', help='foo help')
-   args = parser.parse_args()
-
-The help for this program will display ``myprogram.py`` as the program name
-(regardless of where the program was invoked from)::
-
-   $ python myprogram.py --help
-   usage: myprogram.py [-h] [--foo FOO]
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo FOO   foo help
-   $ cd ..
-   $ python subdir\myprogram.py --help
-   usage: myprogram.py [-h] [--foo FOO]
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo FOO   foo help
-
-To change this default behavior, another value can be supplied using the
-``prog=`` argument to ArgumentParser::
-
-   >>> parser = argparse.ArgumentParser(prog='myprogram')
-   >>> parser.print_help()
-   usage: myprogram [-h]
-
-   optional arguments:
-    -h, --help  show this help message and exit
-
-Note that the program name, whether determined from ``sys.argv[0]`` or from the
-``prog=`` argument, is available to help messages using the ``%(prog)s`` format
-specifier.
-
-::
-
-   >>> parser = argparse.ArgumentParser(prog='myprogram')
-   >>> parser.add_argument('--foo', help='foo of the %(prog)s program')
-   >>> parser.print_help()
-   usage: myprogram [-h] [--foo FOO]
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo FOO   foo of the myprogram program
-
-
-usage
-^^^^^
-
-By default, ArgumentParser objects calculate the usage message from the
-arguments it contains::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('--foo', nargs='?', help='foo help')
-   >>> parser.add_argument('bar', nargs='+', help='bar help')
-   >>> parser.print_help()
-   usage: PROG [-h] [--foo [FOO]] bar [bar ...]
-
-   positional arguments:
-    bar          bar help
-
-   optional arguments:
-    -h, --help   show this help message and exit
-    --foo [FOO]  foo help
-
-If the default usage message is not appropriate for your application, you can
-supply your own usage message using the ``usage=`` keyword argument to
-ArgumentParser::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
-   >>> parser.add_argument('--foo', nargs='?', help='foo help')
-   >>> parser.add_argument('bar', nargs='+', help='bar help')
-   >>> parser.print_help()
-   usage: PROG [options]
-
-   positional arguments:
-    bar          bar help
-
-   optional arguments:
-    -h, --help   show this help message and exit
-    --foo [FOO]  foo help
-
-Note you can use the ``%(prog)s`` format specifier to fill in the program name
-in your usage messages.
-
-
-The add_argument() method
--------------------------
-
-.. method:: add_argument(name or flags..., [action], [nargs], [const], [default], [type], [choices], [required], [help], [metavar], [dest])
-
-   Define how a single command line argument should be parsed. Each parameter
-   has its own more detailed description below, but in short they are:
-
-   * `name or flags`_ - Either a name or a list of option strings, e.g. ``foo``
-     or ``-f, --foo``
-
-   * action_ - The basic type of action to be taken when this argument is
-     encountered at the command-line.
-
-   * nargs_ - The number of command-line arguments that should be consumed.
-
-   * const_ - A constant value required by some action_ and nargs_ selections.
-
-   * default_ - The value produced if the argument is absent from the
-     command-line.
-
-   * type_ - The type to which the command-line arg should be converted.
-
-   * choices_ - A container of the allowable values for the argument.
-
-   * required_ - Whether or not the command-line option may be omitted
-     (optionals only).
-
-   * help_ - A brief description of what the argument does.
-
-   * metavar_ - A name for the argument in usage messages.
-
-   * dest_ - The name of the attribute to be added to the object returned by
-     :meth:`parse_args`.
-
-   The following sections describe how each of these are used.
-
-name or flags
-^^^^^^^^^^^^^
-
-The :meth:`add_argument` method needs to know whether you're expecting an
-optional argument, e.g. ``-f`` or ``--foo``, or a positional argument, e.g. a
-list of filenames. The first arguments passed to :meth:`add_argument` must
-therefore be either a series of flags, or a simple argument name. For example,
-an optional argument could be created like::
-
-   >>> parser.add_argument('-f', '--foo')
-
-while a positional argument could be created like::
-
-   >>> parser.add_argument('bar')
-
-When :meth:`parse_args` is called, optional arguments will be identified by the
-``-`` prefix, and the remaining arguments will be assumed to be positional::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-f', '--foo')
-   >>> parser.add_argument('bar')
-   >>> parser.parse_args(['BAR'])
-   Namespace(bar='BAR', foo=None)
-   >>> parser.parse_args(['BAR', '--foo', 'FOO'])
-   Namespace(bar='BAR', foo='FOO')
-   >>> parser.parse_args(['--foo', 'FOO'])
-   usage: PROG [-h] [-f FOO] bar
-   PROG: error: too few arguments
-
-action
-^^^^^^
-
-:class:`ArgumentParser` objects associate command-line args with actions. These
-actions can do just about anything with the command-line args associated with
-them, though most actions simply add an attribute to the object returned by
-:meth:`parse_args`.  When you specify a new argument using the
-:meth:`add_argument` method, you can indicate how the command-line args should
-be handled by specifying the ``action`` keyword argument. The supported actions
-are:
-
-* ``'store'`` - This just stores the argument's value. This is the default
-   action. For example::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo')
-    >>> parser.parse_args('--foo 1'.split())
-    Namespace(foo='1')
-
-* ``'store_const'`` - This stores the value specified by the const_ keyword
-   argument. Note that the const_ keyword argument defaults to ``None``, so
-   you'll almost always need to provide a value for it. The ``'store_const'``
-   action is most commonly used with optional arguments that specify some sort
-   of flag.  For example::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo', action='store_const', const=42)
-    >>> parser.parse_args('--foo'.split())
-    Namespace(foo=42)
-
-* ``'store_true'`` and ``'store_false'`` - These store the values ``True`` and
-  ``False`` respectively.  These are basically special cases of
-  ``'store_const'``.  For example::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo', action='store_true')
-    >>> parser.add_argument('--bar', action='store_false')
-    >>> parser.parse_args('--foo --bar'.split())
-    Namespace(bar=False, foo=True)
-
-* ``'append'`` - This stores a list, and appends each argument value to the
-  list.  This is useful when you want to allow an option to be specified
-  multiple times.  Example usage::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo', action='append')
-    >>> parser.parse_args('--foo 1 --foo 2'.split())
-    Namespace(foo=['1', '2'])
-
-* ``'append_const'`` - This stores a list, and appends the value specified by
-  the const_ keyword argument to the list.  Note that the const_ keyword
-  argument defaults to ``None``, so you'll almost always need to provide a
-  value for it.  The ``'append_const'`` action is typically useful when you
-  want multiple arguments to store constants to the same list, for example::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--str', dest='types', action='append_const', const=str)
-    >>> parser.add_argument('--int', dest='types', action='append_const', const=int)
-    >>> parser.parse_args('--str --int'.split())
-    Namespace(types=[<type 'str'>, <type 'int'>])
-
-* ``'version'`` - This expects a ``version=`` keyword argument in the
-  :meth:`add_argument` call, and prints version information and exits when
-  invoked.
-
-    >>> import argparse
-    >>> parser = argparse.ArgumentParser(prog='PROG')
-    >>> parser.add_argument('-v', '--version', action='version', version='%(prog)s 2.0')
-    >>> parser.parse_args(['-v'])
-    PROG 2.0
-
-You can also specify an arbitrary action by passing an object that implements
-the Action API.  The easiest way to do this is to extend ``argparse.Action``,
-supplying an appropriate ``__call__`` method.  The ``__call__`` method accepts
-four parameters:
-
-* ``parser`` - The ArgumentParser object which contains this action.
-
-* ``namespace`` - The namespace object that will be returned by
-  :meth:`parse_args`. Most actions add an attribute to this object.
-
-* ``values`` - The associated command-line args, with any type-conversions
-  applied.  (Type-conversions are specified with the type_ keyword argument to
-  :meth:`add_argument`.
-
-* ``option_string`` - The option string that was used to invoke this action.
-  The ``option_string`` argument is optional, and will be absent if the action
-  is associated with a positional argument.
-
-So for example::
-
-   >>> class FooAction(argparse.Action):
-   ...     def __call__(self, parser, namespace, values, option_string=None):
-   ...     print '%r %r %r' % (namespace, values, option_string)
-   ...     setattr(namespace, self.dest, values)
-   ...
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', action=FooAction)
-   >>> parser.add_argument('bar', action=FooAction)
-   >>> args = parser.parse_args('1 --foo 2'.split())
-   Namespace(bar=None, foo=None) '1' None
-   Namespace(bar='1', foo=None) '2' '--foo'
-   >>> args
-   Namespace(bar='1', foo='2')
-
-
-nargs
-^^^^^
-
-ArgumentParser objects usually associate a single command-line argument with a
-single action to be taken.  In the situations where you'd like to associate a
-different number of command-line arguments with a single action, you can use
-the ``nargs`` keyword argument to :meth:`add_argument`. The supported values
-are:
-
-* N (an integer). N args from the command-line will be gathered together into
-  a list.  For example::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo', nargs=2)
-    >>> parser.add_argument('bar', nargs=1)
-    >>> parser.parse_args('c --foo a b'.split())
-    Namespace(bar=['c'], foo=['a', 'b'])
-
-   Note that ``nargs=1`` produces a list of one item.  This is different from
-   the default, in which the item is produced by itself.
-
-* ``'?'``. One arg will be consumed from the command-line if possible, and
-  produced as a single item.  If no command-line arg is present, the value from
-  default_ will be produced.  Note that for optional arguments, there is an
-  additional case - the option string is present but not followed by a
-  command-line arg.  In this case the value from const_ will be produced.  Some
-  examples to illustrate this::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo', nargs='?', const='c', default='d')
-    >>> parser.add_argument('bar', nargs='?', default='d')
-    >>> parser.parse_args('XX --foo YY'.split())
-    Namespace(bar='XX', foo='YY')
-    >>> parser.parse_args('XX --foo'.split())
-    Namespace(bar='XX', foo='c')
-    >>> parser.parse_args(''.split())
-    Namespace(bar='d', foo='d')
-
-   One of the more common uses of ``nargs='?'`` is to allow optional input and
-   output files::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
-    >>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
-    >>> parser.parse_args(['input.txt', 'output.txt'])
-    Namespace(infile=<open file 'input.txt', mode 'r' at 0x...>, outfile=<open file 'output.txt', mode 'w' at 0x...>)
-    >>> parser.parse_args([])
-    Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>, outfile=<open file '<stdout>', mode 'w' at 0x...>)
-
-* ``'*'``. All command-line args present are gathered into a list. Note that
-  it generally doesn't make much sense to have more than one positional
-  argument with ``nargs='*'``, but multiple optional arguments with
-  ``nargs='*'`` is possible.  For example::
-
-    >>> parser = argparse.ArgumentParser()
-    >>> parser.add_argument('--foo', nargs='*')
-    >>> parser.add_argument('--bar', nargs='*')
-    >>> parser.add_argument('baz', nargs='*')
-    >>> parser.parse_args('a b --foo x y --bar 1 2'.split())
-    Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
-
-* ``'+'``. Just like ``'*'``, all command-line args present are gathered into a
-  list.  Additionally, an error message will be generated if there wasn't at
-  least one command-line arg present.  For example::
-
-    >>> parser = argparse.ArgumentParser(prog='PROG')
-    >>> parser.add_argument('foo', nargs='+')
-    >>> parser.parse_args('a b'.split())
-    Namespace(foo=['a', 'b'])
-    >>> parser.parse_args(''.split())
-    usage: PROG [-h] foo [foo ...]
-    PROG: error: too few arguments
-
-If the ``nargs`` keyword argument is not provided, the number of args consumed
-is determined by the action_. Generally this means a single command-line arg
-will be consumed and a single item (not a list) will be produced.
-
-
-const
-^^^^^
-
-The ``const`` argument of :meth:`add_argument` is used to hold constant values
-that are not read from the command line but are required for the various
-ArgumentParser actions.  The two most common uses of it are:
-
-* When :meth:`add_argument` is called with ``action='store_const'`` or
-  ``action='append_const'``.  These actions add the ``const`` value to one of
-  the attributes of the object returned by :meth:`parse_args`.  See the action_
-  description for examples.
-
-* When :meth:`add_argument` is called with option strings (like ``-f`` or
-  ``--foo``) and ``nargs='?'``. This creates an optional argument that can be
-  followed by zero or one command-line args.  When parsing the command-line, if
-  the option string is encountered with no command-line arg following it, the
-  value of ``const`` will be assumed instead. See the nargs_ description for
-  examples.
-
-The ``const`` keyword argument defaults to ``None``.
-
-
-default
-^^^^^^^
-
-All optional arguments and some positional arguments may be omitted at the
-command-line.  The ``default`` keyword argument of :meth:`add_argument`, whose
-value defaults to ``None``, specifies what value should be used if the
-command-line arg is not present.  For optional arguments, the ``default`` value
-is used when the option string was not present at the command line::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', default=42)
-   >>> parser.parse_args('--foo 2'.split())
-   Namespace(foo='2')
-   >>> parser.parse_args(''.split())
-   Namespace(foo=42)
-
-For positional arguments with nargs_ ``='?'`` or ``'*'``, the ``default`` value
-is used when no command-line arg was present::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('foo', nargs='?', default=42)
-   >>> parser.parse_args('a'.split())
-   Namespace(foo='a')
-   >>> parser.parse_args(''.split())
-   Namespace(foo=42)
-
-
-If you don't want to see an attribute when an option was not present at the
-command line, you can supply ``default=argparse.SUPPRESS``::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', default=argparse.SUPPRESS)
-   >>> parser.parse_args([])
-   Namespace()
-   >>> parser.parse_args(['--foo', '1'])
-   Namespace(foo='1')
-
-
-type
-^^^^
-
-By default, ArgumentParser objects read command-line args in as simple strings.
-However, quite often the command-line string should instead be interpreted as
-another type, e.g. ``float``, ``int`` or ``file``. The ``type`` keyword
-argument of :meth:`add_argument` allows any necessary type-checking and
-type-conversions to be performed.  Many common builtin types can be used
-directly as the value of the ``type`` argument::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('foo', type=int)
-   >>> parser.add_argument('bar', type=file)
-   >>> parser.parse_args('2 temp.txt'.split())
-   Namespace(bar=<open file 'temp.txt', mode 'r' at 0x...>, foo=2)
-
-To ease the use of various types of files, the argparse module provides the
-factory FileType which takes the ``mode=`` and ``bufsize=`` arguments of the
-``file`` object. For example, ``FileType('w')`` can be used to create a
-writable file::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('bar', type=argparse.FileType('w'))
-   >>> parser.parse_args(['out.txt'])
-   Namespace(bar=<open file 'out.txt', mode 'w' at 0x...>)
-
-If you need to do some special type-checking or type-conversions, you can
-provide your own types by passing to ``type=`` a callable that takes a single
-string argument and returns the type-converted value::
-
-   >>> def perfect_square(string):
-   ...     value = int(string)
-   ...     sqrt = math.sqrt(value)
-   ...     if sqrt != int(sqrt):
-   ...         msg = "%r is not a perfect square" % string
-   ...         raise argparse.ArgumentTypeError(msg)
-   ...     return value
-   ...
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('foo', type=perfect_square)
-   >>> parser.parse_args('9'.split())
-   Namespace(foo=9)
-   >>> parser.parse_args('7'.split())
-   usage: PROG [-h] foo
-   PROG: error: argument foo: '7' is not a perfect square
-
-Note that if your type-checking function is just checking for a particular set
-of values, it may be more convenient to use the choices_ keyword argument::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('foo', type=int, choices=xrange(5, 10))
-   >>> parser.parse_args('7'.split())
-   Namespace(foo=7)
-   >>> parser.parse_args('11'.split())
-   usage: PROG [-h] {5,6,7,8,9}
-   PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
-
-See the choices_ section for more details.
-
-
-choices
-^^^^^^^
-
-Some command-line args should be selected from a restricted set of values.
-ArgumentParser objects can be told about such sets of values by passing a
-container object as the ``choices`` keyword argument to :meth:`add_argument`.
-When the command-line is parsed with :meth:`parse_args`, arg values will be
-checked, and an error message will be displayed if the arg was not one of the
-acceptable values::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('foo', choices='abc')
-   >>> parser.parse_args('c'.split())
-   Namespace(foo='c')
-   >>> parser.parse_args('X'.split())
-   usage: PROG [-h] {a,b,c}
-   PROG: error: argument foo: invalid choice: 'X' (choose from 'a', 'b', 'c')
-
-Note that inclusion in the ``choices`` container is checked after any type_
-conversions have been performed, so the type of the objects in the ``choices``
-container should match the type_ specified::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('foo', type=complex, choices=[1, 1j])
-   >>> parser.parse_args('1j'.split())
-   Namespace(foo=1j)
-   >>> parser.parse_args('-- -4'.split())
-   usage: PROG [-h] {1,1j}
-   PROG: error: argument foo: invalid choice: (-4+0j) (choose from 1, 1j)
-
-Any object that supports the ``in`` operator can be passed as the ``choices``
-value, so ``dict`` objects, ``set`` objects, custom containers, etc. are all
-supported.
-
-
-required
-^^^^^^^^
-
-In general, the argparse module assumes that flags like ``-f`` and ``--bar``
-indicate *optional* arguments, which can always be omitted at the command-line.
-To change this behavior, i.e. to make an option *required*, the value ``True``
-should be specified for the ``required=`` keyword argument to
-:meth:`add_argument`::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', required=True)
-   >>> parser.parse_args(['--foo', 'BAR'])
-   Namespace(foo='BAR')
-   >>> parser.parse_args([])
-   usage: argparse.py [-h] [--foo FOO]
-   argparse.py: error: option --foo is required
-
-As the example shows, if an option is marked as ``required``, :meth:`parse_args`
-will report an error if that option is not present at the command line.
-
-**Warning:** Required options are generally considered bad form - normal users
-expect *options* to be *optional*. You should avoid the use of required options
-whenever possible.
-
-
-help
-^^^^
-
-A great command-line interface isn't worth anything if your users can't figure
-out which option does what.  So for the end-users, ``help`` is probably the
-most important argument to include in your :meth:`add_argument` calls.  The
-``help`` value should be a string containing a brief description of what the
-argument specifies.  When a user requests help (usually by using ``-h`` or
-``--help`` at the command-line), these ``help`` descriptions will be displayed
-with each argument::
-
-   >>> parser = argparse.ArgumentParser(prog='frobble')
-   >>> parser.add_argument('--foo', action='store_true',
-   ...         help='foo the bars before frobbling')
-   >>> parser.add_argument('bar', nargs='+',
-   ...         help='one of the bars to be frobbled')
-   >>> parser.parse_args('-h'.split())
-   usage: frobble [-h] [--foo] bar [bar ...]
-
-   positional arguments:
-    bar     one of the bars to be frobbled
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo   foo the bars before frobbling
-
-The ``help`` strings can include various format specifiers to avoid repetition
-of things like the program name or the argument default_.  The available
-specifiers include the program name, ``%(prog)s`` and most keyword arguments to
-:meth:`add_argument`, e.g. ``%(default)s``, ``%(type)s``, etc.::
-
-   >>> parser = argparse.ArgumentParser(prog='frobble')
-   >>> parser.add_argument('bar', nargs='?', type=int, default=42,
-   ...         help='the bar to %(prog)s (default: %(default)s)')
-   >>> parser.print_help()
-   usage: frobble [-h] [bar]
-
-   positional arguments:
-    bar     the bar to frobble (default: 42)
-
-   optional arguments:
-    -h, --help  show this help message and exit
-
-
-metavar
-^^^^^^^
-
-When ArgumentParser objects generate help messages, they need some way to refer
-to each expected argument. By default, ArgumentParser objects use the dest_
-value as the "name" of each object.  By default, for positional argument
-actions, the dest_ value is used directly, and for optional argument actions,
-the dest_ value is uppercased.  So if we have a single positional argument with
-``dest='bar'``, that argument will be referred to as ``bar``.  And if we have a
-single optional argument ``--foo`` that should be followed by a single
-command-line arg, that arg will be referred to as ``FOO``.  You can see this
-behavior in the example below::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo')
-   >>> parser.add_argument('bar')
-   >>> parser.parse_args('X --foo Y'.split())
-   Namespace(bar='X', foo='Y')
-   >>> parser.print_help()
-   usage:  [-h] [--foo FOO] bar
-
-   positional arguments:
-    bar
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo FOO
-
-If you would like to provide a different name for your argument in help
-messages, you can supply a value for the ``metavar`` keyword argument to
-:meth:`add_argument`::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', metavar='YYY')
-   >>> parser.add_argument('bar', metavar='XXX')
-   >>> parser.parse_args('X --foo Y'.split())
-   Namespace(bar='X', foo='Y')
-   >>> parser.print_help()
-   usage:  [-h] [--foo YYY] XXX
-
-   positional arguments:
-    XXX
-
-   optional arguments:
-    -h, --help  show this help message and exit
-    --foo YYY
-
-Note that ``metavar`` only changes the *displayed* name - the name of the
-attribute on the :meth:`parse_args` object is still determined by the dest_
-value.
-
-Different values of ``nargs`` may cause the metavar to be used multiple times.
-If you'd like to specify a different display name for each of the arguments,
-you can provide a tuple to ``metavar``::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-x', nargs=2)
-   >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
-   >>> parser.print_help()
-   usage: PROG [-h] [-x X X] [--foo bar baz]
-
-   optional arguments:
-    -h, --help     show this help message and exit
-    -x X X
-    --foo bar baz
-
-
-dest
-^^^^
-
-Most ArgumentParser actions add some value as an attribute of the object
-returned by :meth:`parse_args`. The name of this attribute is determined by the
-``dest`` keyword argument of :meth:`add_argument`. For positional argument
-actions, ``dest`` is normally supplied as the first argument to
-:meth:`add_argument`::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('bar')
-   >>> parser.parse_args('XXX'.split())
-   Namespace(bar='XXX')
-
-For optional argument actions, the value of ``dest`` is normally inferred from
-the option strings. ArgumentParser objects generate the value of ``dest`` by
-taking the first long option string and stripping away the initial ``'--'``
-string.  If no long option strings were supplied, ``dest`` will be derived from
-the first short option string by stripping the initial ``'-'`` character.  Any
-internal ``'-'`` characters will be converted to ``'_'`` characters to make
-sure the string is a valid attribute name. The examples below illustrate this
-behavior::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('-f', '--foo-bar', '--foo')
-   >>> parser.add_argument('-x', '-y')
-   >>> parser.parse_args('-f 1 -x 2'.split())
-   Namespace(foo_bar='1', x='2')
-   >>> parser.parse_args('--foo 1 -y 2'.split())
-   Namespace(foo_bar='1', x='2')
-
-If you would like to use a different attribute name from the one automatically
-inferred by the ArgumentParser, you can supply it with an explicit ``dest``
-parameter::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', dest='bar')
-   >>> parser.parse_args('--foo XXX'.split())
-   Namespace(bar='XXX')
-
-
-The parse_args() method
------------------------
-
-.. method:: parse_args([args], [namespace])
-
-   Convert the strings to objects and assign them as attributes of the
-   namespace. Return the populated namespace.
-
-   Previous calls to :meth:`add_argument` determine exactly what objects are
-   created and how they are assigned. See the documentation for
-   :meth:`add_argument` for details.
-
-   By default, the arg strings are taken from ``sys.argv``, and a new empty
-   ``Namespace`` object is created for the attributes.
-
-Option value syntax
-^^^^^^^^^^^^^^^^^^^
-
-The :meth:`parse_args` method supports several ways of specifying the value of
-an option (if it takes one). In the simplest case, the option and its value are
-passed as two separate arguments::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-x')
-   >>> parser.add_argument('--foo')
-   >>> parser.parse_args('-x X'.split())
-   Namespace(foo=None, x='X')
-   >>> parser.parse_args('--foo FOO'.split())
-   Namespace(foo='FOO', x=None)
-
-For long options (options with names longer than a single character), you may
-also pass the option and value as a single command line argument, using ``=``
-to separate them::
-
-   >>> parser.parse_args('--foo=FOO'.split())
-   Namespace(foo='FOO', x=None)
-
-For short options (options only one character long), you may simply concatenate
-the option and its value::
-
-   >>> parser.parse_args('-xX'.split())
-   Namespace(foo=None, x='X')
-
-You can also combine several short options together, using only a single ``-``
-prefix, as long as only the last option (or none of them) requires a value::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-x', action='store_true')
-   >>> parser.add_argument('-y', action='store_true')
-   >>> parser.add_argument('-z')
-   >>> parser.parse_args('-xyzZ'.split())
-   Namespace(x=True, y=True, z='Z')
-
-
-Invalid arguments
-^^^^^^^^^^^^^^^^^
-
-While parsing the command-line, ``parse_args`` checks for a variety of errors,
-including ambiguous options, invalid types, invalid options, wrong number of
-positional arguments, etc. When it encounters such an error, it exits and
-prints the error along with a usage message::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('--foo', type=int)
-   >>> parser.add_argument('bar', nargs='?')
-
-   >>> # invalid type
-   >>> parser.parse_args(['--foo', 'spam'])
-   usage: PROG [-h] [--foo FOO] [bar]
-   PROG: error: argument --foo: invalid int value: 'spam'
-
-   >>> # invalid option
-   >>> parser.parse_args(['--bar'])
-   usage: PROG [-h] [--foo FOO] [bar]
-   PROG: error: no such option: --bar
-
-   >>> # wrong number of arguments
-   >>> parser.parse_args(['spam', 'badger'])
-   usage: PROG [-h] [--foo FOO] [bar]
-   PROG: error: extra arguments found: badger
-
-
-Arguments containing ``"-"``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``parse_args`` method attempts to give errors whenever the user has clearly
-made a mistake, but some situations are inherently ambiguous. For example, the
-command-line arg ``'-1'`` could either be an attempt to specify an option or an
-attempt to provide a positional argument. The ``parse_args`` method is cautious
-here: positional arguments may only begin with ``'-'`` if they look like
-negative numbers and there are no options in the parser that look like negative
-numbers::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-x')
-   >>> parser.add_argument('foo', nargs='?')
-
-   >>> # no negative number options, so -1 is a positional argument
-   >>> parser.parse_args(['-x', '-1'])
-   Namespace(foo=None, x='-1')
-
-   >>> # no negative number options, so -1 and -5 are positional arguments
-   >>> parser.parse_args(['-x', '-1', '-5'])
-   Namespace(foo='-5', x='-1')
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-1', dest='one')
-   >>> parser.add_argument('foo', nargs='?')
-
-   >>> # negative number options present, so -1 is an option
-   >>> parser.parse_args(['-1', 'X'])
-   Namespace(foo=None, one='X')
-
-   >>> # negative number options present, so -2 is an option
-   >>> parser.parse_args(['-2'])
-   usage: PROG [-h] [-1 ONE] [foo]
-   PROG: error: no such option: -2
-
-   >>> # negative number options present, so both -1s are options
-   >>> parser.parse_args(['-1', '-1'])
-   usage: PROG [-h] [-1 ONE] [foo]
-   PROG: error: argument -1: expected one argument
-
-If you have positional arguments that must begin with ``'-'`` and don't look
-like negative numbers, you can insert the pseudo-argument ``'--'`` which tells
-``parse_args`` that everything after that is a positional argument::
-
-   >>> parser.parse_args(['--', '-f'])
-   Namespace(foo='-f', one=None)
-
-
-Argument abbreviations
-^^^^^^^^^^^^^^^^^^^^^^
-
-The :meth:`parse_args` method allows you to abbreviate long options if the
-abbreviation is unambiguous::
-
-   >>> parser = argparse.ArgumentParser(prog='PROG')
-   >>> parser.add_argument('-bacon')
-   >>> parser.add_argument('-badger')
-   >>> parser.parse_args('-bac MMM'.split())
-   Namespace(bacon='MMM', badger=None)
-   >>> parser.parse_args('-bad WOOD'.split())
-   Namespace(bacon=None, badger='WOOD')
-   >>> parser.parse_args('-ba BA'.split())
-   usage: PROG [-h] [-bacon BACON] [-badger BADGER]
-   PROG: error: ambiguous option: -ba could match -badger, -bacon
-
-As you can see above, you will get an error if you pick a prefix that could
-refer to more than one option.
-
-
-Beyond ``sys.argv``
-^^^^^^^^^^^^^^^^^^^
-
-Sometimes it may be useful to have an ArgumentParser parse args other than
-those of ``sys.argv``.  This can be accomplished by passing a list of strings
-to ``parse_args``.  You may have noticed that the examples in the argparse
-documentation have made heavy use of this calling style - it is much easier
-to use at the interactive prompt::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument(
-   ...     'integers', metavar='int', type=int, choices=xrange(10),
-   ...  nargs='+', help='an integer in the range 0..9')
-   >>> parser.add_argument(
-   ...     '--sum', dest='accumulate', action='store_const', const=sum,
-   ...   default=max, help='sum the integers (default: find the max)')
-   >>> parser.parse_args(['1', '2', '3', '4'])
-   Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
-   >>> parser.parse_args('1 2 3 4 --sum'.split())
-   Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
-
-
-Custom namespaces
-^^^^^^^^^^^^^^^^^
-
-It may also be useful to have an ArgumentParser assign attributes to an already
-existing object, rather than the newly-created Namespace object that is
-normally used. This can be achieved by specifying the ``namespace=`` keyword
-argument::
-
-   >>> class C(object):
-   ...     pass
-   ...
-   >>> c = C()
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo')
-   >>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
-   >>> c.foo
-   'BAR'
-
-
-Other utilities
----------------
-
-Sub-commands
-^^^^^^^^^^^^
-
-.. method:: add_subparsers()
-
-   A lot of programs split up their functionality into a number of
-   sub-commands, for example, the ``svn`` program can invoke sub-commands like
-   ``svn checkout``, ``svn update``, ``svn commit``, etc.  Splitting up
-   functionality this way can be a particularly good idea when a program
-   performs several different functions which require different kinds of
-   command-line arguments.  ArgumentParser objects support the creation of such
-   sub-commands with the :meth:`add_subparsers` method.  The
-   :meth:`add_subparsers` method is normally called with no arguments and
-   returns an special action object.  This object has a single method,
-   ``add_parser``, which takes a command name and any ArgumentParser
-   constructor arguments, and returns an ArgumentParser object that can be
-   modified as usual.
-
-   Some example usage::
-
-     >>> # create the top-level parser
-     >>> parser = argparse.ArgumentParser(prog='PROG')
-     >>> parser.add_argument('--foo', action='store_true', help='foo help')
-     >>> subparsers = parser.add_subparsers(help='sub-command help')
-     >>>
-     >>> # create the parser for the "a" command
-     >>> parser_a = subparsers.add_parser('a', help='a help')
-     >>> parser_a.add_argument('bar', type=int, help='bar help')
-     >>>
-     >>> # create the parser for the "b" command
-     >>> parser_b = subparsers.add_parser('b', help='b help')
-     >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
-     >>>
-     >>> # parse some arg lists
-     >>> parser.parse_args(['a', '12'])
-     Namespace(bar=12, foo=False)
-     >>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
-     Namespace(baz='Z', foo=True)
-
-   Note that the object returned by :meth:`parse_args` will only contain
-   attributes for the main parser and the subparser that was selected by the
-   command line (and not any other subparsers).  So in the example above, when
-   the ``"a"`` command is specified, only the ``foo`` and ``bar`` attributes
-   are present, and when the ``"b"`` command is specified, only the ``foo`` and
-   ``baz`` attributes are present.
-
-   Similarly, when a help message is requested from a subparser, only the help
-   for that particular parser will be printed. The help message will not
-   include parent parser or sibling parser messages. (You can however supply a
-   help message for each subparser command by suppling the ``help=`` argument
-   to ``add_parser`` as above.)
-
-   ::
-
-     >>> parser.parse_args(['--help'])
-     usage: PROG [-h] [--foo] {a,b} ...
-
-     positional arguments:
-       {a,b}   sub-command help
-     a     a help
-     b     b help
-
-     optional arguments:
-       -h, --help  show this help message and exit
-       --foo   foo help
-
-     >>> parser.parse_args(['a', '--help'])
-     usage: PROG a [-h] bar
-
-     positional arguments:
-       bar     bar help
-
-     optional arguments:
-       -h, --help  show this help message and exit
-
-     >>> parser.parse_args(['b', '--help'])
-     usage: PROG b [-h] [--baz {X,Y,Z}]
-
-     optional arguments:
-       -h, --help     show this help message and exit
-       --baz {X,Y,Z}  baz help
-
-   The :meth:`add_subparsers` method also supports ``title`` and
-   ``description`` keyword arguments.  When either is present, the subparser's
-   commands will appear in their own group in the help output.  For example::
-
-     >>> parser = argparse.ArgumentParser()
-     >>> subparsers = parser.add_subparsers(title='subcommands',
-     ...                                    description='valid subcommands',
-     ...                                    help='additional help')
-     >>> subparsers.add_parser('foo')
-     >>> subparsers.add_parser('bar')
-     >>> parser.parse_args(['-h'])
-     usage:  [-h] {foo,bar} ...
-
-     optional arguments:
-       -h, --help  show this help message and exit
-
-     subcommands:
-       valid subcommands
-
-       {foo,bar}   additional help
-
-
-   One particularly effective way of handling sub-commands is to combine the
-   use of the :meth:`add_subparsers` method with calls to :meth:`set_defaults`
-   so that each subparser knows which Python function it should execute.  For
-   example::
-
-     >>> # sub-command functions
-     >>> def foo(args):
-     ...     print args.x * args.y
-     ...
-     >>> def bar(args):
-     ...     print '((%s))' % args.z
-     ...
-     >>> # create the top-level parser
-     >>> parser = argparse.ArgumentParser()
-     >>> subparsers = parser.add_subparsers()
-     >>>
-     >>> # create the parser for the "foo" command
-     >>> parser_foo = subparsers.add_parser('foo')
-     >>> parser_foo.add_argument('-x', type=int, default=1)
-     >>> parser_foo.add_argument('y', type=float)
-     >>> parser_foo.set_defaults(func=foo)
-     >>>
-     >>> # create the parser for the "bar" command
-     >>> parser_bar = subparsers.add_parser('bar')
-     >>> parser_bar.add_argument('z')
-     >>> parser_bar.set_defaults(func=bar)
-     >>>
-     >>> # parse the args and call whatever function was selected
-     >>> args = parser.parse_args('foo 1 -x 2'.split())
-     >>> args.func(args)
-     2.0
-     >>>
-     >>> # parse the args and call whatever function was selected
-     >>> args = parser.parse_args('bar XYZYX'.split())
-     >>> args.func(args)
-     ((XYZYX))
-
-   This way, you can let :meth:`parse_args` do all the work for you, and then
-   just call the appropriate function after the argument parsing is complete.
-   Associating functions with actions like this is typically the easiest way
-   to handle the different actions for each of your subparsers. However, if you
-   find it necessary to check the name of the subparser that was invoked, you
-   can always provide a ``dest`` keyword argument to the :meth:`add_subparsers`
-   call::
-
-     >>> parser = argparse.ArgumentParser()
-     >>> subparsers = parser.add_subparsers(dest='subparser_name')
-     >>> subparser1 = subparsers.add_parser('1')
-     >>> subparser1.add_argument('-x')
-     >>> subparser2 = subparsers.add_parser('2')
-     >>> subparser2.add_argument('y')
-     >>> parser.parse_args(['2', 'frobble'])
-     Namespace(subparser_name='2', y='frobble')
-
-
-FileType objects
-^^^^^^^^^^^^^^^^
-
-.. class:: FileType(mode='r', bufsize=None)
-
-   The :class:`FileType` factory creates objects that can be passed to the type
-   argument of :meth:`add_argument`. Arguments that have :class:`FileType`
-   objects as their type will open command-line args as files with the
-   requested modes and buffer sizes:
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
-   >>> parser.parse_args(['--output', 'out'])
-   Namespace(output=<open file 'out', mode 'wb' at 0x...>)
-
-   FileType objects understand the pseudo-argument ``'-'`` and automatically
-   convert this into ``sys.stdin`` for readable :class:`FileType` objects and
-   ``sys.stdout`` for writable :class:`FileType` objects:
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('infile', type=argparse.FileType('r'))
-   >>> parser.parse_args(['-'])
-   Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>)
-
-
-Argument groups
-^^^^^^^^^^^^^^^
-
-.. method:: add_argument_group([title], [description])
-
-   By default, ArgumentParser objects group command-line arguments into
-   "positional arguments" and "optional arguments" when displaying help
-   messages. When there is a better conceptual grouping of arguments than this
-   default one, appropriate groups can be created using the
-   :meth:`add_argument_group` method::
-
-     >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
-     >>> group = parser.add_argument_group('group')
-     >>> group.add_argument('--foo', help='foo help')
-     >>> group.add_argument('bar', help='bar help')
-     >>> parser.print_help()
-     usage: PROG [--foo FOO] bar
-
-     group:
-       bar    bar help
-       --foo FOO  foo help
-
-   The :meth:`add_argument_group` method returns an argument group object which
-   has an :meth:`add_argument` method just like a regular ArgumentParser
-   objects. When an argument is added to the group, the parser treats it just
-   like a normal argument, but displays the argument in a separate group for
-   help messages. The :meth:`add_argument_group` method accepts ``title`` and
-   ``description`` arguments which can be used to customize this display::
-
-     >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
-     >>> group1 = parser.add_argument_group('group1', 'group1 description')
-     >>> group1.add_argument('foo', help='foo help')
-     >>> group2 = parser.add_argument_group('group2', 'group2 description')
-     >>> group2.add_argument('--bar', help='bar help')
-     >>> parser.print_help()
-     usage: PROG [--bar BAR] foo
-
-     group1:
-       group1 description
-
-       foo    foo help
-
-     group2:
-       group2 description
-
-       --bar BAR  bar help
-
-   Note that any arguments not in your user defined groups will end up back in
-   the usual "positional arguments" and "optional arguments" sections.
-
-
-Mutual exclusion
-^^^^^^^^^^^^^^^^
-
-.. method:: add_mutually_exclusive_group([required=False])
-
-   Sometimes, you need to make sure that only one of a couple different options
-   is specified on the command line. You can create groups of such mutually
-   exclusive arguments using the :meth:`add_mutually_exclusive_group` method.
-   When :func:`parse_args` is called, argparse will make sure that only one of
-   the arguments in the mutually exclusive group was present on the command
-   line::
-
-     >>> parser = argparse.ArgumentParser(prog='PROG')
-     >>> group = parser.add_mutually_exclusive_group()
-     >>> group.add_argument('--foo', action='store_true')
-     >>> group.add_argument('--bar', action='store_false')
-     >>> parser.parse_args(['--foo'])
-     Namespace(bar=True, foo=True)
-     >>> parser.parse_args(['--bar'])
-     Namespace(bar=False, foo=False)
-     >>> parser.parse_args(['--foo', '--bar'])
-     usage: PROG [-h] [--foo | --bar]
-     PROG: error: argument --bar: not allowed with argument --foo
-
-   The :meth:`add_mutually_exclusive_group` method also accepts a ``required``
-   argument, to indicate that at least one of the mutually exclusive arguments
-   is required::
-
-     >>> parser = argparse.ArgumentParser(prog='PROG')
-     >>> group = parser.add_mutually_exclusive_group(required=True)
-     >>> group.add_argument('--foo', action='store_true')
-     >>> group.add_argument('--bar', action='store_false')
-     >>> parser.parse_args([])
-     usage: PROG [-h] (--foo | --bar)
-     PROG: error: one of the arguments --foo --bar is required
-
-   Note that currently mutually exclusive argument groups do not support the
-   ``title`` and ``description`` arguments of :meth:`add_argument_group`. This
-   may change in the future however, so you are *strongly* recommended to
-   specify ``required`` as a keyword argument if you use it.
-
-
-Parser defaults
-^^^^^^^^^^^^^^^
-
-.. method:: set_defaults(**kwargs)
-
-   Most of the time, the attributes of the object returned by
-   :meth:`parse_args` will be fully determined by inspecting the command-line
-   args and the argument actions described in your :meth:`add_argument` calls.
-   However, sometimes it may be useful to add some additional attributes that
-   are determined without any inspection of the command-line.  The
-   :meth:`set_defaults` method allows you to do this::
-
-     >>> parser = argparse.ArgumentParser()
-     >>> parser.add_argument('foo', type=int)
-     >>> parser.set_defaults(bar=42, baz='badger')
-     >>> parser.parse_args(['736'])
-     Namespace(bar=42, baz='badger', foo=736)
-
-   Note that parser-level defaults always override argument-level defaults. So
-   if you set a parser-level default for a name that matches an argument, the
-   old argument default will no longer be used::
-
-     >>> parser = argparse.ArgumentParser()
-     >>> parser.add_argument('--foo', default='bar')
-     >>> parser.set_defaults(foo='spam')
-     >>> parser.parse_args([])
-     Namespace(foo='spam')
-
-   Parser-level defaults can be particularly useful when you're working with
-   multiple parsers.  See the :meth:`add_subparsers` method for an example of
-   this type.
-
-.. method:: get_default(dest)
-
-   Get the default value for a namespace attribute, as set by either
-   :meth:`add_argument` or by :meth:`set_defaults`::
-
-     >>> parser = argparse.ArgumentParser()
-     >>> parser.add_argument('--foo', default='badger')
-     >>> parser.get_default('foo')
-     'badger'
-
-
-Printing help
-^^^^^^^^^^^^^
-
-In most typical applications, :meth:`parse_args` will take care of formatting
-and printing any usage or error messages. However, should you want to format or
-print these on your own, several methods are available:
-
-.. method:: print_usage([file]):
-
-   Print a brief description of how the :class:`ArgumentParser` should be
-   invoked on the command line.  If ``file`` is not present, ``sys.stderr`` is
-   assumed.
-
-.. method:: print_help([file]):
-
-   Print a help message, including the program usage and information about the
-   arguments registered with the :class:`ArgumentParser`. If ``file`` is not
-   present, ``sys.stderr`` is assumed.
-
-There are also variants of these methods that simply return a string instead of
-printing it:
-
-.. method:: format_usage():
-
-   Return a string containing a brief description of how the
-   :class:`ArgumentParser` should be invoked on the command line.
-
-.. method:: format_help():
-
-   Return a string containing a help message, including the program usage and
-   information about the arguments registered with the :class:`ArgumentParser`.
-
-
-
-Partial parsing
-^^^^^^^^^^^^^^^
-
-.. method:: parse_known_args([args], [namespace])
-
-Sometimes a script may only parse a few of the command line arguments, passing
-the remaining arguments on to another script or program. In these cases, the
-:meth:`parse_known_args` method can be useful. It works much like
-:meth:`parse_args` except that it does not produce an error when extra
-arguments are present. Instead, it returns a two item tuple containing the
-populated namespace and the list of remaining argument strings.
-
-::
-
-   >>> parser = argparse.ArgumentParser()
-   >>> parser.add_argument('--foo', action='store_true')
-   >>> parser.add_argument('bar')
-   >>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
-   (Namespace(bar='BAR', foo=True), ['--badger', 'spam'])
-
-
-Customizing file parsing
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. method:: convert_arg_line_to_args(arg_line)
-
-   Arguments that are read from a file (see the ``fromfile_prefix_chars``
-   keyword argument to the :class:`ArgumentParser` constructor) are read one
-   argument per line.  If you need fancier parsing, then you can subclass the
-   :class:`ArgumentParser` and override the :meth:`convert_arg_line_to_args`
-   method.
-
-   This method takes a single argument ``arg_line`` which is a string read from
-   the argument file.  It returns a list of arguments parsed from this string.
-   The method is called once per line read from the argument file, in order.
-
-   A useful override of this method is one that treats each space-separated
-   word as an argument::
-
-    def convert_arg_line_to_args(self, arg_line):
-        for arg in arg_line.split():
-            if not arg.strip():
-                continue
-            yield arg
-
-
-Upgrading optparse code
------------------------
-
-Originally, the argparse module had attempted to maintain compatibility with
- optparse. However, optparse was difficult to extend transparently,
- particularly with the changes required to support the new ``nargs=``
- specifiers and better usage messges. When most everything in optparse had
- either been copy-pasted over or monkey-patched, it no longer seemed practical
- to try to maintain the backwards compatibility.
-
-A partial upgrade path from optparse to argparse:
-
-* Replace all ``add_option()`` calls with :meth:`add_argument` calls.
-
-* Replace ``options, args = parser.parse_args()`` with
-  ``args = parser.parse_args()`` and add additional :meth:`add_argument` calls
-  for the positional arguments.
-
-* Replace callback actions and the ``callback_*`` keyword arguments with
-  ``type`` or ``action`` arguments.
-
-* Replace string names for ``type`` keyword arguments with the corresponding
-  type objects (e.g. int, float, complex, etc).
-
-* Replace ``Values`` with ``Namespace`` and ``OptionError/OptionValueError``
-  with ``ArgumentError``.
-
-* Replace strings with implicit arguments such as ``%default`` or ``%prog``
-  with the standard python syntax to use dictionaries to format strings, that
-  is, ``%(default)s`` and ``%(prog)s``.
+:mod:`argparse` -- Parser for command line options, arguments and sub-commands
+==============================================================================
+
+.. module:: argparse
+   :synopsis: Command-line option and argument parsing library.
+.. moduleauthor:: Steven Bethard <steven.bethard@gmail.com>
+.. versionadded:: 2.7
+.. sectionauthor:: Steven Bethard <steven.bethard@gmail.com>
+
+
+The :mod:`argparse` module makes it easy to write user friendly command line
+interfaces. You define what arguments your program requires, and
+:mod:`argparse` will figure out how to parse those out of ``sys.argv``. The
+:mod:`argparse` module also automatically generates help and usage messages
+based on the arguments you have defined, and issues errors when users give your
+program invalid arguments.
+
+Example
+-------
+
+As an example, the following code is a Python program that takes a list of
+integers and produces either the sum or the max::
+
+   import argparse
+
+   parser = argparse.ArgumentParser(description='Process some integers.')
+   parser.add_argument('integers', metavar='N', type=int, nargs='+',
+                      help='an integer for the accumulator')
+   parser.add_argument('--sum', dest='accumulate', action='store_const',
+                      const=sum, default=max,
+                      help='sum the integers (default: find the max)')
+
+   args = parser.parse_args()
+   print args.accumulate(args.integers)
+
+Assuming the Python code above is saved into a file called ``prog.py``, it can
+be run at the command line and provides useful help messages::
+
+   $ prog.py -h
+   usage: prog.py [-h] [--sum] N [N ...]
+
+   Process some integers.
+
+   positional arguments:
+    N           an integer for the accumulator
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --sum       sum the integers (default: find the max)
+
+When run with the appropriate arguments, it prints either the sum or the max of
+the command-line integers::
+
+   $ prog.py 1 2 3 4
+   4
+
+   $ prog.py 1 2 3 4 --sum
+   10
+
+If invalid arguments are passed in, it will issue an error::
+
+   $ prog.py a b c
+   usage: prog.py [-h] [--sum] N [N ...]
+   prog.py: error: argument N: invalid int value: 'a'
+
+The following sections walk you through this example.
+
+Creating a parser
+^^^^^^^^^^^^^^^^^
+
+Pretty much every script that uses the :mod:`argparse` module will start out by
+creating an :class:`ArgumentParser` object::
+
+   >>> parser = argparse.ArgumentParser(description='Process some integers.')
+
+The :class:`ArgumentParser` object will hold all the information necessary to
+parse the command line into a more manageable form for your program.
+
+
+Adding arguments
+^^^^^^^^^^^^^^^^
+
+Once you've created an :class:`ArgumentParser`, you'll want to fill it with
+information about your program arguments. You typically do this by making calls
+to the :meth:`add_argument` method.  Generally, these calls tell the
+:class:`ArgumentParser` how to take the strings on the command line and turn
+them into objects for you. This information is stored and used when
+:meth:`parse_args` is called. For example, if we add some arguments like this::
+
+   >>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
+   ...                     help='an integer for the accumulator')
+   >>> parser.add_argument('--sum', dest='accumulate', action='store_const',
+   ...                     const=sum, default=max,
+   ...                     help='sum the integers (default: find the max)')
+
+when we later call :meth:`parse_args`, we can expect it to return an object
+with two attributes, ``integers`` and ``accumulate``.  The ``integers``
+attribute will be a list of one or more ints, and the ``accumulate`` attribute
+will be either the ``sum`` function, if ``--sum`` was specified at the command
+line, or the ``max`` function if it was not.
+
+Parsing arguments
+^^^^^^^^^^^^^^^^^
+
+Once an :class:`ArgumentParser` has been initialized with appropriate calls to
+:meth:`add_argument`, it can be instructed to parse the command-line args by
+calling the :meth:`parse_args` method.  This will inspect the command-line,
+convert each arg to the appropriate type and then invoke the appropriate
+action.  In most cases, this means a simple namespace object will be built up
+from attributes parsed out of the command-line::
+
+   >>> parser.parse_args(['--sum', '7', '-1', '42'])
+   Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])
+
+In a script, :meth:`parse_args` will typically be called with no arguments, and
+the :class:`ArgumentParser` will automatically determine the command-line args
+from ``sys.argv``. That's pretty much it. You're now ready to go write some
+command line interfaces!
+
+
+ArgumentParser objects
+----------------------
+
+.. class:: ArgumentParser([description], [epilog], [prog], [usage], [add_help], [argument_default], [parents], [prefix_chars], [conflict_handler], [formatter_class])
+
+   Create a new :class:`ArgumentParser` object. Each parameter has its own more
+   detailed description below, but in short they are:
+
+   * description_ - Text to display before the argument help.
+
+   * epilog_ - Text to display after the argument help.
+
+   * add_help_ - Add a -h/--help option to the parser. (default: True)
+
+   * argument_default_ - Set the global default value for arguments.
+     (default: None)
+
+   * parents_ - A list of :class:ArgumentParser objects whose arguments should
+     also be included.
+
+   * prefix_chars_ - The set of characters that prefix optional arguments.
+     (default: '-')
+
+   * fromfile_prefix_chars_ - The set of characters that prefix files from
+     which additional arguments should be read. (default: None)
+
+   * formatter_class_ - A class for customizing the help output.
+
+   * conflict_handler_ - Usually unnecessary, defines strategy for resolving
+     conflicting optionals.
+
+   * prog_ - Usually unnecessary, the name of the program
+     (default: ``sys.argv[0]``)
+
+   * usage_ - Usually unnecessary, the string describing the program usage
+     (default: generated)
+
+   The following sections describe how each of these are used.
+
+
+description
+^^^^^^^^^^^
+
+Most calls to the ArgumentParser constructor will use the ``description=``
+keyword argument. This argument gives a brief description of what the program
+does and how it works. In help messages, the description is displayed between
+the command-line usage string and the help messages for the various arguments::
+
+   >>> parser = argparse.ArgumentParser(description='A foo that bars')
+   >>> parser.print_help()
+   usage: argparse.py [-h]
+
+   A foo that bars
+
+   optional arguments:
+    -h, --help  show this help message and exit
+
+By default, the description will be line-wrapped so that it fits within the
+given space. To change this behavior, see the formatter_class_ argument.
+
+
+epilog
+^^^^^^
+
+Some programs like to display additional description of the program after the
+description of the arguments. Such text can be specified using the ``epilog=``
+argument to ArgumentParser::
+
+   >>> parser = argparse.ArgumentParser(
+   ...     description='A foo that bars',
+   ...     epilog="And that's how you'd foo a bar")
+   >>> parser.print_help()
+   usage: argparse.py [-h]
+
+   A foo that bars
+
+   optional arguments:
+    -h, --help  show this help message and exit
+
+   And that's how you'd foo a bar
+
+As with the description_ argument, the ``epilog=`` text is by default
+line-wrapped, but this behavior can be adjusted with the formatter_class_
+argument to ArgumentParser.
+
+
+add_help
+^^^^^^^^
+
+By default, ArgumentParser objects add a ``-h/--help`` option which simply
+displays the parser's help message. For example, consider a file named
+``myprogram.py`` containing the following code::
+
+   import argparse
+   parser = argparse.ArgumentParser()
+   parser.add_argument('--foo', help='foo help')
+   args = parser.parse_args()
+
+If ``-h`` or ``--help`` is supplied is at the command-line, the ArgumentParser
+help will be printed::
+
+   $ python myprogram.py --help
+   usage: myprogram.py [-h] [--foo FOO]
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo FOO   foo help
+
+Occasionally, it may be useful to disable the addition of this help option.
+This can be achieved by passing ``False`` as the ``add_help=`` argument to
+ArgumentParser::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
+   >>> parser.add_argument('--foo', help='foo help')
+   >>> parser.print_help()
+   usage: PROG [--foo FOO]
+
+   optional arguments:
+    --foo FOO  foo help
+
+
+prefix_chars
+^^^^^^^^^^^^
+
+Most command-line options will use ``'-'`` as the prefix, e.g. ``-f/--foo``.
+Parsers that need to support additional prefix characters, e.g. for options
+like ``+f`` or ``/foo``, may specify them using the ``prefix_chars=`` argument
+to the ArgumentParser constructor::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
+   >>> parser.add_argument('+f')
+   >>> parser.add_argument('++bar')
+   >>> parser.parse_args('+f X ++bar Y'.split())
+   Namespace(bar='Y', f='X')
+
+The ``prefix_chars=`` argument defaults to ``'-'``. Supplying a set of
+characters that does not include ``'-'`` will cause ``-f/--foo`` options to be
+disallowed.
+
+
+fromfile_prefix_chars
+^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes, e.g. for particularly long argument lists, it may make sense to
+keep the list of arguments in a file rather than typing it out at the command
+line. If the ``fromfile_prefix_chars=`` argument is given to the ArgumentParser
+constructor, then arguments that start with any of the specified characters
+will be treated as files, and will be replaced by the arguments they contain.
+For example::
+
+   >>> open('args.txt', 'w').write('-f\nbar')
+   >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
+   >>> parser.add_argument('-f')
+   >>> parser.parse_args(['-f', 'foo', '@args.txt'])
+   Namespace(f='bar')
+
+Arguments read from a file must by default be one per line (but see also
+:meth:`convert_arg_line_to_args`) and are treated as if they were in the same
+place as the original file referencing argument on the command line. So in the
+example above, the expression ``['-f', 'foo', '@args.txt']`` is considered
+equivalent to the expression ``['-f', 'foo', '-f', 'bar']``.
+
+The ``fromfile_prefix_chars=`` argument defaults to ``None``, meaning that
+arguments will never be treated as file references.
+
+argument_default
+^^^^^^^^^^^^^^^^
+
+Generally, argument defaults are specified either by passing a default to
+:meth:`add_argument` or by calling the :meth:`set_defaults` methods with a
+specific set of name-value pairs. Sometimes however, it may be useful to
+specify a single parser-wide default for arguments. This can be accomplished by
+passing the ``argument_default=`` keyword argument to ArgumentParser. For
+example, to globally suppress attribute creation on :meth:`parse_args` calls,
+we supply ``argument_default=SUPPRESS``::
+
+   >>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
+   >>> parser.add_argument('--foo')
+   >>> parser.add_argument('bar', nargs='?')
+   >>> parser.parse_args(['--foo', '1', 'BAR'])
+   Namespace(bar='BAR', foo='1')
+   >>> parser.parse_args([])
+   Namespace()
+
+
+parents
+^^^^^^^
+
+Sometimes, several parsers share a common set of arguments. Rather than
+repeating the definitions of these arguments, you can define a single parser
+with all the shared arguments and then use the ``parents=`` argument to
+ArgumentParser to have these "inherited". The ``parents=`` argument takes a
+list of ArgumentParser objects, collects all the positional and optional
+actions from them, and adds these actions to the ArgumentParser object being
+constructed::
+
+   >>> parent_parser = argparse.ArgumentParser(add_help=False)
+   >>> parent_parser.add_argument('--parent', type=int)
+
+   >>> foo_parser = argparse.ArgumentParser(parents=[parent_parser])
+   >>> foo_parser.add_argument('foo')
+   >>> foo_parser.parse_args(['--parent', '2', 'XXX'])
+   Namespace(foo='XXX', parent=2)
+
+   >>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
+   >>> bar_parser.add_argument('--bar')
+   >>> bar_parser.parse_args(['--bar', 'YYY'])
+   Namespace(bar='YYY', parent=None)
+
+Note that most parent parsers will specify ``add_help=False``. Otherwise, the
+ArgumentParser will see two ``-h/--help`` options (one in the parent and one in
+the child) and raise an error.
+
+
+formatter_class
+^^^^^^^^^^^^^^^
+
+ArgumentParser objects allow the help formatting to be customized by specifying
+an alternate formatting class. Currently, there are three such classes:
+``argparse.RawDescriptionHelpFormatter``, ``argparse.RawTextHelpFormatter`` and
+``argparse.ArgumentDefaultsHelpFormatter``. The first two allow more control
+over how textual descriptions are displayed, while the last automatically adds
+information about argument default values.
+
+By default, ArgumentParser objects line-wrap the description_ and epilog_ texts
+in command-line help messages::
+
+   >>> parser = argparse.ArgumentParser(
+   ...     prog='PROG',
+   ...     description='''this description
+   ...         was indented weird
+   ...             but that is okay''',
+   ...     epilog='''
+   ...             likewise for this epilog whose whitespace will
+   ...         be cleaned up and whose words will be wrapped
+   ...         across a couple lines''')
+   >>> parser.print_help()
+   usage: PROG [-h]
+
+   this description was indented weird but that is okay
+
+   optional arguments:
+    -h, --help  show this help message and exit
+
+   likewise for this epilog whose whitespace will be cleaned up and whose words
+   will be wrapped across a couple lines
+
+When you have description_ and epilog_ that is already correctly formatted and
+should not be line-wrapped, you can indicate this by passing
+``argparse.RawDescriptionHelpFormatter`` as the ``formatter_class=`` argument
+to ArgumentParser::
+
+   >>> parser = argparse.ArgumentParser(
+   ...     prog='PROG',
+   ...     formatter_class=argparse.RawDescriptionHelpFormatter,
+   ...     description=textwrap.dedent('''\
+   ...         Please do not mess up this text!
+   ...         --------------------------------
+   ...             I have indented it
+   ...             exactly the way
+   ...             I want it
+   ...         '''))
+   >>> parser.print_help()
+   usage: PROG [-h]
+
+   Please do not mess up this text!
+   --------------------------------
+      I have indented it
+      exactly the way
+      I want it
+
+   optional arguments:
+    -h, --help  show this help message and exit
+
+If you want to maintain whitespace for all sorts of help text (including
+argument descriptions), you can use ``argparse.RawTextHelpFormatter``.
+
+The other formatter class available,
+``argparse.ArgumentDefaultsHelpFormatter``, will add information about the
+default value of each of the arguments::
+
+   >>> parser = argparse.ArgumentParser(
+   ...     prog='PROG',
+   ...     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+   >>> parser.add_argument('--foo', type=int, default=42, help='FOO!')
+   >>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
+   >>> parser.print_help()
+   usage: PROG [-h] [--foo FOO] [bar [bar ...]]
+
+   positional arguments:
+    bar         BAR! (default: [1, 2, 3])
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo FOO   FOO! (default: 42)
+
+
+conflict_handler
+^^^^^^^^^^^^^^^^
+
+ArgumentParser objects do not allow two actions with the same option string.
+By default, ArgumentParser objects will raise an exception if you try to create
+an argument with an option string that is already in use::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-f', '--foo', help='old foo help')
+   >>> parser.add_argument('--foo', help='new foo help')
+   Traceback (most recent call last):
+    ..
+   ArgumentError: argument --foo: conflicting option string(s): --foo
+
+Sometimes (e.g. when using parents_) it may be useful to simply override any
+older arguments with the same option string. To get this behavior, the value
+``'resolve'`` can be supplied to the ``conflict_handler=`` argument of
+ArgumentParser::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
+   >>> parser.add_argument('-f', '--foo', help='old foo help')
+   >>> parser.add_argument('--foo', help='new foo help')
+   >>> parser.print_help()
+   usage: PROG [-h] [-f FOO] [--foo FOO]
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    -f FOO      old foo help
+    --foo FOO   new foo help
+
+Note that ArgumentParser objects only remove an action if all of its option
+strings are overridden. So, in the example above, the old ``-f/--foo`` action
+is retained as the ``-f`` action, because only the ``--foo`` option string was
+overridden.
+
+
+prog
+^^^^
+
+By default, ArgumentParser objects use ``sys.argv[0]`` to determine how to
+display the name of the program in help messages. This default is almost always
+what you want because it will make the help messages match what your users have
+typed at the command line. For example, consider a file named ``myprogram.py``
+with the following code::
+
+   import argparse
+   parser = argparse.ArgumentParser()
+   parser.add_argument('--foo', help='foo help')
+   args = parser.parse_args()
+
+The help for this program will display ``myprogram.py`` as the program name
+(regardless of where the program was invoked from)::
+
+   $ python myprogram.py --help
+   usage: myprogram.py [-h] [--foo FOO]
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo FOO   foo help
+   $ cd ..
+   $ python subdir\myprogram.py --help
+   usage: myprogram.py [-h] [--foo FOO]
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo FOO   foo help
+
+To change this default behavior, another value can be supplied using the
+``prog=`` argument to ArgumentParser::
+
+   >>> parser = argparse.ArgumentParser(prog='myprogram')
+   >>> parser.print_help()
+   usage: myprogram [-h]
+
+   optional arguments:
+    -h, --help  show this help message and exit
+
+Note that the program name, whether determined from ``sys.argv[0]`` or from the
+``prog=`` argument, is available to help messages using the ``%(prog)s`` format
+specifier.
+
+::
+
+   >>> parser = argparse.ArgumentParser(prog='myprogram')
+   >>> parser.add_argument('--foo', help='foo of the %(prog)s program')
+   >>> parser.print_help()
+   usage: myprogram [-h] [--foo FOO]
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo FOO   foo of the myprogram program
+
+
+usage
+^^^^^
+
+By default, ArgumentParser objects calculate the usage message from the
+arguments it contains::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('--foo', nargs='?', help='foo help')
+   >>> parser.add_argument('bar', nargs='+', help='bar help')
+   >>> parser.print_help()
+   usage: PROG [-h] [--foo [FOO]] bar [bar ...]
+
+   positional arguments:
+    bar          bar help
+
+   optional arguments:
+    -h, --help   show this help message and exit
+    --foo [FOO]  foo help
+
+If the default usage message is not appropriate for your application, you can
+supply your own usage message using the ``usage=`` keyword argument to
+ArgumentParser::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
+   >>> parser.add_argument('--foo', nargs='?', help='foo help')
+   >>> parser.add_argument('bar', nargs='+', help='bar help')
+   >>> parser.print_help()
+   usage: PROG [options]
+
+   positional arguments:
+    bar          bar help
+
+   optional arguments:
+    -h, --help   show this help message and exit
+    --foo [FOO]  foo help
+
+Note you can use the ``%(prog)s`` format specifier to fill in the program name
+in your usage messages.
+
+
+The add_argument() method
+-------------------------
+
+.. method:: add_argument(name or flags..., [action], [nargs], [const], [default], [type], [choices], [required], [help], [metavar], [dest])
+
+   Define how a single command line argument should be parsed. Each parameter
+   has its own more detailed description below, but in short they are:
+
+   * `name or flags`_ - Either a name or a list of option strings, e.g. ``foo``
+     or ``-f, --foo``
+
+   * action_ - The basic type of action to be taken when this argument is
+     encountered at the command-line.
+
+   * nargs_ - The number of command-line arguments that should be consumed.
+
+   * const_ - A constant value required by some action_ and nargs_ selections.
+
+   * default_ - The value produced if the argument is absent from the
+     command-line.
+
+   * type_ - The type to which the command-line arg should be converted.
+
+   * choices_ - A container of the allowable values for the argument.
+
+   * required_ - Whether or not the command-line option may be omitted
+     (optionals only).
+
+   * help_ - A brief description of what the argument does.
+
+   * metavar_ - A name for the argument in usage messages.
+
+   * dest_ - The name of the attribute to be added to the object returned by
+     :meth:`parse_args`.
+
+   The following sections describe how each of these are used.
+
+name or flags
+^^^^^^^^^^^^^
+
+The :meth:`add_argument` method needs to know whether you're expecting an
+optional argument, e.g. ``-f`` or ``--foo``, or a positional argument, e.g. a
+list of filenames. The first arguments passed to :meth:`add_argument` must
+therefore be either a series of flags, or a simple argument name. For example,
+an optional argument could be created like::
+
+   >>> parser.add_argument('-f', '--foo')
+
+while a positional argument could be created like::
+
+   >>> parser.add_argument('bar')
+
+When :meth:`parse_args` is called, optional arguments will be identified by the
+``-`` prefix, and the remaining arguments will be assumed to be positional::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-f', '--foo')
+   >>> parser.add_argument('bar')
+   >>> parser.parse_args(['BAR'])
+   Namespace(bar='BAR', foo=None)
+   >>> parser.parse_args(['BAR', '--foo', 'FOO'])
+   Namespace(bar='BAR', foo='FOO')
+   >>> parser.parse_args(['--foo', 'FOO'])
+   usage: PROG [-h] [-f FOO] bar
+   PROG: error: too few arguments
+
+action
+^^^^^^
+
+:class:`ArgumentParser` objects associate command-line args with actions. These
+actions can do just about anything with the command-line args associated with
+them, though most actions simply add an attribute to the object returned by
+:meth:`parse_args`.  When you specify a new argument using the
+:meth:`add_argument` method, you can indicate how the command-line args should
+be handled by specifying the ``action`` keyword argument. The supported actions
+are:
+
+* ``'store'`` - This just stores the argument's value. This is the default
+   action. For example::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo')
+    >>> parser.parse_args('--foo 1'.split())
+    Namespace(foo='1')
+
+* ``'store_const'`` - This stores the value specified by the const_ keyword
+   argument. Note that the const_ keyword argument defaults to ``None``, so
+   you'll almost always need to provide a value for it. The ``'store_const'``
+   action is most commonly used with optional arguments that specify some sort
+   of flag.  For example::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo', action='store_const', const=42)
+    >>> parser.parse_args('--foo'.split())
+    Namespace(foo=42)
+
+* ``'store_true'`` and ``'store_false'`` - These store the values ``True`` and
+  ``False`` respectively.  These are basically special cases of
+  ``'store_const'``.  For example::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo', action='store_true')
+    >>> parser.add_argument('--bar', action='store_false')
+    >>> parser.parse_args('--foo --bar'.split())
+    Namespace(bar=False, foo=True)
+
+* ``'append'`` - This stores a list, and appends each argument value to the
+  list.  This is useful when you want to allow an option to be specified
+  multiple times.  Example usage::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo', action='append')
+    >>> parser.parse_args('--foo 1 --foo 2'.split())
+    Namespace(foo=['1', '2'])
+
+* ``'append_const'`` - This stores a list, and appends the value specified by
+  the const_ keyword argument to the list.  Note that the const_ keyword
+  argument defaults to ``None``, so you'll almost always need to provide a
+  value for it.  The ``'append_const'`` action is typically useful when you
+  want multiple arguments to store constants to the same list, for example::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--str', dest='types', action='append_const', const=str)
+    >>> parser.add_argument('--int', dest='types', action='append_const', const=int)
+    >>> parser.parse_args('--str --int'.split())
+    Namespace(types=[<type 'str'>, <type 'int'>])
+
+* ``'version'`` - This expects a ``version=`` keyword argument in the
+  :meth:`add_argument` call, and prints version information and exits when
+  invoked.
+
+    >>> import argparse
+    >>> parser = argparse.ArgumentParser(prog='PROG')
+    >>> parser.add_argument('-v', '--version', action='version', version='%(prog)s 2.0')
+    >>> parser.parse_args(['-v'])
+    PROG 2.0
+
+You can also specify an arbitrary action by passing an object that implements
+the Action API.  The easiest way to do this is to extend ``argparse.Action``,
+supplying an appropriate ``__call__`` method.  The ``__call__`` method accepts
+four parameters:
+
+* ``parser`` - The ArgumentParser object which contains this action.
+
+* ``namespace`` - The namespace object that will be returned by
+  :meth:`parse_args`. Most actions add an attribute to this object.
+
+* ``values`` - The associated command-line args, with any type-conversions
+  applied.  (Type-conversions are specified with the type_ keyword argument to
+  :meth:`add_argument`.
+
+* ``option_string`` - The option string that was used to invoke this action.
+  The ``option_string`` argument is optional, and will be absent if the action
+  is associated with a positional argument.
+
+So for example::
+
+   >>> class FooAction(argparse.Action):
+   ...     def __call__(self, parser, namespace, values, option_string=None):
+   ...     print '%r %r %r' % (namespace, values, option_string)
+   ...     setattr(namespace, self.dest, values)
+   ...
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', action=FooAction)
+   >>> parser.add_argument('bar', action=FooAction)
+   >>> args = parser.parse_args('1 --foo 2'.split())
+   Namespace(bar=None, foo=None) '1' None
+   Namespace(bar='1', foo=None) '2' '--foo'
+   >>> args
+   Namespace(bar='1', foo='2')
+
+
+nargs
+^^^^^
+
+ArgumentParser objects usually associate a single command-line argument with a
+single action to be taken.  In the situations where you'd like to associate a
+different number of command-line arguments with a single action, you can use
+the ``nargs`` keyword argument to :meth:`add_argument`. The supported values
+are:
+
+* N (an integer). N args from the command-line will be gathered together into
+  a list.  For example::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo', nargs=2)
+    >>> parser.add_argument('bar', nargs=1)
+    >>> parser.parse_args('c --foo a b'.split())
+    Namespace(bar=['c'], foo=['a', 'b'])
+
+   Note that ``nargs=1`` produces a list of one item.  This is different from
+   the default, in which the item is produced by itself.
+
+* ``'?'``. One arg will be consumed from the command-line if possible, and
+  produced as a single item.  If no command-line arg is present, the value from
+  default_ will be produced.  Note that for optional arguments, there is an
+  additional case - the option string is present but not followed by a
+  command-line arg.  In this case the value from const_ will be produced.  Some
+  examples to illustrate this::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo', nargs='?', const='c', default='d')
+    >>> parser.add_argument('bar', nargs='?', default='d')
+    >>> parser.parse_args('XX --foo YY'.split())
+    Namespace(bar='XX', foo='YY')
+    >>> parser.parse_args('XX --foo'.split())
+    Namespace(bar='XX', foo='c')
+    >>> parser.parse_args(''.split())
+    Namespace(bar='d', foo='d')
+
+   One of the more common uses of ``nargs='?'`` is to allow optional input and
+   output files::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
+    >>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
+    >>> parser.parse_args(['input.txt', 'output.txt'])
+    Namespace(infile=<open file 'input.txt', mode 'r' at 0x...>, outfile=<open file 'output.txt', mode 'w' at 0x...>)
+    >>> parser.parse_args([])
+    Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>, outfile=<open file '<stdout>', mode 'w' at 0x...>)
+
+* ``'*'``. All command-line args present are gathered into a list. Note that
+  it generally doesn't make much sense to have more than one positional
+  argument with ``nargs='*'``, but multiple optional arguments with
+  ``nargs='*'`` is possible.  For example::
+
+    >>> parser = argparse.ArgumentParser()
+    >>> parser.add_argument('--foo', nargs='*')
+    >>> parser.add_argument('--bar', nargs='*')
+    >>> parser.add_argument('baz', nargs='*')
+    >>> parser.parse_args('a b --foo x y --bar 1 2'.split())
+    Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
+
+* ``'+'``. Just like ``'*'``, all command-line args present are gathered into a
+  list.  Additionally, an error message will be generated if there wasn't at
+  least one command-line arg present.  For example::
+
+    >>> parser = argparse.ArgumentParser(prog='PROG')
+    >>> parser.add_argument('foo', nargs='+')
+    >>> parser.parse_args('a b'.split())
+    Namespace(foo=['a', 'b'])
+    >>> parser.parse_args(''.split())
+    usage: PROG [-h] foo [foo ...]
+    PROG: error: too few arguments
+
+If the ``nargs`` keyword argument is not provided, the number of args consumed
+is determined by the action_. Generally this means a single command-line arg
+will be consumed and a single item (not a list) will be produced.
+
+
+const
+^^^^^
+
+The ``const`` argument of :meth:`add_argument` is used to hold constant values
+that are not read from the command line but are required for the various
+ArgumentParser actions.  The two most common uses of it are:
+
+* When :meth:`add_argument` is called with ``action='store_const'`` or
+  ``action='append_const'``.  These actions add the ``const`` value to one of
+  the attributes of the object returned by :meth:`parse_args`.  See the action_
+  description for examples.
+
+* When :meth:`add_argument` is called with option strings (like ``-f`` or
+  ``--foo``) and ``nargs='?'``. This creates an optional argument that can be
+  followed by zero or one command-line args.  When parsing the command-line, if
+  the option string is encountered with no command-line arg following it, the
+  value of ``const`` will be assumed instead. See the nargs_ description for
+  examples.
+
+The ``const`` keyword argument defaults to ``None``.
+
+
+default
+^^^^^^^
+
+All optional arguments and some positional arguments may be omitted at the
+command-line.  The ``default`` keyword argument of :meth:`add_argument`, whose
+value defaults to ``None``, specifies what value should be used if the
+command-line arg is not present.  For optional arguments, the ``default`` value
+is used when the option string was not present at the command line::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', default=42)
+   >>> parser.parse_args('--foo 2'.split())
+   Namespace(foo='2')
+   >>> parser.parse_args(''.split())
+   Namespace(foo=42)
+
+For positional arguments with nargs_ ``='?'`` or ``'*'``, the ``default`` value
+is used when no command-line arg was present::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('foo', nargs='?', default=42)
+   >>> parser.parse_args('a'.split())
+   Namespace(foo='a')
+   >>> parser.parse_args(''.split())
+   Namespace(foo=42)
+
+
+If you don't want to see an attribute when an option was not present at the
+command line, you can supply ``default=argparse.SUPPRESS``::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', default=argparse.SUPPRESS)
+   >>> parser.parse_args([])
+   Namespace()
+   >>> parser.parse_args(['--foo', '1'])
+   Namespace(foo='1')
+
+
+type
+^^^^
+
+By default, ArgumentParser objects read command-line args in as simple strings.
+However, quite often the command-line string should instead be interpreted as
+another type, e.g. ``float``, ``int`` or ``file``. The ``type`` keyword
+argument of :meth:`add_argument` allows any necessary type-checking and
+type-conversions to be performed.  Many common builtin types can be used
+directly as the value of the ``type`` argument::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('foo', type=int)
+   >>> parser.add_argument('bar', type=file)
+   >>> parser.parse_args('2 temp.txt'.split())
+   Namespace(bar=<open file 'temp.txt', mode 'r' at 0x...>, foo=2)
+
+To ease the use of various types of files, the argparse module provides the
+factory FileType which takes the ``mode=`` and ``bufsize=`` arguments of the
+``file`` object. For example, ``FileType('w')`` can be used to create a
+writable file::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('bar', type=argparse.FileType('w'))
+   >>> parser.parse_args(['out.txt'])
+   Namespace(bar=<open file 'out.txt', mode 'w' at 0x...>)
+
+If you need to do some special type-checking or type-conversions, you can
+provide your own types by passing to ``type=`` a callable that takes a single
+string argument and returns the type-converted value::
+
+   >>> def perfect_square(string):
+   ...     value = int(string)
+   ...     sqrt = math.sqrt(value)
+   ...     if sqrt != int(sqrt):
+   ...         msg = "%r is not a perfect square" % string
+   ...         raise argparse.ArgumentTypeError(msg)
+   ...     return value
+   ...
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('foo', type=perfect_square)
+   >>> parser.parse_args('9'.split())
+   Namespace(foo=9)
+   >>> parser.parse_args('7'.split())
+   usage: PROG [-h] foo
+   PROG: error: argument foo: '7' is not a perfect square
+
+Note that if your type-checking function is just checking for a particular set
+of values, it may be more convenient to use the choices_ keyword argument::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('foo', type=int, choices=xrange(5, 10))
+   >>> parser.parse_args('7'.split())
+   Namespace(foo=7)
+   >>> parser.parse_args('11'.split())
+   usage: PROG [-h] {5,6,7,8,9}
+   PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)
+
+See the choices_ section for more details.
+
+
+choices
+^^^^^^^
+
+Some command-line args should be selected from a restricted set of values.
+ArgumentParser objects can be told about such sets of values by passing a
+container object as the ``choices`` keyword argument to :meth:`add_argument`.
+When the command-line is parsed with :meth:`parse_args`, arg values will be
+checked, and an error message will be displayed if the arg was not one of the
+acceptable values::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('foo', choices='abc')
+   >>> parser.parse_args('c'.split())
+   Namespace(foo='c')
+   >>> parser.parse_args('X'.split())
+   usage: PROG [-h] {a,b,c}
+   PROG: error: argument foo: invalid choice: 'X' (choose from 'a', 'b', 'c')
+
+Note that inclusion in the ``choices`` container is checked after any type_
+conversions have been performed, so the type of the objects in the ``choices``
+container should match the type_ specified::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('foo', type=complex, choices=[1, 1j])
+   >>> parser.parse_args('1j'.split())
+   Namespace(foo=1j)
+   >>> parser.parse_args('-- -4'.split())
+   usage: PROG [-h] {1,1j}
+   PROG: error: argument foo: invalid choice: (-4+0j) (choose from 1, 1j)
+
+Any object that supports the ``in`` operator can be passed as the ``choices``
+value, so ``dict`` objects, ``set`` objects, custom containers, etc. are all
+supported.
+
+
+required
+^^^^^^^^
+
+In general, the argparse module assumes that flags like ``-f`` and ``--bar``
+indicate *optional* arguments, which can always be omitted at the command-line.
+To change this behavior, i.e. to make an option *required*, the value ``True``
+should be specified for the ``required=`` keyword argument to
+:meth:`add_argument`::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', required=True)
+   >>> parser.parse_args(['--foo', 'BAR'])
+   Namespace(foo='BAR')
+   >>> parser.parse_args([])
+   usage: argparse.py [-h] [--foo FOO]
+   argparse.py: error: option --foo is required
+
+As the example shows, if an option is marked as ``required``, :meth:`parse_args`
+will report an error if that option is not present at the command line.
+
+**Warning:** Required options are generally considered bad form - normal users
+expect *options* to be *optional*. You should avoid the use of required options
+whenever possible.
+
+
+help
+^^^^
+
+A great command-line interface isn't worth anything if your users can't figure
+out which option does what.  So for the end-users, ``help`` is probably the
+most important argument to include in your :meth:`add_argument` calls.  The
+``help`` value should be a string containing a brief description of what the
+argument specifies.  When a user requests help (usually by using ``-h`` or
+``--help`` at the command-line), these ``help`` descriptions will be displayed
+with each argument::
+
+   >>> parser = argparse.ArgumentParser(prog='frobble')
+   >>> parser.add_argument('--foo', action='store_true',
+   ...         help='foo the bars before frobbling')
+   >>> parser.add_argument('bar', nargs='+',
+   ...         help='one of the bars to be frobbled')
+   >>> parser.parse_args('-h'.split())
+   usage: frobble [-h] [--foo] bar [bar ...]
+
+   positional arguments:
+    bar     one of the bars to be frobbled
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo   foo the bars before frobbling
+
+The ``help`` strings can include various format specifiers to avoid repetition
+of things like the program name or the argument default_.  The available
+specifiers include the program name, ``%(prog)s`` and most keyword arguments to
+:meth:`add_argument`, e.g. ``%(default)s``, ``%(type)s``, etc.::
+
+   >>> parser = argparse.ArgumentParser(prog='frobble')
+   >>> parser.add_argument('bar', nargs='?', type=int, default=42,
+   ...         help='the bar to %(prog)s (default: %(default)s)')
+   >>> parser.print_help()
+   usage: frobble [-h] [bar]
+
+   positional arguments:
+    bar     the bar to frobble (default: 42)
+
+   optional arguments:
+    -h, --help  show this help message and exit
+
+
+metavar
+^^^^^^^
+
+When ArgumentParser objects generate help messages, they need some way to refer
+to each expected argument. By default, ArgumentParser objects use the dest_
+value as the "name" of each object.  By default, for positional argument
+actions, the dest_ value is used directly, and for optional argument actions,
+the dest_ value is uppercased.  So if we have a single positional argument with
+``dest='bar'``, that argument will be referred to as ``bar``.  And if we have a
+single optional argument ``--foo`` that should be followed by a single
+command-line arg, that arg will be referred to as ``FOO``.  You can see this
+behavior in the example below::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo')
+   >>> parser.add_argument('bar')
+   >>> parser.parse_args('X --foo Y'.split())
+   Namespace(bar='X', foo='Y')
+   >>> parser.print_help()
+   usage:  [-h] [--foo FOO] bar
+
+   positional arguments:
+    bar
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo FOO
+
+If you would like to provide a different name for your argument in help
+messages, you can supply a value for the ``metavar`` keyword argument to
+:meth:`add_argument`::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', metavar='YYY')
+   >>> parser.add_argument('bar', metavar='XXX')
+   >>> parser.parse_args('X --foo Y'.split())
+   Namespace(bar='X', foo='Y')
+   >>> parser.print_help()
+   usage:  [-h] [--foo YYY] XXX
+
+   positional arguments:
+    XXX
+
+   optional arguments:
+    -h, --help  show this help message and exit
+    --foo YYY
+
+Note that ``metavar`` only changes the *displayed* name - the name of the
+attribute on the :meth:`parse_args` object is still determined by the dest_
+value.
+
+Different values of ``nargs`` may cause the metavar to be used multiple times.
+If you'd like to specify a different display name for each of the arguments,
+you can provide a tuple to ``metavar``::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-x', nargs=2)
+   >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
+   >>> parser.print_help()
+   usage: PROG [-h] [-x X X] [--foo bar baz]
+
+   optional arguments:
+    -h, --help     show this help message and exit
+    -x X X
+    --foo bar baz
+
+
+dest
+^^^^
+
+Most ArgumentParser actions add some value as an attribute of the object
+returned by :meth:`parse_args`. The name of this attribute is determined by the
+``dest`` keyword argument of :meth:`add_argument`. For positional argument
+actions, ``dest`` is normally supplied as the first argument to
+:meth:`add_argument`::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('bar')
+   >>> parser.parse_args('XXX'.split())
+   Namespace(bar='XXX')
+
+For optional argument actions, the value of ``dest`` is normally inferred from
+the option strings. ArgumentParser objects generate the value of ``dest`` by
+taking the first long option string and stripping away the initial ``'--'``
+string.  If no long option strings were supplied, ``dest`` will be derived from
+the first short option string by stripping the initial ``'-'`` character.  Any
+internal ``'-'`` characters will be converted to ``'_'`` characters to make
+sure the string is a valid attribute name. The examples below illustrate this
+behavior::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('-f', '--foo-bar', '--foo')
+   >>> parser.add_argument('-x', '-y')
+   >>> parser.parse_args('-f 1 -x 2'.split())
+   Namespace(foo_bar='1', x='2')
+   >>> parser.parse_args('--foo 1 -y 2'.split())
+   Namespace(foo_bar='1', x='2')
+
+If you would like to use a different attribute name from the one automatically
+inferred by the ArgumentParser, you can supply it with an explicit ``dest``
+parameter::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', dest='bar')
+   >>> parser.parse_args('--foo XXX'.split())
+   Namespace(bar='XXX')
+
+
+The parse_args() method
+-----------------------
+
+.. method:: parse_args([args], [namespace])
+
+   Convert the strings to objects and assign them as attributes of the
+   namespace. Return the populated namespace.
+
+   Previous calls to :meth:`add_argument` determine exactly what objects are
+   created and how they are assigned. See the documentation for
+   :meth:`add_argument` for details.
+
+   By default, the arg strings are taken from ``sys.argv``, and a new empty
+   ``Namespace`` object is created for the attributes.
+
+Option value syntax
+^^^^^^^^^^^^^^^^^^^
+
+The :meth:`parse_args` method supports several ways of specifying the value of
+an option (if it takes one). In the simplest case, the option and its value are
+passed as two separate arguments::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-x')
+   >>> parser.add_argument('--foo')
+   >>> parser.parse_args('-x X'.split())
+   Namespace(foo=None, x='X')
+   >>> parser.parse_args('--foo FOO'.split())
+   Namespace(foo='FOO', x=None)
+
+For long options (options with names longer than a single character), you may
+also pass the option and value as a single command line argument, using ``=``
+to separate them::
+
+   >>> parser.parse_args('--foo=FOO'.split())
+   Namespace(foo='FOO', x=None)
+
+For short options (options only one character long), you may simply concatenate
+the option and its value::
+
+   >>> parser.parse_args('-xX'.split())
+   Namespace(foo=None, x='X')
+
+You can also combine several short options together, using only a single ``-``
+prefix, as long as only the last option (or none of them) requires a value::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-x', action='store_true')
+   >>> parser.add_argument('-y', action='store_true')
+   >>> parser.add_argument('-z')
+   >>> parser.parse_args('-xyzZ'.split())
+   Namespace(x=True, y=True, z='Z')
+
+
+Invalid arguments
+^^^^^^^^^^^^^^^^^
+
+While parsing the command-line, ``parse_args`` checks for a variety of errors,
+including ambiguous options, invalid types, invalid options, wrong number of
+positional arguments, etc. When it encounters such an error, it exits and
+prints the error along with a usage message::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('--foo', type=int)
+   >>> parser.add_argument('bar', nargs='?')
+
+   >>> # invalid type
+   >>> parser.parse_args(['--foo', 'spam'])
+   usage: PROG [-h] [--foo FOO] [bar]
+   PROG: error: argument --foo: invalid int value: 'spam'
+
+   >>> # invalid option
+   >>> parser.parse_args(['--bar'])
+   usage: PROG [-h] [--foo FOO] [bar]
+   PROG: error: no such option: --bar
+
+   >>> # wrong number of arguments
+   >>> parser.parse_args(['spam', 'badger'])
+   usage: PROG [-h] [--foo FOO] [bar]
+   PROG: error: extra arguments found: badger
+
+
+Arguments containing ``"-"``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``parse_args`` method attempts to give errors whenever the user has clearly
+made a mistake, but some situations are inherently ambiguous. For example, the
+command-line arg ``'-1'`` could either be an attempt to specify an option or an
+attempt to provide a positional argument. The ``parse_args`` method is cautious
+here: positional arguments may only begin with ``'-'`` if they look like
+negative numbers and there are no options in the parser that look like negative
+numbers::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-x')
+   >>> parser.add_argument('foo', nargs='?')
+
+   >>> # no negative number options, so -1 is a positional argument
+   >>> parser.parse_args(['-x', '-1'])
+   Namespace(foo=None, x='-1')
+
+   >>> # no negative number options, so -1 and -5 are positional arguments
+   >>> parser.parse_args(['-x', '-1', '-5'])
+   Namespace(foo='-5', x='-1')
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-1', dest='one')
+   >>> parser.add_argument('foo', nargs='?')
+
+   >>> # negative number options present, so -1 is an option
+   >>> parser.parse_args(['-1', 'X'])
+   Namespace(foo=None, one='X')
+
+   >>> # negative number options present, so -2 is an option
+   >>> parser.parse_args(['-2'])
+   usage: PROG [-h] [-1 ONE] [foo]
+   PROG: error: no such option: -2
+
+   >>> # negative number options present, so both -1s are options
+   >>> parser.parse_args(['-1', '-1'])
+   usage: PROG [-h] [-1 ONE] [foo]
+   PROG: error: argument -1: expected one argument
+
+If you have positional arguments that must begin with ``'-'`` and don't look
+like negative numbers, you can insert the pseudo-argument ``'--'`` which tells
+``parse_args`` that everything after that is a positional argument::
+
+   >>> parser.parse_args(['--', '-f'])
+   Namespace(foo='-f', one=None)
+
+
+Argument abbreviations
+^^^^^^^^^^^^^^^^^^^^^^
+
+The :meth:`parse_args` method allows you to abbreviate long options if the
+abbreviation is unambiguous::
+
+   >>> parser = argparse.ArgumentParser(prog='PROG')
+   >>> parser.add_argument('-bacon')
+   >>> parser.add_argument('-badger')
+   >>> parser.parse_args('-bac MMM'.split())
+   Namespace(bacon='MMM', badger=None)
+   >>> parser.parse_args('-bad WOOD'.split())
+   Namespace(bacon=None, badger='WOOD')
+   >>> parser.parse_args('-ba BA'.split())
+   usage: PROG [-h] [-bacon BACON] [-badger BADGER]
+   PROG: error: ambiguous option: -ba could match -badger, -bacon
+
+As you can see above, you will get an error if you pick a prefix that could
+refer to more than one option.
+
+
+Beyond ``sys.argv``
+^^^^^^^^^^^^^^^^^^^
+
+Sometimes it may be useful to have an ArgumentParser parse args other than
+those of ``sys.argv``.  This can be accomplished by passing a list of strings
+to ``parse_args``.  You may have noticed that the examples in the argparse
+documentation have made heavy use of this calling style - it is much easier
+to use at the interactive prompt::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument(
+   ...     'integers', metavar='int', type=int, choices=xrange(10),
+   ...  nargs='+', help='an integer in the range 0..9')
+   >>> parser.add_argument(
+   ...     '--sum', dest='accumulate', action='store_const', const=sum,
+   ...   default=max, help='sum the integers (default: find the max)')
+   >>> parser.parse_args(['1', '2', '3', '4'])
+   Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
+   >>> parser.parse_args('1 2 3 4 --sum'.split())
+   Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])
+
+
+Custom namespaces
+^^^^^^^^^^^^^^^^^
+
+It may also be useful to have an ArgumentParser assign attributes to an already
+existing object, rather than the newly-created Namespace object that is
+normally used. This can be achieved by specifying the ``namespace=`` keyword
+argument::
+
+   >>> class C(object):
+   ...     pass
+   ...
+   >>> c = C()
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo')
+   >>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
+   >>> c.foo
+   'BAR'
+
+
+Other utilities
+---------------
+
+Sub-commands
+^^^^^^^^^^^^
+
+.. method:: add_subparsers()
+
+   A lot of programs split up their functionality into a number of
+   sub-commands, for example, the ``svn`` program can invoke sub-commands like
+   ``svn checkout``, ``svn update``, ``svn commit``, etc.  Splitting up
+   functionality this way can be a particularly good idea when a program
+   performs several different functions which require different kinds of
+   command-line arguments.  ArgumentParser objects support the creation of such
+   sub-commands with the :meth:`add_subparsers` method.  The
+   :meth:`add_subparsers` method is normally called with no arguments and
+   returns an special action object.  This object has a single method,
+   ``add_parser``, which takes a command name and any ArgumentParser
+   constructor arguments, and returns an ArgumentParser object that can be
+   modified as usual.
+
+   Some example usage::
+
+     >>> # create the top-level parser
+     >>> parser = argparse.ArgumentParser(prog='PROG')
+     >>> parser.add_argument('--foo', action='store_true', help='foo help')
+     >>> subparsers = parser.add_subparsers(help='sub-command help')
+     >>>
+     >>> # create the parser for the "a" command
+     >>> parser_a = subparsers.add_parser('a', help='a help')
+     >>> parser_a.add_argument('bar', type=int, help='bar help')
+     >>>
+     >>> # create the parser for the "b" command
+     >>> parser_b = subparsers.add_parser('b', help='b help')
+     >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
+     >>>
+     >>> # parse some arg lists
+     >>> parser.parse_args(['a', '12'])
+     Namespace(bar=12, foo=False)
+     >>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
+     Namespace(baz='Z', foo=True)
+
+   Note that the object returned by :meth:`parse_args` will only contain
+   attributes for the main parser and the subparser that was selected by the
+   command line (and not any other subparsers).  So in the example above, when
+   the ``"a"`` command is specified, only the ``foo`` and ``bar`` attributes
+   are present, and when the ``"b"`` command is specified, only the ``foo`` and
+   ``baz`` attributes are present.
+
+   Similarly, when a help message is requested from a subparser, only the help
+   for that particular parser will be printed. The help message will not
+   include parent parser or sibling parser messages. (You can however supply a
+   help message for each subparser command by suppling the ``help=`` argument
+   to ``add_parser`` as above.)
+
+   ::
+
+     >>> parser.parse_args(['--help'])
+     usage: PROG [-h] [--foo] {a,b} ...
+
+     positional arguments:
+       {a,b}   sub-command help
+     a     a help
+     b     b help
+
+     optional arguments:
+       -h, --help  show this help message and exit
+       --foo   foo help
+
+     >>> parser.parse_args(['a', '--help'])
+     usage: PROG a [-h] bar
+
+     positional arguments:
+       bar     bar help
+
+     optional arguments:
+       -h, --help  show this help message and exit
+
+     >>> parser.parse_args(['b', '--help'])
+     usage: PROG b [-h] [--baz {X,Y,Z}]
+
+     optional arguments:
+       -h, --help     show this help message and exit
+       --baz {X,Y,Z}  baz help
+
+   The :meth:`add_subparsers` method also supports ``title`` and
+   ``description`` keyword arguments.  When either is present, the subparser's
+   commands will appear in their own group in the help output.  For example::
+
+     >>> parser = argparse.ArgumentParser()
+     >>> subparsers = parser.add_subparsers(title='subcommands',
+     ...                                    description='valid subcommands',
+     ...                                    help='additional help')
+     >>> subparsers.add_parser('foo')
+     >>> subparsers.add_parser('bar')
+     >>> parser.parse_args(['-h'])
+     usage:  [-h] {foo,bar} ...
+
+     optional arguments:
+       -h, --help  show this help message and exit
+
+     subcommands:
+       valid subcommands
+
+       {foo,bar}   additional help
+
+
+   One particularly effective way of handling sub-commands is to combine the
+   use of the :meth:`add_subparsers` method with calls to :meth:`set_defaults`
+   so that each subparser knows which Python function it should execute.  For
+   example::
+
+     >>> # sub-command functions
+     >>> def foo(args):
+     ...     print args.x * args.y
+     ...
+     >>> def bar(args):
+     ...     print '((%s))' % args.z
+     ...
+     >>> # create the top-level parser
+     >>> parser = argparse.ArgumentParser()
+     >>> subparsers = parser.add_subparsers()
+     >>>
+     >>> # create the parser for the "foo" command
+     >>> parser_foo = subparsers.add_parser('foo')
+     >>> parser_foo.add_argument('-x', type=int, default=1)
+     >>> parser_foo.add_argument('y', type=float)
+     >>> parser_foo.set_defaults(func=foo)
+     >>>
+     >>> # create the parser for the "bar" command
+     >>> parser_bar = subparsers.add_parser('bar')
+     >>> parser_bar.add_argument('z')
+     >>> parser_bar.set_defaults(func=bar)
+     >>>
+     >>> # parse the args and call whatever function was selected
+     >>> args = parser.parse_args('foo 1 -x 2'.split())
+     >>> args.func(args)
+     2.0
+     >>>
+     >>> # parse the args and call whatever function was selected
+     >>> args = parser.parse_args('bar XYZYX'.split())
+     >>> args.func(args)
+     ((XYZYX))
+
+   This way, you can let :meth:`parse_args` do all the work for you, and then
+   just call the appropriate function after the argument parsing is complete.
+   Associating functions with actions like this is typically the easiest way
+   to handle the different actions for each of your subparsers. However, if you
+   find it necessary to check the name of the subparser that was invoked, you
+   can always provide a ``dest`` keyword argument to the :meth:`add_subparsers`
+   call::
+
+     >>> parser = argparse.ArgumentParser()
+     >>> subparsers = parser.add_subparsers(dest='subparser_name')
+     >>> subparser1 = subparsers.add_parser('1')
+     >>> subparser1.add_argument('-x')
+     >>> subparser2 = subparsers.add_parser('2')
+     >>> subparser2.add_argument('y')
+     >>> parser.parse_args(['2', 'frobble'])
+     Namespace(subparser_name='2', y='frobble')
+
+
+FileType objects
+^^^^^^^^^^^^^^^^
+
+.. class:: FileType(mode='r', bufsize=None)
+
+   The :class:`FileType` factory creates objects that can be passed to the type
+   argument of :meth:`add_argument`. Arguments that have :class:`FileType`
+   objects as their type will open command-line args as files with the
+   requested modes and buffer sizes:
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--output', type=argparse.FileType('wb', 0))
+   >>> parser.parse_args(['--output', 'out'])
+   Namespace(output=<open file 'out', mode 'wb' at 0x...>)
+
+   FileType objects understand the pseudo-argument ``'-'`` and automatically
+   convert this into ``sys.stdin`` for readable :class:`FileType` objects and
+   ``sys.stdout`` for writable :class:`FileType` objects:
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('infile', type=argparse.FileType('r'))
+   >>> parser.parse_args(['-'])
+   Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>)
+
+
+Argument groups
+^^^^^^^^^^^^^^^
+
+.. method:: add_argument_group([title], [description])
+
+   By default, ArgumentParser objects group command-line arguments into
+   "positional arguments" and "optional arguments" when displaying help
+   messages. When there is a better conceptual grouping of arguments than this
+   default one, appropriate groups can be created using the
+   :meth:`add_argument_group` method::
+
+     >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
+     >>> group = parser.add_argument_group('group')
+     >>> group.add_argument('--foo', help='foo help')
+     >>> group.add_argument('bar', help='bar help')
+     >>> parser.print_help()
+     usage: PROG [--foo FOO] bar
+
+     group:
+       bar    bar help
+       --foo FOO  foo help
+
+   The :meth:`add_argument_group` method returns an argument group object which
+   has an :meth:`add_argument` method just like a regular ArgumentParser
+   objects. When an argument is added to the group, the parser treats it just
+   like a normal argument, but displays the argument in a separate group for
+   help messages. The :meth:`add_argument_group` method accepts ``title`` and
+   ``description`` arguments which can be used to customize this display::
+
+     >>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
+     >>> group1 = parser.add_argument_group('group1', 'group1 description')
+     >>> group1.add_argument('foo', help='foo help')
+     >>> group2 = parser.add_argument_group('group2', 'group2 description')
+     >>> group2.add_argument('--bar', help='bar help')
+     >>> parser.print_help()
+     usage: PROG [--bar BAR] foo
+
+     group1:
+       group1 description
+
+       foo    foo help
+
+     group2:
+       group2 description
+
+       --bar BAR  bar help
+
+   Note that any arguments not in your user defined groups will end up back in
+   the usual "positional arguments" and "optional arguments" sections.
+
+
+Mutual exclusion
+^^^^^^^^^^^^^^^^
+
+.. method:: add_mutually_exclusive_group([required=False])
+
+   Sometimes, you need to make sure that only one of a couple different options
+   is specified on the command line. You can create groups of such mutually
+   exclusive arguments using the :meth:`add_mutually_exclusive_group` method.
+   When :func:`parse_args` is called, argparse will make sure that only one of
+   the arguments in the mutually exclusive group was present on the command
+   line::
+
+     >>> parser = argparse.ArgumentParser(prog='PROG')
+     >>> group = parser.add_mutually_exclusive_group()
+     >>> group.add_argument('--foo', action='store_true')
+     >>> group.add_argument('--bar', action='store_false')
+     >>> parser.parse_args(['--foo'])
+     Namespace(bar=True, foo=True)
+     >>> parser.parse_args(['--bar'])
+     Namespace(bar=False, foo=False)
+     >>> parser.parse_args(['--foo', '--bar'])
+     usage: PROG [-h] [--foo | --bar]
+     PROG: error: argument --bar: not allowed with argument --foo
+
+   The :meth:`add_mutually_exclusive_group` method also accepts a ``required``
+   argument, to indicate that at least one of the mutually exclusive arguments
+   is required::
+
+     >>> parser = argparse.ArgumentParser(prog='PROG')
+     >>> group = parser.add_mutually_exclusive_group(required=True)
+     >>> group.add_argument('--foo', action='store_true')
+     >>> group.add_argument('--bar', action='store_false')
+     >>> parser.parse_args([])
+     usage: PROG [-h] (--foo | --bar)
+     PROG: error: one of the arguments --foo --bar is required
+
+   Note that currently mutually exclusive argument groups do not support the
+   ``title`` and ``description`` arguments of :meth:`add_argument_group`. This
+   may change in the future however, so you are *strongly* recommended to
+   specify ``required`` as a keyword argument if you use it.
+
+
+Parser defaults
+^^^^^^^^^^^^^^^
+
+.. method:: set_defaults(**kwargs)
+
+   Most of the time, the attributes of the object returned by
+   :meth:`parse_args` will be fully determined by inspecting the command-line
+   args and the argument actions described in your :meth:`add_argument` calls.
+   However, sometimes it may be useful to add some additional attributes that
+   are determined without any inspection of the command-line.  The
+   :meth:`set_defaults` method allows you to do this::
+
+     >>> parser = argparse.ArgumentParser()
+     >>> parser.add_argument('foo', type=int)
+     >>> parser.set_defaults(bar=42, baz='badger')
+     >>> parser.parse_args(['736'])
+     Namespace(bar=42, baz='badger', foo=736)
+
+   Note that parser-level defaults always override argument-level defaults. So
+   if you set a parser-level default for a name that matches an argument, the
+   old argument default will no longer be used::
+
+     >>> parser = argparse.ArgumentParser()
+     >>> parser.add_argument('--foo', default='bar')
+     >>> parser.set_defaults(foo='spam')
+     >>> parser.parse_args([])
+     Namespace(foo='spam')
+
+   Parser-level defaults can be particularly useful when you're working with
+   multiple parsers.  See the :meth:`add_subparsers` method for an example of
+   this type.
+
+.. method:: get_default(dest)
+
+   Get the default value for a namespace attribute, as set by either
+   :meth:`add_argument` or by :meth:`set_defaults`::
+
+     >>> parser = argparse.ArgumentParser()
+     >>> parser.add_argument('--foo', default='badger')
+     >>> parser.get_default('foo')
+     'badger'
+
+
+Printing help
+^^^^^^^^^^^^^
+
+In most typical applications, :meth:`parse_args` will take care of formatting
+and printing any usage or error messages. However, should you want to format or
+print these on your own, several methods are available:
+
+.. method:: print_usage([file]):
+
+   Print a brief description of how the :class:`ArgumentParser` should be
+   invoked on the command line.  If ``file`` is not present, ``sys.stderr`` is
+   assumed.
+
+.. method:: print_help([file]):
+
+   Print a help message, including the program usage and information about the
+   arguments registered with the :class:`ArgumentParser`. If ``file`` is not
+   present, ``sys.stderr`` is assumed.
+
+There are also variants of these methods that simply return a string instead of
+printing it:
+
+.. method:: format_usage():
+
+   Return a string containing a brief description of how the
+   :class:`ArgumentParser` should be invoked on the command line.
+
+.. method:: format_help():
+
+   Return a string containing a help message, including the program usage and
+   information about the arguments registered with the :class:`ArgumentParser`.
+
+
+
+Partial parsing
+^^^^^^^^^^^^^^^
+
+.. method:: parse_known_args([args], [namespace])
+
+Sometimes a script may only parse a few of the command line arguments, passing
+the remaining arguments on to another script or program. In these cases, the
+:meth:`parse_known_args` method can be useful. It works much like
+:meth:`parse_args` except that it does not produce an error when extra
+arguments are present. Instead, it returns a two item tuple containing the
+populated namespace and the list of remaining argument strings.
+
+::
+
+   >>> parser = argparse.ArgumentParser()
+   >>> parser.add_argument('--foo', action='store_true')
+   >>> parser.add_argument('bar')
+   >>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
+   (Namespace(bar='BAR', foo=True), ['--badger', 'spam'])
+
+
+Customizing file parsing
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. method:: convert_arg_line_to_args(arg_line)
+
+   Arguments that are read from a file (see the ``fromfile_prefix_chars``
+   keyword argument to the :class:`ArgumentParser` constructor) are read one
+   argument per line.  If you need fancier parsing, then you can subclass the
+   :class:`ArgumentParser` and override the :meth:`convert_arg_line_to_args`
+   method.
+
+   This method takes a single argument ``arg_line`` which is a string read from
+   the argument file.  It returns a list of arguments parsed from this string.
+   The method is called once per line read from the argument file, in order.
+
+   A useful override of this method is one that treats each space-separated
+   word as an argument::
+
+    def convert_arg_line_to_args(self, arg_line):
+        for arg in arg_line.split():
+            if not arg.strip():
+                continue
+            yield arg
+
+
+Upgrading optparse code
+-----------------------
+
+Originally, the argparse module had attempted to maintain compatibility with
+ optparse. However, optparse was difficult to extend transparently,
+ particularly with the changes required to support the new ``nargs=``
+ specifiers and better usage messges. When most everything in optparse had
+ either been copy-pasted over or monkey-patched, it no longer seemed practical
+ to try to maintain the backwards compatibility.
+
+A partial upgrade path from optparse to argparse:
+
+* Replace all ``add_option()`` calls with :meth:`add_argument` calls.
+
+* Replace ``options, args = parser.parse_args()`` with
+  ``args = parser.parse_args()`` and add additional :meth:`add_argument` calls
+  for the positional arguments.
+
+* Replace callback actions and the ``callback_*`` keyword arguments with
+  ``type`` or ``action`` arguments.
+
+* Replace string names for ``type`` keyword arguments with the corresponding
+  type objects (e.g. int, float, complex, etc).
+
+* Replace ``Values`` with ``Namespace`` and ``OptionError/OptionValueError``
+  with ``ArgumentError``.
+
+* Replace strings with implicit arguments such as ``%default`` or ``%prog``
+  with the standard python syntax to use dictionaries to format strings, that
+  is, ``%(default)s`` and ``%(prog)s``.
diff --git a/Lib/argparse.py b/Lib/argparse.py
index e91bb7a..cde1fe9 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -1,2351 +1,2351 @@
-# Copyright 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
-# use this file except in compliance with the License. You may obtain a copy
-# of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Command-line parsing library
-
-This module is an optparse-inspired command-line parsing library that:
-
-    - handles both optional and positional arguments
-    - produces highly informative usage messages
-    - supports parsers that dispatch to sub-parsers
-
-The following is a simple usage example that sums integers from the
-command-line and writes the result to a file::
-
-    parser = argparse.ArgumentParser(
-        description='sum the integers at the command line')
-    parser.add_argument(
-        'integers', metavar='int', nargs='+', type=int,
-        help='an integer to be summed')
-    parser.add_argument(
-        '--log', default=sys.stdout, type=argparse.FileType('w'),
-        help='the file where the sum should be written')
-    args = parser.parse_args()
-    args.log.write('%s' % sum(args.integers))
-    args.log.close()
-
-The module contains the following public classes:
-
-    - ArgumentParser -- The main entry point for command-line parsing. As the
-        example above shows, the add_argument() method is used to populate
-        the parser with actions for optional and positional arguments. Then
-        the parse_args() method is invoked to convert the args at the
-        command-line into an object with attributes.
-
-    - ArgumentError -- The exception raised by ArgumentParser objects when
-        there are errors with the parser's actions. Errors raised while
-        parsing the command-line are caught by ArgumentParser and emitted
-        as command-line messages.
-
-    - FileType -- A factory for defining types of files to be created. As the
-        example above shows, instances of FileType are typically passed as
-        the type= argument of add_argument() calls.
-
-    - Action -- The base class for parser actions. Typically actions are
-        selected by passing strings like 'store_true' or 'append_const' to
-        the action= argument of add_argument(). However, for greater
-        customization of ArgumentParser actions, subclasses of Action may
-        be defined and passed as the action= argument.
-
-    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
-        ArgumentDefaultsHelpFormatter -- Formatter classes which
-        may be passed as the formatter_class= argument to the
-        ArgumentParser constructor. HelpFormatter is the default,
-        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
-        not to change the formatting for help text, and
-        ArgumentDefaultsHelpFormatter adds information about argument defaults
-        to the help.
-
-All other classes in this module are considered implementation details.
-(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
-considered public as object names -- the API of the formatter objects is
-still considered an implementation detail.)
-"""
-
-__version__ = '1.1'
-__all__ = [
-    'ArgumentParser',
-    'ArgumentError',
-    'Namespace',
-    'Action',
-    'FileType',
-    'HelpFormatter',
-    'RawDescriptionHelpFormatter',
-    'RawTextHelpFormatter',
-    'ArgumentDefaultsHelpFormatter',
-]
-
-
-import copy as _copy
-import os as _os
-import re as _re
-import sys as _sys
-import textwrap as _textwrap
-
-from gettext import gettext as _
-
-try:
-    _set = set
-except NameError:
-    from sets import Set as _set
-
-try:
-    _basestring = basestring
-except NameError:
-    _basestring = str
-
-try:
-    _sorted = sorted
-except NameError:
-
-    def _sorted(iterable, reverse=False):
-        result = list(iterable)
-        result.sort()
-        if reverse:
-            result.reverse()
-        return result
-
-
-def _callable(obj):
-    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
-
-# silence Python 2.6 buggy warnings about Exception.message
-if _sys.version_info[:2] == (2, 6):
-    import warnings
-    warnings.filterwarnings(
-        action='ignore',
-        message='BaseException.message has been deprecated as of Python 2.6',
-        category=DeprecationWarning,
-        module='argparse')
-
-
-SUPPRESS = '==SUPPRESS=='
-
-OPTIONAL = '?'
-ZERO_OR_MORE = '*'
-ONE_OR_MORE = '+'
-PARSER = 'A...'
-REMAINDER = '...'
-
-# =============================
-# Utility functions and classes
-# =============================
-
-class _AttributeHolder(object):
-    """Abstract base class that provides __repr__.
-
-    The __repr__ method returns a string in the format::
-        ClassName(attr=name, attr=name, ...)
-    The attributes are determined either by a class-level attribute,
-    '_kwarg_names', or by inspecting the instance __dict__.
-    """
-
-    def __repr__(self):
-        type_name = type(self).__name__
-        arg_strings = []
-        for arg in self._get_args():
-            arg_strings.append(repr(arg))
-        for name, value in self._get_kwargs():
-            arg_strings.append('%s=%r' % (name, value))
-        return '%s(%s)' % (type_name, ', '.join(arg_strings))
-
-    def _get_kwargs(self):
-        return _sorted(self.__dict__.items())
-
-    def _get_args(self):
-        return []
-
-
-def _ensure_value(namespace, name, value):
-    if getattr(namespace, name, None) is None:
-        setattr(namespace, name, value)
-    return getattr(namespace, name)
-
-
-# ===============
-# Formatting Help
-# ===============
-
-class HelpFormatter(object):
-    """Formatter for generating usage messages and argument help strings.
-
-    Only the name of this class is considered a public API. All the methods
-    provided by the class are considered an implementation detail.
-    """
-
-    def __init__(self,
-                 prog,
-                 indent_increment=2,
-                 max_help_position=24,
-                 width=None):
-
-        # default setting for width
-        if width is None:
-            try:
-                width = int(_os.environ['COLUMNS'])
-            except (KeyError, ValueError):
-                width = 80
-            width -= 2
-
-        self._prog = prog
-        self._indent_increment = indent_increment
-        self._max_help_position = max_help_position
-        self._width = width
-
-        self._current_indent = 0
-        self._level = 0
-        self._action_max_length = 0
-
-        self._root_section = self._Section(self, None)
-        self._current_section = self._root_section
-
-        self._whitespace_matcher = _re.compile(r'\s+')
-        self._long_break_matcher = _re.compile(r'\n\n\n+')
-
-    # ===============================
-    # Section and indentation methods
-    # ===============================
-    def _indent(self):
-        self._current_indent += self._indent_increment
-        self._level += 1
-
-    def _dedent(self):
-        self._current_indent -= self._indent_increment
-        assert self._current_indent >= 0, 'Indent decreased below 0.'
-        self._level -= 1
-
-    class _Section(object):
-
-        def __init__(self, formatter, parent, heading=None):
-            self.formatter = formatter
-            self.parent = parent
-            self.heading = heading
-            self.items = []
-
-        def format_help(self):
-            # format the indented section
-            if self.parent is not None:
-                self.formatter._indent()
-            join = self.formatter._join_parts
-            for func, args in self.items:
-                func(*args)
-            item_help = join([func(*args) for func, args in self.items])
-            if self.parent is not None:
-                self.formatter._dedent()
-
-            # return nothing if the section was empty
-            if not item_help:
-                return ''
-
-            # add the heading if the section was non-empty
-            if self.heading is not SUPPRESS and self.heading is not None:
-                current_indent = self.formatter._current_indent
-                heading = '%*s%s:\n' % (current_indent, '', self.heading)
-            else:
-                heading = ''
-
-            # join the section-initial newline, the heading and the help
-            return join(['\n', heading, item_help, '\n'])
-
-    def _add_item(self, func, args):
-        self._current_section.items.append((func, args))
-
-    # ========================
-    # Message building methods
-    # ========================
-    def start_section(self, heading):
-        self._indent()
-        section = self._Section(self, self._current_section, heading)
-        self._add_item(section.format_help, [])
-        self._current_section = section
-
-    def end_section(self):
-        self._current_section = self._current_section.parent
-        self._dedent()
-
-    def add_text(self, text):
-        if text is not SUPPRESS and text is not None:
-            self._add_item(self._format_text, [text])
-
-    def add_usage(self, usage, actions, groups, prefix=None):
-        if usage is not SUPPRESS:
-            args = usage, actions, groups, prefix
-            self._add_item(self._format_usage, args)
-
-    def add_argument(self, action):
-        if action.help is not SUPPRESS:
-
-            # find all invocations
-            get_invocation = self._format_action_invocation
-            invocations = [get_invocation(action)]
-            for subaction in self._iter_indented_subactions(action):
-                invocations.append(get_invocation(subaction))
-
-            # update the maximum item length
-            invocation_length = max([len(s) for s in invocations])
-            action_length = invocation_length + self._current_indent
-            self._action_max_length = max(self._action_max_length,
-                                          action_length)
-
-            # add the item to the list
-            self._add_item(self._format_action, [action])
-
-    def add_arguments(self, actions):
-        for action in actions:
-            self.add_argument(action)
-
-    # =======================
-    # Help-formatting methods
-    # =======================
-    def format_help(self):
-        help = self._root_section.format_help()
-        if help:
-            help = self._long_break_matcher.sub('\n\n', help)
-            help = help.strip('\n') + '\n'
-        return help
-
-    def _join_parts(self, part_strings):
-        return ''.join([part
-                        for part in part_strings
-                        if part and part is not SUPPRESS])
-
-    def _format_usage(self, usage, actions, groups, prefix):
-        if prefix is None:
-            prefix = _('usage: ')
-
-        # if usage is specified, use that
-        if usage is not None:
-            usage = usage % dict(prog=self._prog)
-
-        # if no optionals or positionals are available, usage is just prog
-        elif usage is None and not actions:
-            usage = '%(prog)s' % dict(prog=self._prog)
-
-        # if optionals and positionals are available, calculate usage
-        elif usage is None:
-            prog = '%(prog)s' % dict(prog=self._prog)
-
-            # split optionals from positionals
-            optionals = []
-            positionals = []
-            for action in actions:
-                if action.option_strings:
-                    optionals.append(action)
-                else:
-                    positionals.append(action)
-
-            # build full usage string
-            format = self._format_actions_usage
-            action_usage = format(optionals + positionals, groups)
-            usage = ' '.join([s for s in [prog, action_usage] if s])
-
-            # wrap the usage parts if it's too long
-            text_width = self._width - self._current_indent
-            if len(prefix) + len(usage) > text_width:
-
-                # break usage into wrappable parts
-                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
-                opt_usage = format(optionals, groups)
-                pos_usage = format(positionals, groups)
-                opt_parts = _re.findall(part_regexp, opt_usage)
-                pos_parts = _re.findall(part_regexp, pos_usage)
-                assert ' '.join(opt_parts) == opt_usage
-                assert ' '.join(pos_parts) == pos_usage
-
-                # helper for wrapping lines
-                def get_lines(parts, indent, prefix=None):
-                    lines = []
-                    line = []
-                    if prefix is not None:
-                        line_len = len(prefix) - 1
-                    else:
-                        line_len = len(indent) - 1
-                    for part in parts:
-                        if line_len + 1 + len(part) > text_width:
-                            lines.append(indent + ' '.join(line))
-                            line = []
-                            line_len = len(indent) - 1
-                        line.append(part)
-                        line_len += len(part) + 1
-                    if line:
-                        lines.append(indent + ' '.join(line))
-                    if prefix is not None:
-                        lines[0] = lines[0][len(indent):]
-                    return lines
-
-                # if prog is short, follow it with optionals or positionals
-                if len(prefix) + len(prog) <= 0.75 * text_width:
-                    indent = ' ' * (len(prefix) + len(prog) + 1)
-                    if opt_parts:
-                        lines = get_lines([prog] + opt_parts, indent, prefix)
-                        lines.extend(get_lines(pos_parts, indent))
-                    elif pos_parts:
-                        lines = get_lines([prog] + pos_parts, indent, prefix)
-                    else:
-                        lines = [prog]
-
-                # if prog is long, put it on its own line
-                else:
-                    indent = ' ' * len(prefix)
-                    parts = opt_parts + pos_parts
-                    lines = get_lines(parts, indent)
-                    if len(lines) > 1:
-                        lines = []
-                        lines.extend(get_lines(opt_parts, indent))
-                        lines.extend(get_lines(pos_parts, indent))
-                    lines = [prog] + lines
-
-                # join lines into usage
-                usage = '\n'.join(lines)
-
-        # prefix with 'usage:'
-        return '%s%s\n\n' % (prefix, usage)
-
-    def _format_actions_usage(self, actions, groups):
-        # find group indices and identify actions in groups
-        group_actions = _set()
-        inserts = {}
-        for group in groups:
-            try:
-                start = actions.index(group._group_actions[0])
-            except ValueError:
-                continue
-            else:
-                end = start + len(group._group_actions)
-                if actions[start:end] == group._group_actions:
-                    for action in group._group_actions:
-                        group_actions.add(action)
-                    if not group.required:
-                        inserts[start] = '['
-                        inserts[end] = ']'
-                    else:
-                        inserts[start] = '('
-                        inserts[end] = ')'
-                    for i in range(start + 1, end):
-                        inserts[i] = '|'
-
-        # collect all actions format strings
-        parts = []
-        for i, action in enumerate(actions):
-
-            # suppressed arguments are marked with None
-            # remove | separators for suppressed arguments
-            if action.help is SUPPRESS:
-                parts.append(None)
-                if inserts.get(i) == '|':
-                    inserts.pop(i)
-                elif inserts.get(i + 1) == '|':
-                    inserts.pop(i + 1)
-
-            # produce all arg strings
-            elif not action.option_strings:
-                part = self._format_args(action, action.dest)
-
-                # if it's in a group, strip the outer []
-                if action in group_actions:
-                    if part[0] == '[' and part[-1] == ']':
-                        part = part[1:-1]
-
-                # add the action string to the list
-                parts.append(part)
-
-            # produce the first way to invoke the option in brackets
-            else:
-                option_string = action.option_strings[0]
-
-                # if the Optional doesn't take a value, format is:
-                #    -s or --long
-                if action.nargs == 0:
-                    part = '%s' % option_string
-
-                # if the Optional takes a value, format is:
-                #    -s ARGS or --long ARGS
-                else:
-                    default = action.dest.upper()
-                    args_string = self._format_args(action, default)
-                    part = '%s %s' % (option_string, args_string)
-
-                # make it look optional if it's not required or in a group
-                if not action.required and action not in group_actions:
-                    part = '[%s]' % part
-
-                # add the action string to the list
-                parts.append(part)
-
-        # insert things at the necessary indices
-        for i in _sorted(inserts, reverse=True):
-            parts[i:i] = [inserts[i]]
-
-        # join all the action items with spaces
-        text = ' '.join([item for item in parts if item is not None])
-
-        # clean up separators for mutually exclusive groups
-        open = r'[\[(]'
-        close = r'[\])]'
-        text = _re.sub(r'(%s) ' % open, r'\1', text)
-        text = _re.sub(r' (%s)' % close, r'\1', text)
-        text = _re.sub(r'%s *%s' % (open, close), r'', text)
-        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
-        text = text.strip()
-
-        # return the text
-        return text
-
-    def _format_text(self, text):
-        if '%(prog)' in text:
-            text = text % dict(prog=self._prog)
-        text_width = self._width - self._current_indent
-        indent = ' ' * self._current_indent
-        return self._fill_text(text, text_width, indent) + '\n\n'
-
-    def _format_action(self, action):
-        # determine the required width and the entry label
-        help_position = min(self._action_max_length + 2,
-                            self._max_help_position)
-        help_width = self._width - help_position
-        action_width = help_position - self._current_indent - 2
-        action_header = self._format_action_invocation(action)
-
-        # ho nelp; start on same line and add a final newline
-        if not action.help:
-            tup = self._current_indent, '', action_header
-            action_header = '%*s%s\n' % tup
-
-        # short action name; start on the same line and pad two spaces
-        elif len(action_header) <= action_width:
-            tup = self._current_indent, '', action_width, action_header
-            action_header = '%*s%-*s  ' % tup
-            indent_first = 0
-
-        # long action name; start on the next line
-        else:
-            tup = self._current_indent, '', action_header
-            action_header = '%*s%s\n' % tup
-            indent_first = help_position
-
-        # collect the pieces of the action help
-        parts = [action_header]
-
-        # if there was help for the action, add lines of help text
-        if action.help:
-            help_text = self._expand_help(action)
-            help_lines = self._split_lines(help_text, help_width)
-            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
-            for line in help_lines[1:]:
-                parts.append('%*s%s\n' % (help_position, '', line))
-
-        # or add a newline if the description doesn't end with one
-        elif not action_header.endswith('\n'):
-            parts.append('\n')
-
-        # if there are any sub-actions, add their help as well
-        for subaction in self._iter_indented_subactions(action):
-            parts.append(self._format_action(subaction))
-
-        # return a single string
-        return self._join_parts(parts)
-
-    def _format_action_invocation(self, action):
-        if not action.option_strings:
-            metavar, = self._metavar_formatter(action, action.dest)(1)
-            return metavar
-
-        else:
-            parts = []
-
-            # if the Optional doesn't take a value, format is:
-            #    -s, --long
-            if action.nargs == 0:
-                parts.extend(action.option_strings)
-
-            # if the Optional takes a value, format is:
-            #    -s ARGS, --long ARGS
-            else:
-                default = action.dest.upper()
-                args_string = self._format_args(action, default)
-                for option_string in action.option_strings:
-                    parts.append('%s %s' % (option_string, args_string))
-
-            return ', '.join(parts)
-
-    def _metavar_formatter(self, action, default_metavar):
-        if action.metavar is not None:
-            result = action.metavar
-        elif action.choices is not None:
-            choice_strs = [str(choice) for choice in action.choices]
-            result = '{%s}' % ','.join(choice_strs)
-        else:
-            result = default_metavar
-
-        def format(tuple_size):
-            if isinstance(result, tuple):
-                return result
-            else:
-                return (result, ) * tuple_size
-        return format
-
-    def _format_args(self, action, default_metavar):
-        get_metavar = self._metavar_formatter(action, default_metavar)
-        if action.nargs is None:
-            result = '%s' % get_metavar(1)
-        elif action.nargs == OPTIONAL:
-            result = '[%s]' % get_metavar(1)
-        elif action.nargs == ZERO_OR_MORE:
-            result = '[%s [%s ...]]' % get_metavar(2)
-        elif action.nargs == ONE_OR_MORE:
-            result = '%s [%s ...]' % get_metavar(2)
-        elif action.nargs == REMAINDER:
-            result = '...'
-        elif action.nargs == PARSER:
-            result = '%s ...' % get_metavar(1)
-        else:
-            formats = ['%s' for _ in range(action.nargs)]
-            result = ' '.join(formats) % get_metavar(action.nargs)
-        return result
-
-    def _expand_help(self, action):
-        params = dict(vars(action), prog=self._prog)
-        for name in list(params):
-            if params[name] is SUPPRESS:
-                del params[name]
-        for name in list(params):
-            if hasattr(params[name], '__name__'):
-                params[name] = params[name].__name__
-        if params.get('choices') is not None:
-            choices_str = ', '.join([str(c) for c in params['choices']])
-            params['choices'] = choices_str
-        return self._get_help_string(action) % params
-
-    def _iter_indented_subactions(self, action):
-        try:
-            get_subactions = action._get_subactions
-        except AttributeError:
-            pass
-        else:
-            self._indent()
-            for subaction in get_subactions():
-                yield subaction
-            self._dedent()
-
-    def _split_lines(self, text, width):
-        text = self._whitespace_matcher.sub(' ', text).strip()
-        return _textwrap.wrap(text, width)
-
-    def _fill_text(self, text, width, indent):
-        text = self._whitespace_matcher.sub(' ', text).strip()
-        return _textwrap.fill(text, width, initial_indent=indent,
-                                           subsequent_indent=indent)
-
-    def _get_help_string(self, action):
-        return action.help
-
-
-class RawDescriptionHelpFormatter(HelpFormatter):
-    """Help message formatter which retains any formatting in descriptions.
-
-    Only the name of this class is considered a public API. All the methods
-    provided by the class are considered an implementation detail.
-    """
-
-    def _fill_text(self, text, width, indent):
-        return ''.join([indent + line for line in text.splitlines(True)])
-
-
-class RawTextHelpFormatter(RawDescriptionHelpFormatter):
-    """Help message formatter which retains formatting of all help text.
-
-    Only the name of this class is considered a public API. All the methods
-    provided by the class are considered an implementation detail.
-    """
-
-    def _split_lines(self, text, width):
-        return text.splitlines()
-
-
-class ArgumentDefaultsHelpFormatter(HelpFormatter):
-    """Help message formatter which adds default values to argument help.
-
-    Only the name of this class is considered a public API. All the methods
-    provided by the class are considered an implementation detail.
-    """
-
-    def _get_help_string(self, action):
-        help = action.help
-        if '%(default)' not in action.help:
-            if action.default is not SUPPRESS:
-                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
-                if action.option_strings or action.nargs in defaulting_nargs:
-                    help += ' (default: %(default)s)'
-        return help
-
-
-# =====================
-# Options and Arguments
-# =====================
-
-def _get_action_name(argument):
-    if argument is None:
-        return None
-    elif argument.option_strings:
-        return  '/'.join(argument.option_strings)
-    elif argument.metavar not in (None, SUPPRESS):
-        return argument.metavar
-    elif argument.dest not in (None, SUPPRESS):
-        return argument.dest
-    else:
-        return None
-
-
-class ArgumentError(Exception):
-    """An error from creating or using an argument (optional or positional).
-
-    The string value of this exception is the message, augmented with
-    information about the argument that caused it.
-    """
-
-    def __init__(self, argument, message):
-        self.argument_name = _get_action_name(argument)
-        self.message = message
-
-    def __str__(self):
-        if self.argument_name is None:
-            format = '%(message)s'
-        else:
-            format = 'argument %(argument_name)s: %(message)s'
-        return format % dict(message=self.message,
-                             argument_name=self.argument_name)
-
-
-class ArgumentTypeError(Exception):
-    """An error from trying to convert a command line string to a type."""
-    pass
-
-
-# ==============
-# Action classes
-# ==============
-
-class Action(_AttributeHolder):
-    """Information about how to convert command line strings to Python objects.
-
-    Action objects are used by an ArgumentParser to represent the information
-    needed to parse a single argument from one or more strings from the
-    command line. The keyword arguments to the Action constructor are also
-    all attributes of Action instances.
-
-    Keyword Arguments:
-
-        - option_strings -- A list of command-line option strings which
-            should be associated with this action.
-
-        - dest -- The name of the attribute to hold the created object(s)
-
-        - nargs -- The number of command-line arguments that should be
-            consumed. By default, one argument will be consumed and a single
-            value will be produced.  Other values include:
-                - N (an integer) consumes N arguments (and produces a list)
-                - '?' consumes zero or one arguments
-                - '*' consumes zero or more arguments (and produces a list)
-                - '+' consumes one or more arguments (and produces a list)
-            Note that the difference between the default and nargs=1 is that
-            with the default, a single value will be produced, while with
-            nargs=1, a list containing a single value will be produced.
-
-        - const -- The value to be produced if the option is specified and the
-            option uses an action that takes no values.
-
-        - default -- The value to be produced if the option is not specified.
-
-        - type -- The type which the command-line arguments should be converted
-            to, should be one of 'string', 'int', 'float', 'complex' or a
-            callable object that accepts a single string argument. If None,
-            'string' is assumed.
-
-        - choices -- A container of values that should be allowed. If not None,
-            after a command-line argument has been converted to the appropriate
-            type, an exception will be raised if it is not a member of this
-            collection.
-
-        - required -- True if the action must always be specified at the
-            command line. This is only meaningful for optional command-line
-            arguments.
-
-        - help -- The help string describing the argument.
-
-        - metavar -- The name to be used for the option's argument with the
-            help string. If None, the 'dest' value will be used as the name.
-    """
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 nargs=None,
-                 const=None,
-                 default=None,
-                 type=None,
-                 choices=None,
-                 required=False,
-                 help=None,
-                 metavar=None):
-        self.option_strings = option_strings
-        self.dest = dest
-        self.nargs = nargs
-        self.const = const
-        self.default = default
-        self.type = type
-        self.choices = choices
-        self.required = required
-        self.help = help
-        self.metavar = metavar
-
-    def _get_kwargs(self):
-        names = [
-            'option_strings',
-            'dest',
-            'nargs',
-            'const',
-            'default',
-            'type',
-            'choices',
-            'help',
-            'metavar',
-        ]
-        return [(name, getattr(self, name)) for name in names]
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        raise NotImplementedError(_('.__call__() not defined'))
-
-
-class _StoreAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 nargs=None,
-                 const=None,
-                 default=None,
-                 type=None,
-                 choices=None,
-                 required=False,
-                 help=None,
-                 metavar=None):
-        if nargs == 0:
-            raise ValueError('nargs for store actions must be > 0; if you '
-                             'have nothing to store, actions such as store '
-                             'true or store const may be more appropriate')
-        if const is not None and nargs != OPTIONAL:
-            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
-        super(_StoreAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            nargs=nargs,
-            const=const,
-            default=default,
-            type=type,
-            choices=choices,
-            required=required,
-            help=help,
-            metavar=metavar)
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        setattr(namespace, self.dest, values)
-
-
-class _StoreConstAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 const,
-                 default=None,
-                 required=False,
-                 help=None,
-                 metavar=None):
-        super(_StoreConstAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            nargs=0,
-            const=const,
-            default=default,
-            required=required,
-            help=help)
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        setattr(namespace, self.dest, self.const)
-
-
-class _StoreTrueAction(_StoreConstAction):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 default=False,
-                 required=False,
-                 help=None):
-        super(_StoreTrueAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            const=True,
-            default=default,
-            required=required,
-            help=help)
-
-
-class _StoreFalseAction(_StoreConstAction):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 default=True,
-                 required=False,
-                 help=None):
-        super(_StoreFalseAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            const=False,
-            default=default,
-            required=required,
-            help=help)
-
-
-class _AppendAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 nargs=None,
-                 const=None,
-                 default=None,
-                 type=None,
-                 choices=None,
-                 required=False,
-                 help=None,
-                 metavar=None):
-        if nargs == 0:
-            raise ValueError('nargs for append actions must be > 0; if arg '
-                             'strings are not supplying the value to append, '
-                             'the append const action may be more appropriate')
-        if const is not None and nargs != OPTIONAL:
-            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
-        super(_AppendAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            nargs=nargs,
-            const=const,
-            default=default,
-            type=type,
-            choices=choices,
-            required=required,
-            help=help,
-            metavar=metavar)
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        items = _copy.copy(_ensure_value(namespace, self.dest, []))
-        items.append(values)
-        setattr(namespace, self.dest, items)
-
-
-class _AppendConstAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 const,
-                 default=None,
-                 required=False,
-                 help=None,
-                 metavar=None):
-        super(_AppendConstAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            nargs=0,
-            const=const,
-            default=default,
-            required=required,
-            help=help,
-            metavar=metavar)
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        items = _copy.copy(_ensure_value(namespace, self.dest, []))
-        items.append(self.const)
-        setattr(namespace, self.dest, items)
-
-
-class _CountAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 dest,
-                 default=None,
-                 required=False,
-                 help=None):
-        super(_CountAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            nargs=0,
-            default=default,
-            required=required,
-            help=help)
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        new_count = _ensure_value(namespace, self.dest, 0) + 1
-        setattr(namespace, self.dest, new_count)
-
-
-class _HelpAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 dest=SUPPRESS,
-                 default=SUPPRESS,
-                 help=None):
-        super(_HelpAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            default=default,
-            nargs=0,
-            help=help)
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        parser.print_help()
-        parser.exit()
-
-
-class _VersionAction(Action):
-
-    def __init__(self,
-                 option_strings,
-                 version=None,
-                 dest=SUPPRESS,
-                 default=SUPPRESS,
-                 help=None):
-        super(_VersionAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            default=default,
-            nargs=0,
-            help=help)
-        self.version = version
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        version = self.version
-        if version is None:
-            version = parser.version
-        formatter = parser._get_formatter()
-        formatter.add_text(version)
-        parser.exit(message=formatter.format_help())
-
-
-class _SubParsersAction(Action):
-
-    class _ChoicesPseudoAction(Action):
-
-        def __init__(self, name, help):
-            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
-            sup.__init__(option_strings=[], dest=name, help=help)
-
-    def __init__(self,
-                 option_strings,
-                 prog,
-                 parser_class,
-                 dest=SUPPRESS,
-                 help=None,
-                 metavar=None):
-
-        self._prog_prefix = prog
-        self._parser_class = parser_class
-        self._name_parser_map = {}
-        self._choices_actions = []
-
-        super(_SubParsersAction, self).__init__(
-            option_strings=option_strings,
-            dest=dest,
-            nargs=PARSER,
-            choices=self._name_parser_map,
-            help=help,
-            metavar=metavar)
-
-    def add_parser(self, name, **kwargs):
-        # set prog from the existing prefix
-        if kwargs.get('prog') is None:
-            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
-
-        # create a pseudo-action to hold the choice help
-        if 'help' in kwargs:
-            help = kwargs.pop('help')
-            choice_action = self._ChoicesPseudoAction(name, help)
-            self._choices_actions.append(choice_action)
-
-        # create the parser and add it to the map
-        parser = self._parser_class(**kwargs)
-        self._name_parser_map[name] = parser
-        return parser
-
-    def _get_subactions(self):
-        return self._choices_actions
-
-    def __call__(self, parser, namespace, values, option_string=None):
-        parser_name = values[0]
-        arg_strings = values[1:]
-
-        # set the parser name if requested
-        if self.dest is not SUPPRESS:
-            setattr(namespace, self.dest, parser_name)
-
-        # select the parser
-        try:
-            parser = self._name_parser_map[parser_name]
-        except KeyError:
-            tup = parser_name, ', '.join(self._name_parser_map)
-            msg = _('unknown parser %r (choices: %s)' % tup)
-            raise ArgumentError(self, msg)
-
-        # parse all the remaining options into the namespace
-        parser.parse_args(arg_strings, namespace)
-
-
-# ==============
-# Type classes
-# ==============
-
-class FileType(object):
-    """Factory for creating file object types
-
-    Instances of FileType are typically passed as type= arguments to the
-    ArgumentParser add_argument() method.
-
-    Keyword Arguments:
-        - mode -- A string indicating how the file is to be opened. Accepts the
-            same values as the builtin open() function.
-        - bufsize -- The file's desired buffer size. Accepts the same values as
-            the builtin open() function.
-    """
-
-    def __init__(self, mode='r', bufsize=None):
-        self._mode = mode
-        self._bufsize = bufsize
-
-    def __call__(self, string):
-        # the special argument "-" means sys.std{in,out}
-        if string == '-':
-            if 'r' in self._mode:
-                return _sys.stdin
-            elif 'w' in self._mode:
-                return _sys.stdout
-            else:
-                msg = _('argument "-" with mode %r' % self._mode)
-                raise ValueError(msg)
-
-        # all other arguments are used as file names
-        if self._bufsize:
-            return open(string, self._mode, self._bufsize)
-        else:
-            return open(string, self._mode)
-
-    def __repr__(self):
-        args = [self._mode, self._bufsize]
-        args_str = ', '.join([repr(arg) for arg in args if arg is not None])
-        return '%s(%s)' % (type(self).__name__, args_str)
-
-# ===========================
-# Optional and Positional Parsing
-# ===========================
-
-class Namespace(_AttributeHolder):
-    """Simple object for storing attributes.
-
-    Implements equality by attribute names and values, and provides a simple
-    string representation.
-    """
-
-    def __init__(self, **kwargs):
-        for name in kwargs:
-            setattr(self, name, kwargs[name])
-
-    def __eq__(self, other):
-        return vars(self) == vars(other)
-
-    def __ne__(self, other):
-        return not (self == other)
-
-    def __contains__(self, key):
-        return key in self.__dict__
-
-
-class _ActionsContainer(object):
-
-    def __init__(self,
-                 description,
-                 prefix_chars,
-                 argument_default,
-                 conflict_handler):
-        super(_ActionsContainer, self).__init__()
-
-        self.description = description
-        self.argument_default = argument_default
-        self.prefix_chars = prefix_chars
-        self.conflict_handler = conflict_handler
-
-        # set up registries
-        self._registries = {}
-
-        # register actions
-        self.register('action', None, _StoreAction)
-        self.register('action', 'store', _StoreAction)
-        self.register('action', 'store_const', _StoreConstAction)
-        self.register('action', 'store_true', _StoreTrueAction)
-        self.register('action', 'store_false', _StoreFalseAction)
-        self.register('action', 'append', _AppendAction)
-        self.register('action', 'append_const', _AppendConstAction)
-        self.register('action', 'count', _CountAction)
-        self.register('action', 'help', _HelpAction)
-        self.register('action', 'version', _VersionAction)
-        self.register('action', 'parsers', _SubParsersAction)
-
-        # raise an exception if the conflict handler is invalid
-        self._get_handler()
-
-        # action storage
-        self._actions = []
-        self._option_string_actions = {}
-
-        # groups
-        self._action_groups = []
-        self._mutually_exclusive_groups = []
-
-        # defaults storage
-        self._defaults = {}
-
-        # determines whether an "option" looks like a negative number
-        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
-
-        # whether or not there are any optionals that look like negative
-        # numbers -- uses a list so it can be shared and edited
-        self._has_negative_number_optionals = []
-
-    # ====================
-    # Registration methods
-    # ====================
-    def register(self, registry_name, value, object):
-        registry = self._registries.setdefault(registry_name, {})
-        registry[value] = object
-
-    def _registry_get(self, registry_name, value, default=None):
-        return self._registries[registry_name].get(value, default)
-
-    # ==================================
-    # Namespace default accessor methods
-    # ==================================
-    def set_defaults(self, **kwargs):
-        self._defaults.update(kwargs)
-
-        # if these defaults match any existing arguments, replace
-        # the previous default on the object with the new one
-        for action in self._actions:
-            if action.dest in kwargs:
-                action.default = kwargs[action.dest]
-
-    def get_default(self, dest):
-        for action in self._actions:
-            if action.dest == dest and action.default is not None:
-                return action.default
-        return self._defaults.get(dest, None)
-
-
-    # =======================
-    # Adding argument actions
-    # =======================
-    def add_argument(self, *args, **kwargs):
-        """
-        add_argument(dest, ..., name=value, ...)
-        add_argument(option_string, option_string, ..., name=value, ...)
-        """
-
-        # if no positional args are supplied or only one is supplied and
-        # it doesn't look like an option string, parse a positional
-        # argument
-        chars = self.prefix_chars
-        if not args or len(args) == 1 and args[0][0] not in chars:
-            if args and 'dest' in kwargs:
-                raise ValueError('dest supplied twice for positional argument')
-            kwargs = self._get_positional_kwargs(*args, **kwargs)
-
-        # otherwise, we're adding an optional argument
-        else:
-            kwargs = self._get_optional_kwargs(*args, **kwargs)
-
-        # if no default was supplied, use the parser-level default
-        if 'default' not in kwargs:
-            dest = kwargs['dest']
-            if dest in self._defaults:
-                kwargs['default'] = self._defaults[dest]
-            elif self.argument_default is not None:
-                kwargs['default'] = self.argument_default
-
-        # create the action object, and add it to the parser
-        action_class = self._pop_action_class(kwargs)
-        if not _callable(action_class):
-            raise ValueError('unknown action "%s"' % action_class)
-        action = action_class(**kwargs)
-
-        # raise an error if the action type is not callable
-        type_func = self._registry_get('type', action.type, action.type)
-        if not _callable(type_func):
-            raise ValueError('%r is not callable' % type_func)
-
-        return self._add_action(action)
-
-    def add_argument_group(self, *args, **kwargs):
-        group = _ArgumentGroup(self, *args, **kwargs)
-        self._action_groups.append(group)
-        return group
-
-    def add_mutually_exclusive_group(self, **kwargs):
-        group = _MutuallyExclusiveGroup(self, **kwargs)
-        self._mutually_exclusive_groups.append(group)
-        return group
-
-    def _add_action(self, action):
-        # resolve any conflicts
-        self._check_conflict(action)
-
-        # add to actions list
-        self._actions.append(action)
-        action.container = self
-
-        # index the action by any option strings it has
-        for option_string in action.option_strings:
-            self._option_string_actions[option_string] = action
-
-        # set the flag if any option strings look like negative numbers
-        for option_string in action.option_strings:
-            if self._negative_number_matcher.match(option_string):
-                if not self._has_negative_number_optionals:
-                    self._has_negative_number_optionals.append(True)
-
-        # return the created action
-        return action
-
-    def _remove_action(self, action):
-        self._actions.remove(action)
-
-    def _add_container_actions(self, container):
-        # collect groups by titles
-        title_group_map = {}
-        for group in self._action_groups:
-            if group.title in title_group_map:
-                msg = _('cannot merge actions - two groups are named %r')
-                raise ValueError(msg % (group.title))
-            title_group_map[group.title] = group
-
-        # map each action to its group
-        group_map = {}
-        for group in container._action_groups:
-
-            # if a group with the title exists, use that, otherwise
-            # create a new group matching the container's group
-            if group.title not in title_group_map:
-                title_group_map[group.title] = self.add_argument_group(
-                    title=group.title,
-                    description=group.description,
-                    conflict_handler=group.conflict_handler)
-
-            # map the actions to their new group
-            for action in group._group_actions:
-                group_map[action] = title_group_map[group.title]
-
-        # add container's mutually exclusive groups
-        # NOTE: if add_mutually_exclusive_group ever gains title= and
-        # description= then this code will need to be expanded as above
-        for group in container._mutually_exclusive_groups:
-            mutex_group = self.add_mutually_exclusive_group(
-                required=group.required)
-
-            # map the actions to their new mutex group
-            for action in group._group_actions:
-                group_map[action] = mutex_group
-
-        # add all actions to this container or their group
-        for action in container._actions:
-            group_map.get(action, self)._add_action(action)
-
-    def _get_positional_kwargs(self, dest, **kwargs):
-        # make sure required is not specified
-        if 'required' in kwargs:
-            msg = _("'required' is an invalid argument for positionals")
-            raise TypeError(msg)
-
-        # mark positional arguments as required if at least one is
-        # always required
-        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
-            kwargs['required'] = True
-        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
-            kwargs['required'] = True
-
-        # return the keyword arguments with no option strings
-        return dict(kwargs, dest=dest, option_strings=[])
-
-    def _get_optional_kwargs(self, *args, **kwargs):
-        # determine short and long option strings
-        option_strings = []
-        long_option_strings = []
-        for option_string in args:
-            # error on strings that don't start with an appropriate prefix
-            if not option_string[0] in self.prefix_chars:
-                msg = _('invalid option string %r: '
-                        'must start with a character %r')
-                tup = option_string, self.prefix_chars
-                raise ValueError(msg % tup)
-
-            # strings starting with two prefix characters are long options
-            option_strings.append(option_string)
-            if option_string[0] in self.prefix_chars:
-                if len(option_string) > 1:
-                    if option_string[1] in self.prefix_chars:
-                        long_option_strings.append(option_string)
-
-        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
-        dest = kwargs.pop('dest', None)
-        if dest is None:
-            if long_option_strings:
-                dest_option_string = long_option_strings[0]
-            else:
-                dest_option_string = option_strings[0]
-            dest = dest_option_string.lstrip(self.prefix_chars)
-            if not dest:
-                msg = _('dest= is required for options like %r')
-                raise ValueError(msg % option_string)
-            dest = dest.replace('-', '_')
-
-        # return the updated keyword arguments
-        return dict(kwargs, dest=dest, option_strings=option_strings)
-
-    def _pop_action_class(self, kwargs, default=None):
-        action = kwargs.pop('action', default)
-        return self._registry_get('action', action, action)
-
-    def _get_handler(self):
-        # determine function from conflict handler string
-        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
-        try:
-            return getattr(self, handler_func_name)
-        except AttributeError:
-            msg = _('invalid conflict_resolution value: %r')
-            raise ValueError(msg % self.conflict_handler)
-
-    def _check_conflict(self, action):
-
-        # find all options that conflict with this option
-        confl_optionals = []
-        for option_string in action.option_strings:
-            if option_string in self._option_string_actions:
-                confl_optional = self._option_string_actions[option_string]
-                confl_optionals.append((option_string, confl_optional))
-
-        # resolve any conflicts
-        if confl_optionals:
-            conflict_handler = self._get_handler()
-            conflict_handler(action, confl_optionals)
-
-    def _handle_conflict_error(self, action, conflicting_actions):
-        message = _('conflicting option string(s): %s')
-        conflict_string = ', '.join([option_string
-                                     for option_string, action
-                                     in conflicting_actions])
-        raise ArgumentError(action, message % conflict_string)
-
-    def _handle_conflict_resolve(self, action, conflicting_actions):
-
-        # remove all conflicting options
-        for option_string, action in conflicting_actions:
-
-            # remove the conflicting option
-            action.option_strings.remove(option_string)
-            self._option_string_actions.pop(option_string, None)
-
-            # if the option now has no option string, remove it from the
-            # container holding it
-            if not action.option_strings:
-                action.container._remove_action(action)
-
-
-class _ArgumentGroup(_ActionsContainer):
-
-    def __init__(self, container, title=None, description=None, **kwargs):
-        # add any missing keyword arguments by checking the container
-        update = kwargs.setdefault
-        update('conflict_handler', container.conflict_handler)
-        update('prefix_chars', container.prefix_chars)
-        update('argument_default', container.argument_default)
-        super_init = super(_ArgumentGroup, self).__init__
-        super_init(description=description, **kwargs)
-
-        # group attributes
-        self.title = title
-        self._group_actions = []
-
-        # share most attributes with the container
-        self._registries = container._registries
-        self._actions = container._actions
-        self._option_string_actions = container._option_string_actions
-        self._defaults = container._defaults
-        self._has_negative_number_optionals = \
-            container._has_negative_number_optionals
-
-    def _add_action(self, action):
-        action = super(_ArgumentGroup, self)._add_action(action)
-        self._group_actions.append(action)
-        return action
-
-    def _remove_action(self, action):
-        super(_ArgumentGroup, self)._remove_action(action)
-        self._group_actions.remove(action)
-
-
-class _MutuallyExclusiveGroup(_ArgumentGroup):
-
-    def __init__(self, container, required=False):
-        super(_MutuallyExclusiveGroup, self).__init__(container)
-        self.required = required
-        self._container = container
-
-    def _add_action(self, action):
-        if action.required:
-            msg = _('mutually exclusive arguments must be optional')
-            raise ValueError(msg)
-        action = self._container._add_action(action)
-        self._group_actions.append(action)
-        return action
-
-    def _remove_action(self, action):
-        self._container._remove_action(action)
-        self._group_actions.remove(action)
-
-
-class ArgumentParser(_AttributeHolder, _ActionsContainer):
-    """Object for parsing command line strings into Python objects.
-
-    Keyword Arguments:
-        - prog -- The name of the program (default: sys.argv[0])
-        - usage -- A usage message (default: auto-generated from arguments)
-        - description -- A description of what the program does
-        - epilog -- Text following the argument descriptions
-        - parents -- Parsers whose arguments should be copied into this one
-        - formatter_class -- HelpFormatter class for printing help messages
-        - prefix_chars -- Characters that prefix optional arguments
-        - fromfile_prefix_chars -- Characters that prefix files containing
-            additional arguments
-        - argument_default -- The default value for all arguments
-        - conflict_handler -- String indicating how to handle conflicts
-        - add_help -- Add a -h/-help option
-    """
-
-    def __init__(self,
-                 prog=None,
-                 usage=None,
-                 description=None,
-                 epilog=None,
-                 version=None,
-                 parents=[],
-                 formatter_class=HelpFormatter,
-                 prefix_chars='-',
-                 fromfile_prefix_chars=None,
-                 argument_default=None,
-                 conflict_handler='error',
-                 add_help=True):
-
-        if version is not None:
-            import warnings
-            warnings.warn(
-                """The "version" argument to ArgumentParser is deprecated. """
-                """Please use """
-                """"add_argument(..., action='version', version="N", ...)" """
-                """instead""", DeprecationWarning)
-
-        superinit = super(ArgumentParser, self).__init__
-        superinit(description=description,
-                  prefix_chars=prefix_chars,
-                  argument_default=argument_default,
-                  conflict_handler=conflict_handler)
-
-        # default setting for prog
-        if prog is None:
-            prog = _os.path.basename(_sys.argv[0])
-
-        self.prog = prog
-        self.usage = usage
-        self.epilog = epilog
-        self.version = version
-        self.formatter_class = formatter_class
-        self.fromfile_prefix_chars = fromfile_prefix_chars
-        self.add_help = add_help
-
-        add_group = self.add_argument_group
-        self._positionals = add_group(_('positional arguments'))
-        self._optionals = add_group(_('optional arguments'))
-        self._subparsers = None
-
-        # register types
-        def identity(string):
-            return string
-        self.register('type', None, identity)
-
-        # add help and version arguments if necessary
-        # (using explicit default to override global argument_default)
-        if self.add_help:
-            self.add_argument(
-                '-h', '--help', action='help', default=SUPPRESS,
-                help=_('show this help message and exit'))
-        if self.version:
-            self.add_argument(
-                '-v', '--version', action='version', default=SUPPRESS,
-                version=self.version,
-                help=_("show program's version number and exit"))
-
-        # add parent arguments and defaults
-        for parent in parents:
-            self._add_container_actions(parent)
-            try:
-                defaults = parent._defaults
-            except AttributeError:
-                pass
-            else:
-                self._defaults.update(defaults)
-
-    # =======================
-    # Pretty __repr__ methods
-    # =======================
-    def _get_kwargs(self):
-        names = [
-            'prog',
-            'usage',
-            'description',
-            'version',
-            'formatter_class',
-            'conflict_handler',
-            'add_help',
-        ]
-        return [(name, getattr(self, name)) for name in names]
-
-    # ==================================
-    # Optional/Positional adding methods
-    # ==================================
-    def add_subparsers(self, **kwargs):
-        if self._subparsers is not None:
-            self.error(_('cannot have multiple subparser arguments'))
-
-        # add the parser class to the arguments if it's not present
-        kwargs.setdefault('parser_class', type(self))
-
-        if 'title' in kwargs or 'description' in kwargs:
-            title = _(kwargs.pop('title', 'subcommands'))
-            description = _(kwargs.pop('description', None))
-            self._subparsers = self.add_argument_group(title, description)
-        else:
-            self._subparsers = self._positionals
-
-        # prog defaults to the usage message of this parser, skipping
-        # optional arguments and with no "usage:" prefix
-        if kwargs.get('prog') is None:
-            formatter = self._get_formatter()
-            positionals = self._get_positional_actions()
-            groups = self._mutually_exclusive_groups
-            formatter.add_usage(self.usage, positionals, groups, '')
-            kwargs['prog'] = formatter.format_help().strip()
-
-        # create the parsers action and add it to the positionals list
-        parsers_class = self._pop_action_class(kwargs, 'parsers')
-        action = parsers_class(option_strings=[], **kwargs)
-        self._subparsers._add_action(action)
-
-        # return the created parsers action
-        return action
-
-    def _add_action(self, action):
-        if action.option_strings:
-            self._optionals._add_action(action)
-        else:
-            self._positionals._add_action(action)
-        return action
-
-    def _get_optional_actions(self):
-        return [action
-                for action in self._actions
-                if action.option_strings]
-
-    def _get_positional_actions(self):
-        return [action
-                for action in self._actions
-                if not action.option_strings]
-
-    # =====================================
-    # Command line argument parsing methods
-    # =====================================
-    def parse_args(self, args=None, namespace=None):
-        args, argv = self.parse_known_args(args, namespace)
-        if argv:
-            msg = _('unrecognized arguments: %s')
-            self.error(msg % ' '.join(argv))
-        return args
-
-    def parse_known_args(self, args=None, namespace=None):
-        # args default to the system args
-        if args is None:
-            args = _sys.argv[1:]
-
-        # default Namespace built from parser defaults
-        if namespace is None:
-            namespace = Namespace()
-
-        # add any action defaults that aren't present
-        for action in self._actions:
-            if action.dest is not SUPPRESS:
-                if not hasattr(namespace, action.dest):
-                    if action.default is not SUPPRESS:
-                        default = action.default
-                        if isinstance(action.default, _basestring):
-                            default = self._get_value(action, default)
-                        setattr(namespace, action.dest, default)
-
-        # add any parser defaults that aren't present
-        for dest in self._defaults:
-            if not hasattr(namespace, dest):
-                setattr(namespace, dest, self._defaults[dest])
-
-        # parse the arguments and exit if there are any errors
-        try:
-            return self._parse_known_args(args, namespace)
-        except ArgumentError:
-            err = _sys.exc_info()[1]
-            self.error(str(err))
-
-    def _parse_known_args(self, arg_strings, namespace):
-        # replace arg strings that are file references
-        if self.fromfile_prefix_chars is not None:
-            arg_strings = self._read_args_from_files(arg_strings)
-
-        # map all mutually exclusive arguments to the other arguments
-        # they can't occur with
-        action_conflicts = {}
-        for mutex_group in self._mutually_exclusive_groups:
-            group_actions = mutex_group._group_actions
-            for i, mutex_action in enumerate(mutex_group._group_actions):
-                conflicts = action_conflicts.setdefault(mutex_action, [])
-                conflicts.extend(group_actions[:i])
-                conflicts.extend(group_actions[i + 1:])
-
-        # find all option indices, and determine the arg_string_pattern
-        # which has an 'O' if there is an option at an index,
-        # an 'A' if there is an argument, or a '-' if there is a '--'
-        option_string_indices = {}
-        arg_string_pattern_parts = []
-        arg_strings_iter = iter(arg_strings)
-        for i, arg_string in enumerate(arg_strings_iter):
-
-            # all args after -- are non-options
-            if arg_string == '--':
-                arg_string_pattern_parts.append('-')
-                for arg_string in arg_strings_iter:
-                    arg_string_pattern_parts.append('A')
-
-            # otherwise, add the arg to the arg strings
-            # and note the index if it was an option
-            else:
-                option_tuple = self._parse_optional(arg_string)
-                if option_tuple is None:
-                    pattern = 'A'
-                else:
-                    option_string_indices[i] = option_tuple
-                    pattern = 'O'
-                arg_string_pattern_parts.append(pattern)
-
-        # join the pieces together to form the pattern
-        arg_strings_pattern = ''.join(arg_string_pattern_parts)
-
-        # converts arg strings to the appropriate and then takes the action
-        seen_actions = _set()
-        seen_non_default_actions = _set()
-
-        def take_action(action, argument_strings, option_string=None):
-            seen_actions.add(action)
-            argument_values = self._get_values(action, argument_strings)
-
-            # error if this argument is not allowed with other previously
-            # seen arguments, assuming that actions that use the default
-            # value don't really count as "present"
-            if argument_values is not action.default:
-                seen_non_default_actions.add(action)
-                for conflict_action in action_conflicts.get(action, []):
-                    if conflict_action in seen_non_default_actions:
-                        msg = _('not allowed with argument %s')
-                        action_name = _get_action_name(conflict_action)
-                        raise ArgumentError(action, msg % action_name)
-
-            # take the action if we didn't receive a SUPPRESS value
-            # (e.g. from a default)
-            if argument_values is not SUPPRESS:
-                action(self, namespace, argument_values, option_string)
-
-        # function to convert arg_strings into an optional action
-        def consume_optional(start_index):
-
-            # get the optional identified at this index
-            option_tuple = option_string_indices[start_index]
-            action, option_string, explicit_arg = option_tuple
-
-            # identify additional optionals in the same arg string
-            # (e.g. -xyz is the same as -x -y -z if no args are required)
-            match_argument = self._match_argument
-            action_tuples = []
-            while True:
-
-                # if we found no optional action, skip it
-                if action is None:
-                    extras.append(arg_strings[start_index])
-                    return start_index + 1
-
-                # if there is an explicit argument, try to match the
-                # optional's string arguments to only this
-                if explicit_arg is not None:
-                    arg_count = match_argument(action, 'A')
-
-                    # if the action is a single-dash option and takes no
-                    # arguments, try to parse more single-dash options out
-                    # of the tail of the option string
-                    chars = self.prefix_chars
-                    if arg_count == 0 and option_string[1] not in chars:
-                        action_tuples.append((action, [], option_string))
-                        for char in self.prefix_chars:
-                            option_string = char + explicit_arg[0]
-                            explicit_arg = explicit_arg[1:] or None
-                            optionals_map = self._option_string_actions
-                            if option_string in optionals_map:
-                                action = optionals_map[option_string]
-                                break
-                        else:
-                            msg = _('ignored explicit argument %r')
-                            raise ArgumentError(action, msg % explicit_arg)
-
-                    # if the action expect exactly one argument, we've
-                    # successfully matched the option; exit the loop
-                    elif arg_count == 1:
-                        stop = start_index + 1
-                        args = [explicit_arg]
-                        action_tuples.append((action, args, option_string))
-                        break
-
-                    # error if a double-dash option did not use the
-                    # explicit argument
-                    else:
-                        msg = _('ignored explicit argument %r')
-                        raise ArgumentError(action, msg % explicit_arg)
-
-                # if there is no explicit argument, try to match the
-                # optional's string arguments with the following strings
-                # if successful, exit the loop
-                else:
-                    start = start_index + 1
-                    selected_patterns = arg_strings_pattern[start:]
-                    arg_count = match_argument(action, selected_patterns)
-                    stop = start + arg_count
-                    args = arg_strings[start:stop]
-                    action_tuples.append((action, args, option_string))
-                    break
-
-            # add the Optional to the list and return the index at which
-            # the Optional's string args stopped
-            assert action_tuples
-            for action, args, option_string in action_tuples:
-                take_action(action, args, option_string)
-            return stop
-
-        # the list of Positionals left to be parsed; this is modified
-        # by consume_positionals()
-        positionals = self._get_positional_actions()
-
-        # function to convert arg_strings into positional actions
-        def consume_positionals(start_index):
-            # match as many Positionals as possible
-            match_partial = self._match_arguments_partial
-            selected_pattern = arg_strings_pattern[start_index:]
-            arg_counts = match_partial(positionals, selected_pattern)
-
-            # slice off the appropriate arg strings for each Positional
-            # and add the Positional and its args to the list
-            for action, arg_count in zip(positionals, arg_counts):
-                args = arg_strings[start_index: start_index + arg_count]
-                start_index += arg_count
-                take_action(action, args)
-
-            # slice off the Positionals that we just parsed and return the
-            # index at which the Positionals' string args stopped
-            positionals[:] = positionals[len(arg_counts):]
-            return start_index
-
-        # consume Positionals and Optionals alternately, until we have
-        # passed the last option string
-        extras = []
-        start_index = 0
-        if option_string_indices:
-            max_option_string_index = max(option_string_indices)
-        else:
-            max_option_string_index = -1
-        while start_index <= max_option_string_index:
-
-            # consume any Positionals preceding the next option
-            next_option_string_index = min([
-                index
-                for index in option_string_indices
-                if index >= start_index])
-            if start_index != next_option_string_index:
-                positionals_end_index = consume_positionals(start_index)
-
-                # only try to parse the next optional if we didn't consume
-                # the option string during the positionals parsing
-                if positionals_end_index > start_index:
-                    start_index = positionals_end_index
-                    continue
-                else:
-                    start_index = positionals_end_index
-
-            # if we consumed all the positionals we could and we're not
-            # at the index of an option string, there were extra arguments
-            if start_index not in option_string_indices:
-                strings = arg_strings[start_index:next_option_string_index]
-                extras.extend(strings)
-                start_index = next_option_string_index
-
-            # consume the next optional and any arguments for it
-            start_index = consume_optional(start_index)
-
-        # consume any positionals following the last Optional
-        stop_index = consume_positionals(start_index)
-
-        # if we didn't consume all the argument strings, there were extras
-        extras.extend(arg_strings[stop_index:])
-
-        # if we didn't use all the Positional objects, there were too few
-        # arg strings supplied.
-        if positionals:
-            self.error(_('too few arguments'))
-
-        # make sure all required actions were present
-        for action in self._actions:
-            if action.required:
-                if action not in seen_actions:
-                    name = _get_action_name(action)
-                    self.error(_('argument %s is required') % name)
-
-        # make sure all required groups had one option present
-        for group in self._mutually_exclusive_groups:
-            if group.required:
-                for action in group._group_actions:
-                    if action in seen_non_default_actions:
-                        break
-
-                # if no actions were used, report the error
-                else:
-                    names = [_get_action_name(action)
-                             for action in group._group_actions
-                             if action.help is not SUPPRESS]
-                    msg = _('one of the arguments %s is required')
-                    self.error(msg % ' '.join(names))
-
-        # return the updated namespace and the extra arguments
-        return namespace, extras
-
-    def _read_args_from_files(self, arg_strings):
-        # expand arguments referencing files
-        new_arg_strings = []
-        for arg_string in arg_strings:
-
-            # for regular arguments, just add them back into the list
-            if arg_string[0] not in self.fromfile_prefix_chars:
-                new_arg_strings.append(arg_string)
-
-            # replace arguments referencing files with the file content
-            else:
-                try:
-                    args_file = open(arg_string[1:])
-                    try:
-                        arg_strings = []
-                        for arg_line in args_file.read().splitlines():
-                            for arg in self.convert_arg_line_to_args(arg_line):
-                                arg_strings.append(arg)
-                        arg_strings = self._read_args_from_files(arg_strings)
-                        new_arg_strings.extend(arg_strings)
-                    finally:
-                        args_file.close()
-                except IOError:
-                    err = _sys.exc_info()[1]
-                    self.error(str(err))
-
-        # return the modified argument list
-        return new_arg_strings
-
-    def convert_arg_line_to_args(self, arg_line):
-        return [arg_line]
-
-    def _match_argument(self, action, arg_strings_pattern):
-        # match the pattern for this action to the arg strings
-        nargs_pattern = self._get_nargs_pattern(action)
-        match = _re.match(nargs_pattern, arg_strings_pattern)
-
-        # raise an exception if we weren't able to find a match
-        if match is None:
-            nargs_errors = {
-                None: _('expected one argument'),
-                OPTIONAL: _('expected at most one argument'),
-                ONE_OR_MORE: _('expected at least one argument'),
-            }
-            default = _('expected %s argument(s)') % action.nargs
-            msg = nargs_errors.get(action.nargs, default)
-            raise ArgumentError(action, msg)
-
-        # return the number of arguments matched
-        return len(match.group(1))
-
-    def _match_arguments_partial(self, actions, arg_strings_pattern):
-        # progressively shorten the actions list by slicing off the
-        # final actions until we find a match
-        result = []
-        for i in range(len(actions), 0, -1):
-            actions_slice = actions[:i]
-            pattern = ''.join([self._get_nargs_pattern(action)
-                               for action in actions_slice])
-            match = _re.match(pattern, arg_strings_pattern)
-            if match is not None:
-                result.extend([len(string) for string in match.groups()])
-                break
-
-        # return the list of arg string counts
-        return result
-
-    def _parse_optional(self, arg_string):
-        # if it's an empty string, it was meant to be a positional
-        if not arg_string:
-            return None
-
-        # if it doesn't start with a prefix, it was meant to be positional
-        if not arg_string[0] in self.prefix_chars:
-            return None
-
-        # if the option string is present in the parser, return the action
-        if arg_string in self._option_string_actions:
-            action = self._option_string_actions[arg_string]
-            return action, arg_string, None
-
-        # if it's just a single character, it was meant to be positional
-        if len(arg_string) == 1:
-            return None
-
-        # if the option string before the "=" is present, return the action
-        if '=' in arg_string:
-            option_string, explicit_arg = arg_string.split('=', 1)
-            if option_string in self._option_string_actions:
-                action = self._option_string_actions[option_string]
-                return action, option_string, explicit_arg
-
-        # search through all possible prefixes of the option string
-        # and all actions in the parser for possible interpretations
-        option_tuples = self._get_option_tuples(arg_string)
-
-        # if multiple actions match, the option string was ambiguous
-        if len(option_tuples) > 1:
-            options = ', '.join([option_string
-                for action, option_string, explicit_arg in option_tuples])
-            tup = arg_string, options
-            self.error(_('ambiguous option: %s could match %s') % tup)
-
-        # if exactly one action matched, this segmentation is good,
-        # so return the parsed action
-        elif len(option_tuples) == 1:
-            option_tuple, = option_tuples
-            return option_tuple
-
-        # if it was not found as an option, but it looks like a negative
-        # number, it was meant to be positional
-        # unless there are negative-number-like options
-        if self._negative_number_matcher.match(arg_string):
-            if not self._has_negative_number_optionals:
-                return None
-
-        # if it contains a space, it was meant to be a positional
-        if ' ' in arg_string:
-            return None
-
-        # it was meant to be an optional but there is no such option
-        # in this parser (though it might be a valid option in a subparser)
-        return None, arg_string, None
-
-    def _get_option_tuples(self, option_string):
-        result = []
-
-        # option strings starting with two prefix characters are only
-        # split at the '='
-        chars = self.prefix_chars
-        if option_string[0] in chars and option_string[1] in chars:
-            if '=' in option_string:
-                option_prefix, explicit_arg = option_string.split('=', 1)
-            else:
-                option_prefix = option_string
-                explicit_arg = None
-            for option_string in self._option_string_actions:
-                if option_string.startswith(option_prefix):
-                    action = self._option_string_actions[option_string]
-                    tup = action, option_string, explicit_arg
-                    result.append(tup)
-
-        # single character options can be concatenated with their arguments
-        # but multiple character options always have to have their argument
-        # separate
-        elif option_string[0] in chars and option_string[1] not in chars:
-            option_prefix = option_string
-            explicit_arg = None
-            short_option_prefix = option_string[:2]
-            short_explicit_arg = option_string[2:]
-
-            for option_string in self._option_string_actions:
-                if option_string == short_option_prefix:
-                    action = self._option_string_actions[option_string]
-                    tup = action, option_string, short_explicit_arg
-                    result.append(tup)
-                elif option_string.startswith(option_prefix):
-                    action = self._option_string_actions[option_string]
-                    tup = action, option_string, explicit_arg
-                    result.append(tup)
-
-        # shouldn't ever get here
-        else:
-            self.error(_('unexpected option string: %s') % option_string)
-
-        # return the collected option tuples
-        return result
-
-    def _get_nargs_pattern(self, action):
-        # in all examples below, we have to allow for '--' args
-        # which are represented as '-' in the pattern
-        nargs = action.nargs
-
-        # the default (None) is assumed to be a single argument
-        if nargs is None:
-            nargs_pattern = '(-*A-*)'
-
-        # allow zero or one arguments
-        elif nargs == OPTIONAL:
-            nargs_pattern = '(-*A?-*)'
-
-        # allow zero or more arguments
-        elif nargs == ZERO_OR_MORE:
-            nargs_pattern = '(-*[A-]*)'
-
-        # allow one or more arguments
-        elif nargs == ONE_OR_MORE:
-            nargs_pattern = '(-*A[A-]*)'
-
-        # allow any number of options or arguments
-        elif nargs == REMAINDER:
-            nargs_pattern = '([-AO]*)'
-
-        # allow one argument followed by any number of options or arguments
-        elif nargs == PARSER:
-            nargs_pattern = '(-*A[-AO]*)'
-
-        # all others should be integers
-        else:
-            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
-
-        # if this is an optional action, -- is not allowed
-        if action.option_strings:
-            nargs_pattern = nargs_pattern.replace('-*', '')
-            nargs_pattern = nargs_pattern.replace('-', '')
-
-        # return the pattern
-        return nargs_pattern
-
-    # ========================
-    # Value conversion methods
-    # ========================
-    def _get_values(self, action, arg_strings):
-        # for everything but PARSER args, strip out '--'
-        if action.nargs not in [PARSER, REMAINDER]:
-            arg_strings = [s for s in arg_strings if s != '--']
-
-        # optional argument produces a default when not present
-        if not arg_strings and action.nargs == OPTIONAL:
-            if action.option_strings:
-                value = action.const
-            else:
-                value = action.default
-            if isinstance(value, _basestring):
-                value = self._get_value(action, value)
-                self._check_value(action, value)
-
-        # when nargs='*' on a positional, if there were no command-line
-        # args, use the default if it is anything other than None
-        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
-              not action.option_strings):
-            if action.default is not None:
-                value = action.default
-            else:
-                value = arg_strings
-            self._check_value(action, value)
-
-        # single argument or optional argument produces a single value
-        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
-            arg_string, = arg_strings
-            value = self._get_value(action, arg_string)
-            self._check_value(action, value)
-
-        # REMAINDER arguments convert all values, checking none
-        elif action.nargs == REMAINDER:
-            value = [self._get_value(action, v) for v in arg_strings]
-
-        # PARSER arguments convert all values, but check only the first
-        elif action.nargs == PARSER:
-            value = [self._get_value(action, v) for v in arg_strings]
-            self._check_value(action, value[0])
-
-        # all other types of nargs produce a list
-        else:
-            value = [self._get_value(action, v) for v in arg_strings]
-            for v in value:
-                self._check_value(action, v)
-
-        # return the converted value
-        return value
-
-    def _get_value(self, action, arg_string):
-        type_func = self._registry_get('type', action.type, action.type)
-        if not _callable(type_func):
-            msg = _('%r is not callable')
-            raise ArgumentError(action, msg % type_func)
-
-        # convert the value to the appropriate type
-        try:
-            result = type_func(arg_string)
-
-        # ArgumentTypeErrors indicate errors
-        except ArgumentTypeError:
-            name = getattr(action.type, '__name__', repr(action.type))
-            msg = str(_sys.exc_info()[1])
-            raise ArgumentError(action, msg)
-
-        # TypeErrors or ValueErrors also indicate errors
-        except (TypeError, ValueError):
-            name = getattr(action.type, '__name__', repr(action.type))
-            msg = _('invalid %s value: %r')
-            raise ArgumentError(action, msg % (name, arg_string))
-
-        # return the converted value
-        return result
-
-    def _check_value(self, action, value):
-        # converted value must be one of the choices (if specified)
-        if action.choices is not None and value not in action.choices:
-            tup = value, ', '.join(map(repr, action.choices))
-            msg = _('invalid choice: %r (choose from %s)') % tup
-            raise ArgumentError(action, msg)
-
-    # =======================
-    # Help-formatting methods
-    # =======================
-    def format_usage(self):
-        formatter = self._get_formatter()
-        formatter.add_usage(self.usage, self._actions,
-                            self._mutually_exclusive_groups)
-        return formatter.format_help()
-
-    def format_help(self):
-        formatter = self._get_formatter()
-
-        # usage
-        formatter.add_usage(self.usage, self._actions,
-                            self._mutually_exclusive_groups)
-
-        # description
-        formatter.add_text(self.description)
-
-        # positionals, optionals and user-defined groups
-        for action_group in self._action_groups:
-            formatter.start_section(action_group.title)
-            formatter.add_text(action_group.description)
-            formatter.add_arguments(action_group._group_actions)
-            formatter.end_section()
-
-        # epilog
-        formatter.add_text(self.epilog)
-
-        # determine help from format above
-        return formatter.format_help()
-
-    def format_version(self):
-        import warnings
-        warnings.warn(
-            'The format_version method is deprecated -- the "version" '
-            'argument to ArgumentParser is no longer supported.',
-            DeprecationWarning)
-        formatter = self._get_formatter()
-        formatter.add_text(self.version)
-        return formatter.format_help()
-
-    def _get_formatter(self):
-        return self.formatter_class(prog=self.prog)
-
-    # =====================
-    # Help-printing methods
-    # =====================
-    def print_usage(self, file=None):
-        if file is None:
-            file = _sys.stdout
-        self._print_message(self.format_usage(), file)
-
-    def print_help(self, file=None):
-        if file is None:
-            file = _sys.stdout
-        self._print_message(self.format_help(), file)
-
-    def print_version(self, file=None):
-        import warnings
-        warnings.warn(
-            'The print_version method is deprecated -- the "version" '
-            'argument to ArgumentParser is no longer supported.',
-            DeprecationWarning)
-        self._print_message(self.format_version(), file)
-
-    def _print_message(self, message, file=None):
-        if message:
-            if file is None:
-                file = _sys.stderr
-            file.write(message)
-
-    # ===============
-    # Exiting methods
-    # ===============
-    def exit(self, status=0, message=None):
-        if message:
-            self._print_message(message, _sys.stderr)
-        _sys.exit(status)
-
-    def error(self, message):
-        """error(message: string)
-
-        Prints a usage message incorporating the message to stderr and
-        exits.
-
-        If you override this in a subclass, it should not return -- it
-        should either exit or raise an exception.
-        """
-        self.print_usage(_sys.stderr)
-        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
+# Copyright 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy
+# of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Command-line parsing library
+
+This module is an optparse-inspired command-line parsing library that:
+
+    - handles both optional and positional arguments
+    - produces highly informative usage messages
+    - supports parsers that dispatch to sub-parsers
+
+The following is a simple usage example that sums integers from the
+command-line and writes the result to a file::
+
+    parser = argparse.ArgumentParser(
+        description='sum the integers at the command line')
+    parser.add_argument(
+        'integers', metavar='int', nargs='+', type=int,
+        help='an integer to be summed')
+    parser.add_argument(
+        '--log', default=sys.stdout, type=argparse.FileType('w'),
+        help='the file where the sum should be written')
+    args = parser.parse_args()
+    args.log.write('%s' % sum(args.integers))
+    args.log.close()
+
+The module contains the following public classes:
+
+    - ArgumentParser -- The main entry point for command-line parsing. As the
+        example above shows, the add_argument() method is used to populate
+        the parser with actions for optional and positional arguments. Then
+        the parse_args() method is invoked to convert the args at the
+        command-line into an object with attributes.
+
+    - ArgumentError -- The exception raised by ArgumentParser objects when
+        there are errors with the parser's actions. Errors raised while
+        parsing the command-line are caught by ArgumentParser and emitted
+        as command-line messages.
+
+    - FileType -- A factory for defining types of files to be created. As the
+        example above shows, instances of FileType are typically passed as
+        the type= argument of add_argument() calls.
+
+    - Action -- The base class for parser actions. Typically actions are
+        selected by passing strings like 'store_true' or 'append_const' to
+        the action= argument of add_argument(). However, for greater
+        customization of ArgumentParser actions, subclasses of Action may
+        be defined and passed as the action= argument.
+
+    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
+        ArgumentDefaultsHelpFormatter -- Formatter classes which
+        may be passed as the formatter_class= argument to the
+        ArgumentParser constructor. HelpFormatter is the default,
+        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
+        not to change the formatting for help text, and
+        ArgumentDefaultsHelpFormatter adds information about argument defaults
+        to the help.
+
+All other classes in this module are considered implementation details.
+(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
+considered public as object names -- the API of the formatter objects is
+still considered an implementation detail.)
+"""
+
+__version__ = '1.1'
+__all__ = [
+    'ArgumentParser',
+    'ArgumentError',
+    'Namespace',
+    'Action',
+    'FileType',
+    'HelpFormatter',
+    'RawDescriptionHelpFormatter',
+    'RawTextHelpFormatter',
+    'ArgumentDefaultsHelpFormatter',
+]
+
+
+import copy as _copy
+import os as _os
+import re as _re
+import sys as _sys
+import textwrap as _textwrap
+
+from gettext import gettext as _
+
+try:
+    _set = set
+except NameError:
+    from sets import Set as _set
+
+try:
+    _basestring = basestring
+except NameError:
+    _basestring = str
+
+try:
+    _sorted = sorted
+except NameError:
+
+    def _sorted(iterable, reverse=False):
+        result = list(iterable)
+        result.sort()
+        if reverse:
+            result.reverse()
+        return result
+
+
+def _callable(obj):
+    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
+
+# silence Python 2.6 buggy warnings about Exception.message
+if _sys.version_info[:2] == (2, 6):
+    import warnings
+    warnings.filterwarnings(
+        action='ignore',
+        message='BaseException.message has been deprecated as of Python 2.6',
+        category=DeprecationWarning,
+        module='argparse')
+
+
+SUPPRESS = '==SUPPRESS=='
+
+OPTIONAL = '?'
+ZERO_OR_MORE = '*'
+ONE_OR_MORE = '+'
+PARSER = 'A...'
+REMAINDER = '...'
+
+# =============================
+# Utility functions and classes
+# =============================
+
+class _AttributeHolder(object):
+    """Abstract base class that provides __repr__.
+
+    The __repr__ method returns a string in the format::
+        ClassName(attr=name, attr=name, ...)
+    The attributes are determined either by a class-level attribute,
+    '_kwarg_names', or by inspecting the instance __dict__.
+    """
+
+    def __repr__(self):
+        type_name = type(self).__name__
+        arg_strings = []
+        for arg in self._get_args():
+            arg_strings.append(repr(arg))
+        for name, value in self._get_kwargs():
+            arg_strings.append('%s=%r' % (name, value))
+        return '%s(%s)' % (type_name, ', '.join(arg_strings))
+
+    def _get_kwargs(self):
+        return _sorted(self.__dict__.items())
+
+    def _get_args(self):
+        return []
+
+
+def _ensure_value(namespace, name, value):
+    if getattr(namespace, name, None) is None:
+        setattr(namespace, name, value)
+    return getattr(namespace, name)
+
+
+# ===============
+# Formatting Help
+# ===============
+
+class HelpFormatter(object):
+    """Formatter for generating usage messages and argument help strings.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def __init__(self,
+                 prog,
+                 indent_increment=2,
+                 max_help_position=24,
+                 width=None):
+
+        # default setting for width
+        if width is None:
+            try:
+                width = int(_os.environ['COLUMNS'])
+            except (KeyError, ValueError):
+                width = 80
+            width -= 2
+
+        self._prog = prog
+        self._indent_increment = indent_increment
+        self._max_help_position = max_help_position
+        self._width = width
+
+        self._current_indent = 0
+        self._level = 0
+        self._action_max_length = 0
+
+        self._root_section = self._Section(self, None)
+        self._current_section = self._root_section
+
+        self._whitespace_matcher = _re.compile(r'\s+')
+        self._long_break_matcher = _re.compile(r'\n\n\n+')
+
+    # ===============================
+    # Section and indentation methods
+    # ===============================
+    def _indent(self):
+        self._current_indent += self._indent_increment
+        self._level += 1
+
+    def _dedent(self):
+        self._current_indent -= self._indent_increment
+        assert self._current_indent >= 0, 'Indent decreased below 0.'
+        self._level -= 1
+
+    class _Section(object):
+
+        def __init__(self, formatter, parent, heading=None):
+            self.formatter = formatter
+            self.parent = parent
+            self.heading = heading
+            self.items = []
+
+        def format_help(self):
+            # format the indented section
+            if self.parent is not None:
+                self.formatter._indent()
+            join = self.formatter._join_parts
+            for func, args in self.items:
+                func(*args)
+            item_help = join([func(*args) for func, args in self.items])
+            if self.parent is not None:
+                self.formatter._dedent()
+
+            # return nothing if the section was empty
+            if not item_help:
+                return ''
+
+            # add the heading if the section was non-empty
+            if self.heading is not SUPPRESS and self.heading is not None:
+                current_indent = self.formatter._current_indent
+                heading = '%*s%s:\n' % (current_indent, '', self.heading)
+            else:
+                heading = ''
+
+            # join the section-initial newline, the heading and the help
+            return join(['\n', heading, item_help, '\n'])
+
+    def _add_item(self, func, args):
+        self._current_section.items.append((func, args))
+
+    # ========================
+    # Message building methods
+    # ========================
+    def start_section(self, heading):
+        self._indent()
+        section = self._Section(self, self._current_section, heading)
+        self._add_item(section.format_help, [])
+        self._current_section = section
+
+    def end_section(self):
+        self._current_section = self._current_section.parent
+        self._dedent()
+
+    def add_text(self, text):
+        if text is not SUPPRESS and text is not None:
+            self._add_item(self._format_text, [text])
+
+    def add_usage(self, usage, actions, groups, prefix=None):
+        if usage is not SUPPRESS:
+            args = usage, actions, groups, prefix
+            self._add_item(self._format_usage, args)
+
+    def add_argument(self, action):
+        if action.help is not SUPPRESS:
+
+            # find all invocations
+            get_invocation = self._format_action_invocation
+            invocations = [get_invocation(action)]
+            for subaction in self._iter_indented_subactions(action):
+                invocations.append(get_invocation(subaction))
+
+            # update the maximum item length
+            invocation_length = max([len(s) for s in invocations])
+            action_length = invocation_length + self._current_indent
+            self._action_max_length = max(self._action_max_length,
+                                          action_length)
+
+            # add the item to the list
+            self._add_item(self._format_action, [action])
+
+    def add_arguments(self, actions):
+        for action in actions:
+            self.add_argument(action)
+
+    # =======================
+    # Help-formatting methods
+    # =======================
+    def format_help(self):
+        help = self._root_section.format_help()
+        if help:
+            help = self._long_break_matcher.sub('\n\n', help)
+            help = help.strip('\n') + '\n'
+        return help
+
+    def _join_parts(self, part_strings):
+        return ''.join([part
+                        for part in part_strings
+                        if part and part is not SUPPRESS])
+
+    def _format_usage(self, usage, actions, groups, prefix):
+        if prefix is None:
+            prefix = _('usage: ')
+
+        # if usage is specified, use that
+        if usage is not None:
+            usage = usage % dict(prog=self._prog)
+
+        # if no optionals or positionals are available, usage is just prog
+        elif usage is None and not actions:
+            usage = '%(prog)s' % dict(prog=self._prog)
+
+        # if optionals and positionals are available, calculate usage
+        elif usage is None:
+            prog = '%(prog)s' % dict(prog=self._prog)
+
+            # split optionals from positionals
+            optionals = []
+            positionals = []
+            for action in actions:
+                if action.option_strings:
+                    optionals.append(action)
+                else:
+                    positionals.append(action)
+
+            # build full usage string
+            format = self._format_actions_usage
+            action_usage = format(optionals + positionals, groups)
+            usage = ' '.join([s for s in [prog, action_usage] if s])
+
+            # wrap the usage parts if it's too long
+            text_width = self._width - self._current_indent
+            if len(prefix) + len(usage) > text_width:
+
+                # break usage into wrappable parts
+                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+                opt_usage = format(optionals, groups)
+                pos_usage = format(positionals, groups)
+                opt_parts = _re.findall(part_regexp, opt_usage)
+                pos_parts = _re.findall(part_regexp, pos_usage)
+                assert ' '.join(opt_parts) == opt_usage
+                assert ' '.join(pos_parts) == pos_usage
+
+                # helper for wrapping lines
+                def get_lines(parts, indent, prefix=None):
+                    lines = []
+                    line = []
+                    if prefix is not None:
+                        line_len = len(prefix) - 1
+                    else:
+                        line_len = len(indent) - 1
+                    for part in parts:
+                        if line_len + 1 + len(part) > text_width:
+                            lines.append(indent + ' '.join(line))
+                            line = []
+                            line_len = len(indent) - 1
+                        line.append(part)
+                        line_len += len(part) + 1
+                    if line:
+                        lines.append(indent + ' '.join(line))
+                    if prefix is not None:
+                        lines[0] = lines[0][len(indent):]
+                    return lines
+
+                # if prog is short, follow it with optionals or positionals
+                if len(prefix) + len(prog) <= 0.75 * text_width:
+                    indent = ' ' * (len(prefix) + len(prog) + 1)
+                    if opt_parts:
+                        lines = get_lines([prog] + opt_parts, indent, prefix)
+                        lines.extend(get_lines(pos_parts, indent))
+                    elif pos_parts:
+                        lines = get_lines([prog] + pos_parts, indent, prefix)
+                    else:
+                        lines = [prog]
+
+                # if prog is long, put it on its own line
+                else:
+                    indent = ' ' * len(prefix)
+                    parts = opt_parts + pos_parts
+                    lines = get_lines(parts, indent)
+                    if len(lines) > 1:
+                        lines = []
+                        lines.extend(get_lines(opt_parts, indent))
+                        lines.extend(get_lines(pos_parts, indent))
+                    lines = [prog] + lines
+
+                # join lines into usage
+                usage = '\n'.join(lines)
+
+        # prefix with 'usage:'
+        return '%s%s\n\n' % (prefix, usage)
+
+    def _format_actions_usage(self, actions, groups):
+        # find group indices and identify actions in groups
+        group_actions = _set()
+        inserts = {}
+        for group in groups:
+            try:
+                start = actions.index(group._group_actions[0])
+            except ValueError:
+                continue
+            else:
+                end = start + len(group._group_actions)
+                if actions[start:end] == group._group_actions:
+                    for action in group._group_actions:
+                        group_actions.add(action)
+                    if not group.required:
+                        inserts[start] = '['
+                        inserts[end] = ']'
+                    else:
+                        inserts[start] = '('
+                        inserts[end] = ')'
+                    for i in range(start + 1, end):
+                        inserts[i] = '|'
+
+        # collect all actions format strings
+        parts = []
+        for i, action in enumerate(actions):
+
+            # suppressed arguments are marked with None
+            # remove | separators for suppressed arguments
+            if action.help is SUPPRESS:
+                parts.append(None)
+                if inserts.get(i) == '|':
+                    inserts.pop(i)
+                elif inserts.get(i + 1) == '|':
+                    inserts.pop(i + 1)
+
+            # produce all arg strings
+            elif not action.option_strings:
+                part = self._format_args(action, action.dest)
+
+                # if it's in a group, strip the outer []
+                if action in group_actions:
+                    if part[0] == '[' and part[-1] == ']':
+                        part = part[1:-1]
+
+                # add the action string to the list
+                parts.append(part)
+
+            # produce the first way to invoke the option in brackets
+            else:
+                option_string = action.option_strings[0]
+
+                # if the Optional doesn't take a value, format is:
+                #    -s or --long
+                if action.nargs == 0:
+                    part = '%s' % option_string
+
+                # if the Optional takes a value, format is:
+                #    -s ARGS or --long ARGS
+                else:
+                    default = action.dest.upper()
+                    args_string = self._format_args(action, default)
+                    part = '%s %s' % (option_string, args_string)
+
+                # make it look optional if it's not required or in a group
+                if not action.required and action not in group_actions:
+                    part = '[%s]' % part
+
+                # add the action string to the list
+                parts.append(part)
+
+        # insert things at the necessary indices
+        for i in _sorted(inserts, reverse=True):
+            parts[i:i] = [inserts[i]]
+
+        # join all the action items with spaces
+        text = ' '.join([item for item in parts if item is not None])
+
+        # clean up separators for mutually exclusive groups
+        open = r'[\[(]'
+        close = r'[\])]'
+        text = _re.sub(r'(%s) ' % open, r'\1', text)
+        text = _re.sub(r' (%s)' % close, r'\1', text)
+        text = _re.sub(r'%s *%s' % (open, close), r'', text)
+        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
+        text = text.strip()
+
+        # return the text
+        return text
+
+    def _format_text(self, text):
+        if '%(prog)' in text:
+            text = text % dict(prog=self._prog)
+        text_width = self._width - self._current_indent
+        indent = ' ' * self._current_indent
+        return self._fill_text(text, text_width, indent) + '\n\n'
+
+    def _format_action(self, action):
+        # determine the required width and the entry label
+        help_position = min(self._action_max_length + 2,
+                            self._max_help_position)
+        help_width = self._width - help_position
+        action_width = help_position - self._current_indent - 2
+        action_header = self._format_action_invocation(action)
+
+        # ho nelp; start on same line and add a final newline
+        if not action.help:
+            tup = self._current_indent, '', action_header
+            action_header = '%*s%s\n' % tup
+
+        # short action name; start on the same line and pad two spaces
+        elif len(action_header) <= action_width:
+            tup = self._current_indent, '', action_width, action_header
+            action_header = '%*s%-*s  ' % tup
+            indent_first = 0
+
+        # long action name; start on the next line
+        else:
+            tup = self._current_indent, '', action_header
+            action_header = '%*s%s\n' % tup
+            indent_first = help_position
+
+        # collect the pieces of the action help
+        parts = [action_header]
+
+        # if there was help for the action, add lines of help text
+        if action.help:
+            help_text = self._expand_help(action)
+            help_lines = self._split_lines(help_text, help_width)
+            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
+            for line in help_lines[1:]:
+                parts.append('%*s%s\n' % (help_position, '', line))
+
+        # or add a newline if the description doesn't end with one
+        elif not action_header.endswith('\n'):
+            parts.append('\n')
+
+        # if there are any sub-actions, add their help as well
+        for subaction in self._iter_indented_subactions(action):
+            parts.append(self._format_action(subaction))
+
+        # return a single string
+        return self._join_parts(parts)
+
+    def _format_action_invocation(self, action):
+        if not action.option_strings:
+            metavar, = self._metavar_formatter(action, action.dest)(1)
+            return metavar
+
+        else:
+            parts = []
+
+            # if the Optional doesn't take a value, format is:
+            #    -s, --long
+            if action.nargs == 0:
+                parts.extend(action.option_strings)
+
+            # if the Optional takes a value, format is:
+            #    -s ARGS, --long ARGS
+            else:
+                default = action.dest.upper()
+                args_string = self._format_args(action, default)
+                for option_string in action.option_strings:
+                    parts.append('%s %s' % (option_string, args_string))
+
+            return ', '.join(parts)
+
+    def _metavar_formatter(self, action, default_metavar):
+        if action.metavar is not None:
+            result = action.metavar
+        elif action.choices is not None:
+            choice_strs = [str(choice) for choice in action.choices]
+            result = '{%s}' % ','.join(choice_strs)
+        else:
+            result = default_metavar
+
+        def format(tuple_size):
+            if isinstance(result, tuple):
+                return result
+            else:
+                return (result, ) * tuple_size
+        return format
+
+    def _format_args(self, action, default_metavar):
+        get_metavar = self._metavar_formatter(action, default_metavar)
+        if action.nargs is None:
+            result = '%s' % get_metavar(1)
+        elif action.nargs == OPTIONAL:
+            result = '[%s]' % get_metavar(1)
+        elif action.nargs == ZERO_OR_MORE:
+            result = '[%s [%s ...]]' % get_metavar(2)
+        elif action.nargs == ONE_OR_MORE:
+            result = '%s [%s ...]' % get_metavar(2)
+        elif action.nargs == REMAINDER:
+            result = '...'
+        elif action.nargs == PARSER:
+            result = '%s ...' % get_metavar(1)
+        else:
+            formats = ['%s' for _ in range(action.nargs)]
+            result = ' '.join(formats) % get_metavar(action.nargs)
+        return result
+
+    def _expand_help(self, action):
+        params = dict(vars(action), prog=self._prog)
+        for name in list(params):
+            if params[name] is SUPPRESS:
+                del params[name]
+        for name in list(params):
+            if hasattr(params[name], '__name__'):
+                params[name] = params[name].__name__
+        if params.get('choices') is not None:
+            choices_str = ', '.join([str(c) for c in params['choices']])
+            params['choices'] = choices_str
+        return self._get_help_string(action) % params
+
+    def _iter_indented_subactions(self, action):
+        try:
+            get_subactions = action._get_subactions
+        except AttributeError:
+            pass
+        else:
+            self._indent()
+            for subaction in get_subactions():
+                yield subaction
+            self._dedent()
+
+    def _split_lines(self, text, width):
+        text = self._whitespace_matcher.sub(' ', text).strip()
+        return _textwrap.wrap(text, width)
+
+    def _fill_text(self, text, width, indent):
+        text = self._whitespace_matcher.sub(' ', text).strip()
+        return _textwrap.fill(text, width, initial_indent=indent,
+                                           subsequent_indent=indent)
+
+    def _get_help_string(self, action):
+        return action.help
+
+
+class RawDescriptionHelpFormatter(HelpFormatter):
+    """Help message formatter which retains any formatting in descriptions.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _fill_text(self, text, width, indent):
+        return ''.join([indent + line for line in text.splitlines(True)])
+
+
+class RawTextHelpFormatter(RawDescriptionHelpFormatter):
+    """Help message formatter which retains formatting of all help text.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _split_lines(self, text, width):
+        return text.splitlines()
+
+
+class ArgumentDefaultsHelpFormatter(HelpFormatter):
+    """Help message formatter which adds default values to argument help.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _get_help_string(self, action):
+        help = action.help
+        if '%(default)' not in action.help:
+            if action.default is not SUPPRESS:
+                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
+                if action.option_strings or action.nargs in defaulting_nargs:
+                    help += ' (default: %(default)s)'
+        return help
+
+
+# =====================
+# Options and Arguments
+# =====================
+
+def _get_action_name(argument):
+    if argument is None:
+        return None
+    elif argument.option_strings:
+        return  '/'.join(argument.option_strings)
+    elif argument.metavar not in (None, SUPPRESS):
+        return argument.metavar
+    elif argument.dest not in (None, SUPPRESS):
+        return argument.dest
+    else:
+        return None
+
+
+class ArgumentError(Exception):
+    """An error from creating or using an argument (optional or positional).
+
+    The string value of this exception is the message, augmented with
+    information about the argument that caused it.
+    """
+
+    def __init__(self, argument, message):
+        self.argument_name = _get_action_name(argument)
+        self.message = message
+
+    def __str__(self):
+        if self.argument_name is None:
+            format = '%(message)s'
+        else:
+            format = 'argument %(argument_name)s: %(message)s'
+        return format % dict(message=self.message,
+                             argument_name=self.argument_name)
+
+
+class ArgumentTypeError(Exception):
+    """An error from trying to convert a command line string to a type."""
+    pass
+
+
+# ==============
+# Action classes
+# ==============
+
+class Action(_AttributeHolder):
+    """Information about how to convert command line strings to Python objects.
+
+    Action objects are used by an ArgumentParser to represent the information
+    needed to parse a single argument from one or more strings from the
+    command line. The keyword arguments to the Action constructor are also
+    all attributes of Action instances.
+
+    Keyword Arguments:
+
+        - option_strings -- A list of command-line option strings which
+            should be associated with this action.
+
+        - dest -- The name of the attribute to hold the created object(s)
+
+        - nargs -- The number of command-line arguments that should be
+            consumed. By default, one argument will be consumed and a single
+            value will be produced.  Other values include:
+                - N (an integer) consumes N arguments (and produces a list)
+                - '?' consumes zero or one arguments
+                - '*' consumes zero or more arguments (and produces a list)
+                - '+' consumes one or more arguments (and produces a list)
+            Note that the difference between the default and nargs=1 is that
+            with the default, a single value will be produced, while with
+            nargs=1, a list containing a single value will be produced.
+
+        - const -- The value to be produced if the option is specified and the
+            option uses an action that takes no values.
+
+        - default -- The value to be produced if the option is not specified.
+
+        - type -- The type which the command-line arguments should be converted
+            to, should be one of 'string', 'int', 'float', 'complex' or a
+            callable object that accepts a single string argument. If None,
+            'string' is assumed.
+
+        - choices -- A container of values that should be allowed. If not None,
+            after a command-line argument has been converted to the appropriate
+            type, an exception will be raised if it is not a member of this
+            collection.
+
+        - required -- True if the action must always be specified at the
+            command line. This is only meaningful for optional command-line
+            arguments.
+
+        - help -- The help string describing the argument.
+
+        - metavar -- The name to be used for the option's argument with the
+            help string. If None, the 'dest' value will be used as the name.
+    """
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        self.option_strings = option_strings
+        self.dest = dest
+        self.nargs = nargs
+        self.const = const
+        self.default = default
+        self.type = type
+        self.choices = choices
+        self.required = required
+        self.help = help
+        self.metavar = metavar
+
+    def _get_kwargs(self):
+        names = [
+            'option_strings',
+            'dest',
+            'nargs',
+            'const',
+            'default',
+            'type',
+            'choices',
+            'help',
+            'metavar',
+        ]
+        return [(name, getattr(self, name)) for name in names]
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        raise NotImplementedError(_('.__call__() not defined'))
+
+
+class _StoreAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        if nargs == 0:
+            raise ValueError('nargs for store actions must be > 0; if you '
+                             'have nothing to store, actions such as store '
+                             'true or store const may be more appropriate')
+        if const is not None and nargs != OPTIONAL:
+            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+        super(_StoreAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=nargs,
+            const=const,
+            default=default,
+            type=type,
+            choices=choices,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, values)
+
+
+class _StoreConstAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 const,
+                 default=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        super(_StoreConstAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            const=const,
+            default=default,
+            required=required,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, self.const)
+
+
+class _StoreTrueAction(_StoreConstAction):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=False,
+                 required=False,
+                 help=None):
+        super(_StoreTrueAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            const=True,
+            default=default,
+            required=required,
+            help=help)
+
+
+class _StoreFalseAction(_StoreConstAction):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=True,
+                 required=False,
+                 help=None):
+        super(_StoreFalseAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            const=False,
+            default=default,
+            required=required,
+            help=help)
+
+
+class _AppendAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        if nargs == 0:
+            raise ValueError('nargs for append actions must be > 0; if arg '
+                             'strings are not supplying the value to append, '
+                             'the append const action may be more appropriate')
+        if const is not None and nargs != OPTIONAL:
+            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+        super(_AppendAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=nargs,
+            const=const,
+            default=default,
+            type=type,
+            choices=choices,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+        items.append(values)
+        setattr(namespace, self.dest, items)
+
+
+class _AppendConstAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 const,
+                 default=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        super(_AppendConstAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            const=const,
+            default=default,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+        items.append(self.const)
+        setattr(namespace, self.dest, items)
+
+
+class _CountAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=None,
+                 required=False,
+                 help=None):
+        super(_CountAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            default=default,
+            required=required,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        new_count = _ensure_value(namespace, self.dest, 0) + 1
+        setattr(namespace, self.dest, new_count)
+
+
+class _HelpAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest=SUPPRESS,
+                 default=SUPPRESS,
+                 help=None):
+        super(_HelpAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            default=default,
+            nargs=0,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser.print_help()
+        parser.exit()
+
+
+class _VersionAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 version=None,
+                 dest=SUPPRESS,
+                 default=SUPPRESS,
+                 help=None):
+        super(_VersionAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            default=default,
+            nargs=0,
+            help=help)
+        self.version = version
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        version = self.version
+        if version is None:
+            version = parser.version
+        formatter = parser._get_formatter()
+        formatter.add_text(version)
+        parser.exit(message=formatter.format_help())
+
+
+class _SubParsersAction(Action):
+
+    class _ChoicesPseudoAction(Action):
+
+        def __init__(self, name, help):
+            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
+            sup.__init__(option_strings=[], dest=name, help=help)
+
+    def __init__(self,
+                 option_strings,
+                 prog,
+                 parser_class,
+                 dest=SUPPRESS,
+                 help=None,
+                 metavar=None):
+
+        self._prog_prefix = prog
+        self._parser_class = parser_class
+        self._name_parser_map = {}
+        self._choices_actions = []
+
+        super(_SubParsersAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=PARSER,
+            choices=self._name_parser_map,
+            help=help,
+            metavar=metavar)
+
+    def add_parser(self, name, **kwargs):
+        # set prog from the existing prefix
+        if kwargs.get('prog') is None:
+            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
+
+        # create a pseudo-action to hold the choice help
+        if 'help' in kwargs:
+            help = kwargs.pop('help')
+            choice_action = self._ChoicesPseudoAction(name, help)
+            self._choices_actions.append(choice_action)
+
+        # create the parser and add it to the map
+        parser = self._parser_class(**kwargs)
+        self._name_parser_map[name] = parser
+        return parser
+
+    def _get_subactions(self):
+        return self._choices_actions
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser_name = values[0]
+        arg_strings = values[1:]
+
+        # set the parser name if requested
+        if self.dest is not SUPPRESS:
+            setattr(namespace, self.dest, parser_name)
+
+        # select the parser
+        try:
+            parser = self._name_parser_map[parser_name]
+        except KeyError:
+            tup = parser_name, ', '.join(self._name_parser_map)
+            msg = _('unknown parser %r (choices: %s)' % tup)
+            raise ArgumentError(self, msg)
+
+        # parse all the remaining options into the namespace
+        parser.parse_args(arg_strings, namespace)
+
+
+# ==============
+# Type classes
+# ==============
+
+class FileType(object):
+    """Factory for creating file object types
+
+    Instances of FileType are typically passed as type= arguments to the
+    ArgumentParser add_argument() method.
+
+    Keyword Arguments:
+        - mode -- A string indicating how the file is to be opened. Accepts the
+            same values as the builtin open() function.
+        - bufsize -- The file's desired buffer size. Accepts the same values as
+            the builtin open() function.
+    """
+
+    def __init__(self, mode='r', bufsize=None):
+        self._mode = mode
+        self._bufsize = bufsize
+
+    def __call__(self, string):
+        # the special argument "-" means sys.std{in,out}
+        if string == '-':
+            if 'r' in self._mode:
+                return _sys.stdin
+            elif 'w' in self._mode:
+                return _sys.stdout
+            else:
+                msg = _('argument "-" with mode %r' % self._mode)
+                raise ValueError(msg)
+
+        # all other arguments are used as file names
+        if self._bufsize:
+            return open(string, self._mode, self._bufsize)
+        else:
+            return open(string, self._mode)
+
+    def __repr__(self):
+        args = [self._mode, self._bufsize]
+        args_str = ', '.join([repr(arg) for arg in args if arg is not None])
+        return '%s(%s)' % (type(self).__name__, args_str)
+
+# ===========================
+# Optional and Positional Parsing
+# ===========================
+
+class Namespace(_AttributeHolder):
+    """Simple object for storing attributes.
+
+    Implements equality by attribute names and values, and provides a simple
+    string representation.
+    """
+
+    def __init__(self, **kwargs):
+        for name in kwargs:
+            setattr(self, name, kwargs[name])
+
+    def __eq__(self, other):
+        return vars(self) == vars(other)
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def __contains__(self, key):
+        return key in self.__dict__
+
+
+class _ActionsContainer(object):
+
+    def __init__(self,
+                 description,
+                 prefix_chars,
+                 argument_default,
+                 conflict_handler):
+        super(_ActionsContainer, self).__init__()
+
+        self.description = description
+        self.argument_default = argument_default
+        self.prefix_chars = prefix_chars
+        self.conflict_handler = conflict_handler
+
+        # set up registries
+        self._registries = {}
+
+        # register actions
+        self.register('action', None, _StoreAction)
+        self.register('action', 'store', _StoreAction)
+        self.register('action', 'store_const', _StoreConstAction)
+        self.register('action', 'store_true', _StoreTrueAction)
+        self.register('action', 'store_false', _StoreFalseAction)
+        self.register('action', 'append', _AppendAction)
+        self.register('action', 'append_const', _AppendConstAction)
+        self.register('action', 'count', _CountAction)
+        self.register('action', 'help', _HelpAction)
+        self.register('action', 'version', _VersionAction)
+        self.register('action', 'parsers', _SubParsersAction)
+
+        # raise an exception if the conflict handler is invalid
+        self._get_handler()
+
+        # action storage
+        self._actions = []
+        self._option_string_actions = {}
+
+        # groups
+        self._action_groups = []
+        self._mutually_exclusive_groups = []
+
+        # defaults storage
+        self._defaults = {}
+
+        # determines whether an "option" looks like a negative number
+        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
+
+        # whether or not there are any optionals that look like negative
+        # numbers -- uses a list so it can be shared and edited
+        self._has_negative_number_optionals = []
+
+    # ====================
+    # Registration methods
+    # ====================
+    def register(self, registry_name, value, object):
+        registry = self._registries.setdefault(registry_name, {})
+        registry[value] = object
+
+    def _registry_get(self, registry_name, value, default=None):
+        return self._registries[registry_name].get(value, default)
+
+    # ==================================
+    # Namespace default accessor methods
+    # ==================================
+    def set_defaults(self, **kwargs):
+        self._defaults.update(kwargs)
+
+        # if these defaults match any existing arguments, replace
+        # the previous default on the object with the new one
+        for action in self._actions:
+            if action.dest in kwargs:
+                action.default = kwargs[action.dest]
+
+    def get_default(self, dest):
+        for action in self._actions:
+            if action.dest == dest and action.default is not None:
+                return action.default
+        return self._defaults.get(dest, None)
+
+
+    # =======================
+    # Adding argument actions
+    # =======================
+    def add_argument(self, *args, **kwargs):
+        """
+        add_argument(dest, ..., name=value, ...)
+        add_argument(option_string, option_string, ..., name=value, ...)
+        """
+
+        # if no positional args are supplied or only one is supplied and
+        # it doesn't look like an option string, parse a positional
+        # argument
+        chars = self.prefix_chars
+        if not args or len(args) == 1 and args[0][0] not in chars:
+            if args and 'dest' in kwargs:
+                raise ValueError('dest supplied twice for positional argument')
+            kwargs = self._get_positional_kwargs(*args, **kwargs)
+
+        # otherwise, we're adding an optional argument
+        else:
+            kwargs = self._get_optional_kwargs(*args, **kwargs)
+
+        # if no default was supplied, use the parser-level default
+        if 'default' not in kwargs:
+            dest = kwargs['dest']
+            if dest in self._defaults:
+                kwargs['default'] = self._defaults[dest]
+            elif self.argument_default is not None:
+                kwargs['default'] = self.argument_default
+
+        # create the action object, and add it to the parser
+        action_class = self._pop_action_class(kwargs)
+        if not _callable(action_class):
+            raise ValueError('unknown action "%s"' % action_class)
+        action = action_class(**kwargs)
+
+        # raise an error if the action type is not callable
+        type_func = self._registry_get('type', action.type, action.type)
+        if not _callable(type_func):
+            raise ValueError('%r is not callable' % type_func)
+
+        return self._add_action(action)
+
+    def add_argument_group(self, *args, **kwargs):
+        group = _ArgumentGroup(self, *args, **kwargs)
+        self._action_groups.append(group)
+        return group
+
+    def add_mutually_exclusive_group(self, **kwargs):
+        group = _MutuallyExclusiveGroup(self, **kwargs)
+        self._mutually_exclusive_groups.append(group)
+        return group
+
+    def _add_action(self, action):
+        # resolve any conflicts
+        self._check_conflict(action)
+
+        # add to actions list
+        self._actions.append(action)
+        action.container = self
+
+        # index the action by any option strings it has
+        for option_string in action.option_strings:
+            self._option_string_actions[option_string] = action
+
+        # set the flag if any option strings look like negative numbers
+        for option_string in action.option_strings:
+            if self._negative_number_matcher.match(option_string):
+                if not self._has_negative_number_optionals:
+                    self._has_negative_number_optionals.append(True)
+
+        # return the created action
+        return action
+
+    def _remove_action(self, action):
+        self._actions.remove(action)
+
+    def _add_container_actions(self, container):
+        # collect groups by titles
+        title_group_map = {}
+        for group in self._action_groups:
+            if group.title in title_group_map:
+                msg = _('cannot merge actions - two groups are named %r')
+                raise ValueError(msg % (group.title))
+            title_group_map[group.title] = group
+
+        # map each action to its group
+        group_map = {}
+        for group in container._action_groups:
+
+            # if a group with the title exists, use that, otherwise
+            # create a new group matching the container's group
+            if group.title not in title_group_map:
+                title_group_map[group.title] = self.add_argument_group(
+                    title=group.title,
+                    description=group.description,
+                    conflict_handler=group.conflict_handler)
+
+            # map the actions to their new group
+            for action in group._group_actions:
+                group_map[action] = title_group_map[group.title]
+
+        # add container's mutually exclusive groups
+        # NOTE: if add_mutually_exclusive_group ever gains title= and
+        # description= then this code will need to be expanded as above
+        for group in container._mutually_exclusive_groups:
+            mutex_group = self.add_mutually_exclusive_group(
+                required=group.required)
+
+            # map the actions to their new mutex group
+            for action in group._group_actions:
+                group_map[action] = mutex_group
+
+        # add all actions to this container or their group
+        for action in container._actions:
+            group_map.get(action, self)._add_action(action)
+
+    def _get_positional_kwargs(self, dest, **kwargs):
+        # make sure required is not specified
+        if 'required' in kwargs:
+            msg = _("'required' is an invalid argument for positionals")
+            raise TypeError(msg)
+
+        # mark positional arguments as required if at least one is
+        # always required
+        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
+            kwargs['required'] = True
+        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+            kwargs['required'] = True
+
+        # return the keyword arguments with no option strings
+        return dict(kwargs, dest=dest, option_strings=[])
+
+    def _get_optional_kwargs(self, *args, **kwargs):
+        # determine short and long option strings
+        option_strings = []
+        long_option_strings = []
+        for option_string in args:
+            # error on strings that don't start with an appropriate prefix
+            if not option_string[0] in self.prefix_chars:
+                msg = _('invalid option string %r: '
+                        'must start with a character %r')
+                tup = option_string, self.prefix_chars
+                raise ValueError(msg % tup)
+
+            # strings starting with two prefix characters are long options
+            option_strings.append(option_string)
+            if option_string[0] in self.prefix_chars:
+                if len(option_string) > 1:
+                    if option_string[1] in self.prefix_chars:
+                        long_option_strings.append(option_string)
+
+        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
+        dest = kwargs.pop('dest', None)
+        if dest is None:
+            if long_option_strings:
+                dest_option_string = long_option_strings[0]
+            else:
+                dest_option_string = option_strings[0]
+            dest = dest_option_string.lstrip(self.prefix_chars)
+            if not dest:
+                msg = _('dest= is required for options like %r')
+                raise ValueError(msg % option_string)
+            dest = dest.replace('-', '_')
+
+        # return the updated keyword arguments
+        return dict(kwargs, dest=dest, option_strings=option_strings)
+
+    def _pop_action_class(self, kwargs, default=None):
+        action = kwargs.pop('action', default)
+        return self._registry_get('action', action, action)
+
+    def _get_handler(self):
+        # determine function from conflict handler string
+        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
+        try:
+            return getattr(self, handler_func_name)
+        except AttributeError:
+            msg = _('invalid conflict_resolution value: %r')
+            raise ValueError(msg % self.conflict_handler)
+
+    def _check_conflict(self, action):
+
+        # find all options that conflict with this option
+        confl_optionals = []
+        for option_string in action.option_strings:
+            if option_string in self._option_string_actions:
+                confl_optional = self._option_string_actions[option_string]
+                confl_optionals.append((option_string, confl_optional))
+
+        # resolve any conflicts
+        if confl_optionals:
+            conflict_handler = self._get_handler()
+            conflict_handler(action, confl_optionals)
+
+    def _handle_conflict_error(self, action, conflicting_actions):
+        message = _('conflicting option string(s): %s')
+        conflict_string = ', '.join([option_string
+                                     for option_string, action
+                                     in conflicting_actions])
+        raise ArgumentError(action, message % conflict_string)
+
+    def _handle_conflict_resolve(self, action, conflicting_actions):
+
+        # remove all conflicting options
+        for option_string, action in conflicting_actions:
+
+            # remove the conflicting option
+            action.option_strings.remove(option_string)
+            self._option_string_actions.pop(option_string, None)
+
+            # if the option now has no option string, remove it from the
+            # container holding it
+            if not action.option_strings:
+                action.container._remove_action(action)
+
+
+class _ArgumentGroup(_ActionsContainer):
+
+    def __init__(self, container, title=None, description=None, **kwargs):
+        # add any missing keyword arguments by checking the container
+        update = kwargs.setdefault
+        update('conflict_handler', container.conflict_handler)
+        update('prefix_chars', container.prefix_chars)
+        update('argument_default', container.argument_default)
+        super_init = super(_ArgumentGroup, self).__init__
+        super_init(description=description, **kwargs)
+
+        # group attributes
+        self.title = title
+        self._group_actions = []
+
+        # share most attributes with the container
+        self._registries = container._registries
+        self._actions = container._actions
+        self._option_string_actions = container._option_string_actions
+        self._defaults = container._defaults
+        self._has_negative_number_optionals = \
+            container._has_negative_number_optionals
+
+    def _add_action(self, action):
+        action = super(_ArgumentGroup, self)._add_action(action)
+        self._group_actions.append(action)
+        return action
+
+    def _remove_action(self, action):
+        super(_ArgumentGroup, self)._remove_action(action)
+        self._group_actions.remove(action)
+
+
+class _MutuallyExclusiveGroup(_ArgumentGroup):
+
+    def __init__(self, container, required=False):
+        super(_MutuallyExclusiveGroup, self).__init__(container)
+        self.required = required
+        self._container = container
+
+    def _add_action(self, action):
+        if action.required:
+            msg = _('mutually exclusive arguments must be optional')
+            raise ValueError(msg)
+        action = self._container._add_action(action)
+        self._group_actions.append(action)
+        return action
+
+    def _remove_action(self, action):
+        self._container._remove_action(action)
+        self._group_actions.remove(action)
+
+
+class ArgumentParser(_AttributeHolder, _ActionsContainer):
+    """Object for parsing command line strings into Python objects.
+
+    Keyword Arguments:
+        - prog -- The name of the program (default: sys.argv[0])
+        - usage -- A usage message (default: auto-generated from arguments)
+        - description -- A description of what the program does
+        - epilog -- Text following the argument descriptions
+        - parents -- Parsers whose arguments should be copied into this one
+        - formatter_class -- HelpFormatter class for printing help messages
+        - prefix_chars -- Characters that prefix optional arguments
+        - fromfile_prefix_chars -- Characters that prefix files containing
+            additional arguments
+        - argument_default -- The default value for all arguments
+        - conflict_handler -- String indicating how to handle conflicts
+        - add_help -- Add a -h/-help option
+    """
+
+    def __init__(self,
+                 prog=None,
+                 usage=None,
+                 description=None,
+                 epilog=None,
+                 version=None,
+                 parents=[],
+                 formatter_class=HelpFormatter,
+                 prefix_chars='-',
+                 fromfile_prefix_chars=None,
+                 argument_default=None,
+                 conflict_handler='error',
+                 add_help=True):
+
+        if version is not None:
+            import warnings
+            warnings.warn(
+                """The "version" argument to ArgumentParser is deprecated. """
+                """Please use """
+                """"add_argument(..., action='version', version="N", ...)" """
+                """instead""", DeprecationWarning)
+
+        superinit = super(ArgumentParser, self).__init__
+        superinit(description=description,
+                  prefix_chars=prefix_chars,
+                  argument_default=argument_default,
+                  conflict_handler=conflict_handler)
+
+        # default setting for prog
+        if prog is None:
+            prog = _os.path.basename(_sys.argv[0])
+
+        self.prog = prog
+        self.usage = usage
+        self.epilog = epilog
+        self.version = version
+        self.formatter_class = formatter_class
+        self.fromfile_prefix_chars = fromfile_prefix_chars
+        self.add_help = add_help
+
+        add_group = self.add_argument_group
+        self._positionals = add_group(_('positional arguments'))
+        self._optionals = add_group(_('optional arguments'))
+        self._subparsers = None
+
+        # register types
+        def identity(string):
+            return string
+        self.register('type', None, identity)
+
+        # add help and version arguments if necessary
+        # (using explicit default to override global argument_default)
+        if self.add_help:
+            self.add_argument(
+                '-h', '--help', action='help', default=SUPPRESS,
+                help=_('show this help message and exit'))
+        if self.version:
+            self.add_argument(
+                '-v', '--version', action='version', default=SUPPRESS,
+                version=self.version,
+                help=_("show program's version number and exit"))
+
+        # add parent arguments and defaults
+        for parent in parents:
+            self._add_container_actions(parent)
+            try:
+                defaults = parent._defaults
+            except AttributeError:
+                pass
+            else:
+                self._defaults.update(defaults)
+
+    # =======================
+    # Pretty __repr__ methods
+    # =======================
+    def _get_kwargs(self):
+        names = [
+            'prog',
+            'usage',
+            'description',
+            'version',
+            'formatter_class',
+            'conflict_handler',
+            'add_help',
+        ]
+        return [(name, getattr(self, name)) for name in names]
+
+    # ==================================
+    # Optional/Positional adding methods
+    # ==================================
+    def add_subparsers(self, **kwargs):
+        if self._subparsers is not None:
+            self.error(_('cannot have multiple subparser arguments'))
+
+        # add the parser class to the arguments if it's not present
+        kwargs.setdefault('parser_class', type(self))
+
+        if 'title' in kwargs or 'description' in kwargs:
+            title = _(kwargs.pop('title', 'subcommands'))
+            description = _(kwargs.pop('description', None))
+            self._subparsers = self.add_argument_group(title, description)
+        else:
+            self._subparsers = self._positionals
+
+        # prog defaults to the usage message of this parser, skipping
+        # optional arguments and with no "usage:" prefix
+        if kwargs.get('prog') is None:
+            formatter = self._get_formatter()
+            positionals = self._get_positional_actions()
+            groups = self._mutually_exclusive_groups
+            formatter.add_usage(self.usage, positionals, groups, '')
+            kwargs['prog'] = formatter.format_help().strip()
+
+        # create the parsers action and add it to the positionals list
+        parsers_class = self._pop_action_class(kwargs, 'parsers')
+        action = parsers_class(option_strings=[], **kwargs)
+        self._subparsers._add_action(action)
+
+        # return the created parsers action
+        return action
+
+    def _add_action(self, action):
+        if action.option_strings:
+            self._optionals._add_action(action)
+        else:
+            self._positionals._add_action(action)
+        return action
+
+    def _get_optional_actions(self):
+        return [action
+                for action in self._actions
+                if action.option_strings]
+
+    def _get_positional_actions(self):
+        return [action
+                for action in self._actions
+                if not action.option_strings]
+
+    # =====================================
+    # Command line argument parsing methods
+    # =====================================
+    def parse_args(self, args=None, namespace=None):
+        args, argv = self.parse_known_args(args, namespace)
+        if argv:
+            msg = _('unrecognized arguments: %s')
+            self.error(msg % ' '.join(argv))
+        return args
+
+    def parse_known_args(self, args=None, namespace=None):
+        # args default to the system args
+        if args is None:
+            args = _sys.argv[1:]
+
+        # default Namespace built from parser defaults
+        if namespace is None:
+            namespace = Namespace()
+
+        # add any action defaults that aren't present
+        for action in self._actions:
+            if action.dest is not SUPPRESS:
+                if not hasattr(namespace, action.dest):
+                    if action.default is not SUPPRESS:
+                        default = action.default
+                        if isinstance(action.default, _basestring):
+                            default = self._get_value(action, default)
+                        setattr(namespace, action.dest, default)
+
+        # add any parser defaults that aren't present
+        for dest in self._defaults:
+            if not hasattr(namespace, dest):
+                setattr(namespace, dest, self._defaults[dest])
+
+        # parse the arguments and exit if there are any errors
+        try:
+            return self._parse_known_args(args, namespace)
+        except ArgumentError:
+            err = _sys.exc_info()[1]
+            self.error(str(err))
+
+    def _parse_known_args(self, arg_strings, namespace):
+        # replace arg strings that are file references
+        if self.fromfile_prefix_chars is not None:
+            arg_strings = self._read_args_from_files(arg_strings)
+
+        # map all mutually exclusive arguments to the other arguments
+        # they can't occur with
+        action_conflicts = {}
+        for mutex_group in self._mutually_exclusive_groups:
+            group_actions = mutex_group._group_actions
+            for i, mutex_action in enumerate(mutex_group._group_actions):
+                conflicts = action_conflicts.setdefault(mutex_action, [])
+                conflicts.extend(group_actions[:i])
+                conflicts.extend(group_actions[i + 1:])
+
+        # find all option indices, and determine the arg_string_pattern
+        # which has an 'O' if there is an option at an index,
+        # an 'A' if there is an argument, or a '-' if there is a '--'
+        option_string_indices = {}
+        arg_string_pattern_parts = []
+        arg_strings_iter = iter(arg_strings)
+        for i, arg_string in enumerate(arg_strings_iter):
+
+            # all args after -- are non-options
+            if arg_string == '--':
+                arg_string_pattern_parts.append('-')
+                for arg_string in arg_strings_iter:
+                    arg_string_pattern_parts.append('A')
+
+            # otherwise, add the arg to the arg strings
+            # and note the index if it was an option
+            else:
+                option_tuple = self._parse_optional(arg_string)
+                if option_tuple is None:
+                    pattern = 'A'
+                else:
+                    option_string_indices[i] = option_tuple
+                    pattern = 'O'
+                arg_string_pattern_parts.append(pattern)
+
+        # join the pieces together to form the pattern
+        arg_strings_pattern = ''.join(arg_string_pattern_parts)
+
+        # converts arg strings to the appropriate and then takes the action
+        seen_actions = _set()
+        seen_non_default_actions = _set()
+
+        def take_action(action, argument_strings, option_string=None):
+            seen_actions.add(action)
+            argument_values = self._get_values(action, argument_strings)
+
+            # error if this argument is not allowed with other previously
+            # seen arguments, assuming that actions that use the default
+            # value don't really count as "present"
+            if argument_values is not action.default:
+                seen_non_default_actions.add(action)
+                for conflict_action in action_conflicts.get(action, []):
+                    if conflict_action in seen_non_default_actions:
+                        msg = _('not allowed with argument %s')
+                        action_name = _get_action_name(conflict_action)
+                        raise ArgumentError(action, msg % action_name)
+
+            # take the action if we didn't receive a SUPPRESS value
+            # (e.g. from a default)
+            if argument_values is not SUPPRESS:
+                action(self, namespace, argument_values, option_string)
+
+        # function to convert arg_strings into an optional action
+        def consume_optional(start_index):
+
+            # get the optional identified at this index
+            option_tuple = option_string_indices[start_index]
+            action, option_string, explicit_arg = option_tuple
+
+            # identify additional optionals in the same arg string
+            # (e.g. -xyz is the same as -x -y -z if no args are required)
+            match_argument = self._match_argument
+            action_tuples = []
+            while True:
+
+                # if we found no optional action, skip it
+                if action is None:
+                    extras.append(arg_strings[start_index])
+                    return start_index + 1
+
+                # if there is an explicit argument, try to match the
+                # optional's string arguments to only this
+                if explicit_arg is not None:
+                    arg_count = match_argument(action, 'A')
+
+                    # if the action is a single-dash option and takes no
+                    # arguments, try to parse more single-dash options out
+                    # of the tail of the option string
+                    chars = self.prefix_chars
+                    if arg_count == 0 and option_string[1] not in chars:
+                        action_tuples.append((action, [], option_string))
+                        for char in self.prefix_chars:
+                            option_string = char + explicit_arg[0]
+                            explicit_arg = explicit_arg[1:] or None
+                            optionals_map = self._option_string_actions
+                            if option_string in optionals_map:
+                                action = optionals_map[option_string]
+                                break
+                        else:
+                            msg = _('ignored explicit argument %r')
+                            raise ArgumentError(action, msg % explicit_arg)
+
+                    # if the action expect exactly one argument, we've
+                    # successfully matched the option; exit the loop
+                    elif arg_count == 1:
+                        stop = start_index + 1
+                        args = [explicit_arg]
+                        action_tuples.append((action, args, option_string))
+                        break
+
+                    # error if a double-dash option did not use the
+                    # explicit argument
+                    else:
+                        msg = _('ignored explicit argument %r')
+                        raise ArgumentError(action, msg % explicit_arg)
+
+                # if there is no explicit argument, try to match the
+                # optional's string arguments with the following strings
+                # if successful, exit the loop
+                else:
+                    start = start_index + 1
+                    selected_patterns = arg_strings_pattern[start:]
+                    arg_count = match_argument(action, selected_patterns)
+                    stop = start + arg_count
+                    args = arg_strings[start:stop]
+                    action_tuples.append((action, args, option_string))
+                    break
+
+            # add the Optional to the list and return the index at which
+            # the Optional's string args stopped
+            assert action_tuples
+            for action, args, option_string in action_tuples:
+                take_action(action, args, option_string)
+            return stop
+
+        # the list of Positionals left to be parsed; this is modified
+        # by consume_positionals()
+        positionals = self._get_positional_actions()
+
+        # function to convert arg_strings into positional actions
+        def consume_positionals(start_index):
+            # match as many Positionals as possible
+            match_partial = self._match_arguments_partial
+            selected_pattern = arg_strings_pattern[start_index:]
+            arg_counts = match_partial(positionals, selected_pattern)
+
+            # slice off the appropriate arg strings for each Positional
+            # and add the Positional and its args to the list
+            for action, arg_count in zip(positionals, arg_counts):
+                args = arg_strings[start_index: start_index + arg_count]
+                start_index += arg_count
+                take_action(action, args)
+
+            # slice off the Positionals that we just parsed and return the
+            # index at which the Positionals' string args stopped
+            positionals[:] = positionals[len(arg_counts):]
+            return start_index
+
+        # consume Positionals and Optionals alternately, until we have
+        # passed the last option string
+        extras = []
+        start_index = 0
+        if option_string_indices:
+            max_option_string_index = max(option_string_indices)
+        else:
+            max_option_string_index = -1
+        while start_index <= max_option_string_index:
+
+            # consume any Positionals preceding the next option
+            next_option_string_index = min([
+                index
+                for index in option_string_indices
+                if index >= start_index])
+            if start_index != next_option_string_index:
+                positionals_end_index = consume_positionals(start_index)
+
+                # only try to parse the next optional if we didn't consume
+                # the option string during the positionals parsing
+                if positionals_end_index > start_index:
+                    start_index = positionals_end_index
+                    continue
+                else:
+                    start_index = positionals_end_index
+
+            # if we consumed all the positionals we could and we're not
+            # at the index of an option string, there were extra arguments
+            if start_index not in option_string_indices:
+                strings = arg_strings[start_index:next_option_string_index]
+                extras.extend(strings)
+                start_index = next_option_string_index
+
+            # consume the next optional and any arguments for it
+            start_index = consume_optional(start_index)
+
+        # consume any positionals following the last Optional
+        stop_index = consume_positionals(start_index)
+
+        # if we didn't consume all the argument strings, there were extras
+        extras.extend(arg_strings[stop_index:])
+
+        # if we didn't use all the Positional objects, there were too few
+        # arg strings supplied.
+        if positionals:
+            self.error(_('too few arguments'))
+
+        # make sure all required actions were present
+        for action in self._actions:
+            if action.required:
+                if action not in seen_actions:
+                    name = _get_action_name(action)
+                    self.error(_('argument %s is required') % name)
+
+        # make sure all required groups had one option present
+        for group in self._mutually_exclusive_groups:
+            if group.required:
+                for action in group._group_actions:
+                    if action in seen_non_default_actions:
+                        break
+
+                # if no actions were used, report the error
+                else:
+                    names = [_get_action_name(action)
+                             for action in group._group_actions
+                             if action.help is not SUPPRESS]
+                    msg = _('one of the arguments %s is required')
+                    self.error(msg % ' '.join(names))
+
+        # return the updated namespace and the extra arguments
+        return namespace, extras
+
+    def _read_args_from_files(self, arg_strings):
+        # expand arguments referencing files
+        new_arg_strings = []
+        for arg_string in arg_strings:
+
+            # for regular arguments, just add them back into the list
+            if arg_string[0] not in self.fromfile_prefix_chars:
+                new_arg_strings.append(arg_string)
+
+            # replace arguments referencing files with the file content
+            else:
+                try:
+                    args_file = open(arg_string[1:])
+                    try:
+                        arg_strings = []
+                        for arg_line in args_file.read().splitlines():
+                            for arg in self.convert_arg_line_to_args(arg_line):
+                                arg_strings.append(arg)
+                        arg_strings = self._read_args_from_files(arg_strings)
+                        new_arg_strings.extend(arg_strings)
+                    finally:
+                        args_file.close()
+                except IOError:
+                    err = _sys.exc_info()[1]
+                    self.error(str(err))
+
+        # return the modified argument list
+        return new_arg_strings
+
+    def convert_arg_line_to_args(self, arg_line):
+        return [arg_line]
+
+    def _match_argument(self, action, arg_strings_pattern):
+        # match the pattern for this action to the arg strings
+        nargs_pattern = self._get_nargs_pattern(action)
+        match = _re.match(nargs_pattern, arg_strings_pattern)
+
+        # raise an exception if we weren't able to find a match
+        if match is None:
+            nargs_errors = {
+                None: _('expected one argument'),
+                OPTIONAL: _('expected at most one argument'),
+                ONE_OR_MORE: _('expected at least one argument'),
+            }
+            default = _('expected %s argument(s)') % action.nargs
+            msg = nargs_errors.get(action.nargs, default)
+            raise ArgumentError(action, msg)
+
+        # return the number of arguments matched
+        return len(match.group(1))
+
+    def _match_arguments_partial(self, actions, arg_strings_pattern):
+        # progressively shorten the actions list by slicing off the
+        # final actions until we find a match
+        result = []
+        for i in range(len(actions), 0, -1):
+            actions_slice = actions[:i]
+            pattern = ''.join([self._get_nargs_pattern(action)
+                               for action in actions_slice])
+            match = _re.match(pattern, arg_strings_pattern)
+            if match is not None:
+                result.extend([len(string) for string in match.groups()])
+                break
+
+        # return the list of arg string counts
+        return result
+
+    def _parse_optional(self, arg_string):
+        # if it's an empty string, it was meant to be a positional
+        if not arg_string:
+            return None
+
+        # if it doesn't start with a prefix, it was meant to be positional
+        if not arg_string[0] in self.prefix_chars:
+            return None
+
+        # if the option string is present in the parser, return the action
+        if arg_string in self._option_string_actions:
+            action = self._option_string_actions[arg_string]
+            return action, arg_string, None
+
+        # if it's just a single character, it was meant to be positional
+        if len(arg_string) == 1:
+            return None
+
+        # if the option string before the "=" is present, return the action
+        if '=' in arg_string:
+            option_string, explicit_arg = arg_string.split('=', 1)
+            if option_string in self._option_string_actions:
+                action = self._option_string_actions[option_string]
+                return action, option_string, explicit_arg
+
+        # search through all possible prefixes of the option string
+        # and all actions in the parser for possible interpretations
+        option_tuples = self._get_option_tuples(arg_string)
+
+        # if multiple actions match, the option string was ambiguous
+        if len(option_tuples) > 1:
+            options = ', '.join([option_string
+                for action, option_string, explicit_arg in option_tuples])
+            tup = arg_string, options
+            self.error(_('ambiguous option: %s could match %s') % tup)
+
+        # if exactly one action matched, this segmentation is good,
+        # so return the parsed action
+        elif len(option_tuples) == 1:
+            option_tuple, = option_tuples
+            return option_tuple
+
+        # if it was not found as an option, but it looks like a negative
+        # number, it was meant to be positional
+        # unless there are negative-number-like options
+        if self._negative_number_matcher.match(arg_string):
+            if not self._has_negative_number_optionals:
+                return None
+
+        # if it contains a space, it was meant to be a positional
+        if ' ' in arg_string:
+            return None
+
+        # it was meant to be an optional but there is no such option
+        # in this parser (though it might be a valid option in a subparser)
+        return None, arg_string, None
+
+    def _get_option_tuples(self, option_string):
+        result = []
+
+        # option strings starting with two prefix characters are only
+        # split at the '='
+        chars = self.prefix_chars
+        if option_string[0] in chars and option_string[1] in chars:
+            if '=' in option_string:
+                option_prefix, explicit_arg = option_string.split('=', 1)
+            else:
+                option_prefix = option_string
+                explicit_arg = None
+            for option_string in self._option_string_actions:
+                if option_string.startswith(option_prefix):
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, explicit_arg
+                    result.append(tup)
+
+        # single character options can be concatenated with their arguments
+        # but multiple character options always have to have their argument
+        # separate
+        elif option_string[0] in chars and option_string[1] not in chars:
+            option_prefix = option_string
+            explicit_arg = None
+            short_option_prefix = option_string[:2]
+            short_explicit_arg = option_string[2:]
+
+            for option_string in self._option_string_actions:
+                if option_string == short_option_prefix:
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, short_explicit_arg
+                    result.append(tup)
+                elif option_string.startswith(option_prefix):
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, explicit_arg
+                    result.append(tup)
+
+        # shouldn't ever get here
+        else:
+            self.error(_('unexpected option string: %s') % option_string)
+
+        # return the collected option tuples
+        return result
+
+    def _get_nargs_pattern(self, action):
+        # in all examples below, we have to allow for '--' args
+        # which are represented as '-' in the pattern
+        nargs = action.nargs
+
+        # the default (None) is assumed to be a single argument
+        if nargs is None:
+            nargs_pattern = '(-*A-*)'
+
+        # allow zero or one arguments
+        elif nargs == OPTIONAL:
+            nargs_pattern = '(-*A?-*)'
+
+        # allow zero or more arguments
+        elif nargs == ZERO_OR_MORE:
+            nargs_pattern = '(-*[A-]*)'
+
+        # allow one or more arguments
+        elif nargs == ONE_OR_MORE:
+            nargs_pattern = '(-*A[A-]*)'
+
+        # allow any number of options or arguments
+        elif nargs == REMAINDER:
+            nargs_pattern = '([-AO]*)'
+
+        # allow one argument followed by any number of options or arguments
+        elif nargs == PARSER:
+            nargs_pattern = '(-*A[-AO]*)'
+
+        # all others should be integers
+        else:
+            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
+
+        # if this is an optional action, -- is not allowed
+        if action.option_strings:
+            nargs_pattern = nargs_pattern.replace('-*', '')
+            nargs_pattern = nargs_pattern.replace('-', '')
+
+        # return the pattern
+        return nargs_pattern
+
+    # ========================
+    # Value conversion methods
+    # ========================
+    def _get_values(self, action, arg_strings):
+        # for everything but PARSER args, strip out '--'
+        if action.nargs not in [PARSER, REMAINDER]:
+            arg_strings = [s for s in arg_strings if s != '--']
+
+        # optional argument produces a default when not present
+        if not arg_strings and action.nargs == OPTIONAL:
+            if action.option_strings:
+                value = action.const
+            else:
+                value = action.default
+            if isinstance(value, _basestring):
+                value = self._get_value(action, value)
+                self._check_value(action, value)
+
+        # when nargs='*' on a positional, if there were no command-line
+        # args, use the default if it is anything other than None
+        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
+              not action.option_strings):
+            if action.default is not None:
+                value = action.default
+            else:
+                value = arg_strings
+            self._check_value(action, value)
+
+        # single argument or optional argument produces a single value
+        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
+            arg_string, = arg_strings
+            value = self._get_value(action, arg_string)
+            self._check_value(action, value)
+
+        # REMAINDER arguments convert all values, checking none
+        elif action.nargs == REMAINDER:
+            value = [self._get_value(action, v) for v in arg_strings]
+
+        # PARSER arguments convert all values, but check only the first
+        elif action.nargs == PARSER:
+            value = [self._get_value(action, v) for v in arg_strings]
+            self._check_value(action, value[0])
+
+        # all other types of nargs produce a list
+        else:
+            value = [self._get_value(action, v) for v in arg_strings]
+            for v in value:
+                self._check_value(action, v)
+
+        # return the converted value
+        return value
+
+    def _get_value(self, action, arg_string):
+        type_func = self._registry_get('type', action.type, action.type)
+        if not _callable(type_func):
+            msg = _('%r is not callable')
+            raise ArgumentError(action, msg % type_func)
+
+        # convert the value to the appropriate type
+        try:
+            result = type_func(arg_string)
+
+        # ArgumentTypeErrors indicate errors
+        except ArgumentTypeError:
+            name = getattr(action.type, '__name__', repr(action.type))
+            msg = str(_sys.exc_info()[1])
+            raise ArgumentError(action, msg)
+
+        # TypeErrors or ValueErrors also indicate errors
+        except (TypeError, ValueError):
+            name = getattr(action.type, '__name__', repr(action.type))
+            msg = _('invalid %s value: %r')
+            raise ArgumentError(action, msg % (name, arg_string))
+
+        # return the converted value
+        return result
+
+    def _check_value(self, action, value):
+        # converted value must be one of the choices (if specified)
+        if action.choices is not None and value not in action.choices:
+            tup = value, ', '.join(map(repr, action.choices))
+            msg = _('invalid choice: %r (choose from %s)') % tup
+            raise ArgumentError(action, msg)
+
+    # =======================
+    # Help-formatting methods
+    # =======================
+    def format_usage(self):
+        formatter = self._get_formatter()
+        formatter.add_usage(self.usage, self._actions,
+                            self._mutually_exclusive_groups)
+        return formatter.format_help()
+
+    def format_help(self):
+        formatter = self._get_formatter()
+
+        # usage
+        formatter.add_usage(self.usage, self._actions,
+                            self._mutually_exclusive_groups)
+
+        # description
+        formatter.add_text(self.description)
+
+        # positionals, optionals and user-defined groups
+        for action_group in self._action_groups:
+            formatter.start_section(action_group.title)
+            formatter.add_text(action_group.description)
+            formatter.add_arguments(action_group._group_actions)
+            formatter.end_section()
+
+        # epilog
+        formatter.add_text(self.epilog)
+
+        # determine help from format above
+        return formatter.format_help()
+
+    def format_version(self):
+        import warnings
+        warnings.warn(
+            'The format_version method is deprecated -- the "version" '
+            'argument to ArgumentParser is no longer supported.',
+            DeprecationWarning)
+        formatter = self._get_formatter()
+        formatter.add_text(self.version)
+        return formatter.format_help()
+
+    def _get_formatter(self):
+        return self.formatter_class(prog=self.prog)
+
+    # =====================
+    # Help-printing methods
+    # =====================
+    def print_usage(self, file=None):
+        if file is None:
+            file = _sys.stdout
+        self._print_message(self.format_usage(), file)
+
+    def print_help(self, file=None):
+        if file is None:
+            file = _sys.stdout
+        self._print_message(self.format_help(), file)
+
+    def print_version(self, file=None):
+        import warnings
+        warnings.warn(
+            'The print_version method is deprecated -- the "version" '
+            'argument to ArgumentParser is no longer supported.',
+            DeprecationWarning)
+        self._print_message(self.format_version(), file)
+
+    def _print_message(self, message, file=None):
+        if message:
+            if file is None:
+                file = _sys.stderr
+            file.write(message)
+
+    # ===============
+    # Exiting methods
+    # ===============
+    def exit(self, status=0, message=None):
+        if message:
+            self._print_message(message, _sys.stderr)
+        _sys.exit(status)
+
+    def error(self, message):
+        """error(message: string)
+
+        Prints a usage message incorporating the message to stderr and
+        exits.
+
+        If you override this in a subclass, it should not return -- it
+        should either exit or raise an exception.
+        """
+        self.print_usage(_sys.stderr)
+        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index a50a3db..4392e42 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -1,4206 +1,4206 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
-# use this file except in compliance with the License. You may obtain a copy
-# of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import codecs
-import os
-import shutil
-import sys
-import textwrap
-import tempfile
-import unittest
-import argparse
-
-try:
-    from StringIO import StringIO
-except ImportError:
-    from io import StringIO
-
-try:
-    set
-except NameError:
-    from sets import Set as set
-
-try:
-    sorted
-except NameError:
-
-    def sorted(iterable, reverse=False):
-        result = list(iterable)
-        result.sort()
-        if reverse:
-            result.reverse()
-        return result
-
-# silence Python 2.6 buggy warnings about Exception.message
-if sys.version_info[:2] == (2, 6):
-    import warnings
-    warnings.filterwarnings(
-        action='ignore',
-        message='BaseException.message has been deprecated as of Python 2.6',
-        category=DeprecationWarning)
-
-# silence warnings about version argument - these are expected
-import warnings
-warnings.filterwarnings(
-    action='ignore',
-    message='The "version" argument to ArgumentParser is deprecated.',
-    category=DeprecationWarning)
-warnings.filterwarnings(
-    action='ignore',
-    message='The format_version method is deprecated',
-    category=DeprecationWarning)
-warnings.filterwarnings(
-    action='ignore',
-    message='The print_version method is deprecated',
-    category=DeprecationWarning)
-
-
-class TestCase(unittest.TestCase):
-
-    def assertEqual(self, obj1, obj2):
-        if obj1 != obj2:
-            print('')
-            print(repr(obj1))
-            print(repr(obj2))
-            print(obj1)
-            print(obj2)
-        super(TestCase, self).assertEqual(obj1, obj2)
-
-
-class TempDirMixin(object):
-
-    def setUp(self):
-        self.temp_dir = tempfile.mkdtemp()
-        self.old_dir = os.getcwd()
-        os.chdir(self.temp_dir)
-
-    def tearDown(self):
-        os.chdir(self.old_dir)
-        while True:
-            try:
-                shutil.rmtree(self.temp_dir)
-            except WindowsError:
-                continue
-            else:
-                break
-
-
-class Sig(object):
-
-    def __init__(self, *args, **kwargs):
-        self.args = args
-        self.kwargs = kwargs
-
-
-class NS(object):
-
-    def __init__(self, **kwargs):
-        self.__dict__.update(kwargs)
-
-    def __repr__(self):
-        sorted_items = sorted(self.__dict__.items())
-        kwarg_str = ', '.join(['%s=%r' % tup for tup in sorted_items])
-        return '%s(%s)' % (type(self).__name__, kwarg_str)
-
-    def __eq__(self, other):
-        return vars(self) == vars(other)
-
-    def __ne__(self, other):
-        return not (self == other)
-
-
-class ArgumentParserError(Exception):
-
-    def __init__(self, message, stdout=None, stderr=None, error_code=None):
-        Exception.__init__(self, message, stdout, stderr)
-        self.message = message
-        self.stdout = stdout
-        self.stderr = stderr
-        self.error_code = error_code
-
-
-def stderr_to_parser_error(parse_args, *args, **kwargs):
-    # if this is being called recursively and stderr or stdout is already being
-    # redirected, simply call the function and let the enclosing function
-    # catch the exception
-    if isinstance(sys.stderr, StringIO) or isinstance(sys.stdout, StringIO):
-        return parse_args(*args, **kwargs)
-
-    # if this is not being called recursively, redirect stderr and
-    # use it as the ArgumentParserError message
-    old_stdout = sys.stdout
-    old_stderr = sys.stderr
-    sys.stdout = StringIO()
-    sys.stderr = StringIO()
-    try:
-        try:
-            result = parse_args(*args, **kwargs)
-            for key in list(vars(result)):
-                if getattr(result, key) is sys.stdout:
-                    setattr(result, key, old_stdout)
-                if getattr(result, key) is sys.stderr:
-                    setattr(result, key, old_stderr)
-            return result
-        except SystemExit:
-            code = sys.exc_info()[1].code
-            stdout = sys.stdout.getvalue()
-            stderr = sys.stderr.getvalue()
-            raise ArgumentParserError("SystemExit", stdout, stderr, code)
-    finally:
-        sys.stdout = old_stdout
-        sys.stderr = old_stderr
-
-
-class ErrorRaisingArgumentParser(argparse.ArgumentParser):
-
-    def parse_args(self, *args, **kwargs):
-        parse_args = super(ErrorRaisingArgumentParser, self).parse_args
-        return stderr_to_parser_error(parse_args, *args, **kwargs)
-
-    def exit(self, *args, **kwargs):
-        exit = super(ErrorRaisingArgumentParser, self).exit
-        return stderr_to_parser_error(exit, *args, **kwargs)
-
-    def error(self, *args, **kwargs):
-        error = super(ErrorRaisingArgumentParser, self).error
-        return stderr_to_parser_error(error, *args, **kwargs)
-
-
-class ParserTesterMetaclass(type):
-    """Adds parser tests using the class attributes.
-
-    Classes of this type should specify the following attributes:
-
-    argument_signatures -- a list of Sig objects which specify
-        the signatures of Argument objects to be created
-    failures -- a list of args lists that should cause the parser
-        to fail
-    successes -- a list of (initial_args, options, remaining_args) tuples
-        where initial_args specifies the string args to be parsed,
-        options is a dict that should match the vars() of the options
-        parsed out of initial_args, and remaining_args should be any
-        remaining unparsed arguments
-    """
-
-    def __init__(cls, name, bases, bodydict):
-        if name == 'ParserTestCase':
-            return
-
-        # default parser signature is empty
-        if not hasattr(cls, 'parser_signature'):
-            cls.parser_signature = Sig()
-        if not hasattr(cls, 'parser_class'):
-            cls.parser_class = ErrorRaisingArgumentParser
-
-        # ---------------------------------------
-        # functions for adding optional arguments
-        # ---------------------------------------
-        def no_groups(parser, argument_signatures):
-            """Add all arguments directly to the parser"""
-            for sig in argument_signatures:
-                parser.add_argument(*sig.args, **sig.kwargs)
-
-        def one_group(parser, argument_signatures):
-            """Add all arguments under a single group in the parser"""
-            group = parser.add_argument_group('foo')
-            for sig in argument_signatures:
-                group.add_argument(*sig.args, **sig.kwargs)
-
-        def many_groups(parser, argument_signatures):
-            """Add each argument in its own group to the parser"""
-            for i, sig in enumerate(argument_signatures):
-                group = parser.add_argument_group('foo:%i' % i)
-                group.add_argument(*sig.args, **sig.kwargs)
-
-        # --------------------------
-        # functions for parsing args
-        # --------------------------
-        def listargs(parser, args):
-            """Parse the args by passing in a list"""
-            return parser.parse_args(args)
-
-        def sysargs(parser, args):
-            """Parse the args by defaulting to sys.argv"""
-            old_sys_argv = sys.argv
-            sys.argv = [old_sys_argv[0]] + args
-            try:
-                return parser.parse_args()
-            finally:
-                sys.argv = old_sys_argv
-
-        # class that holds the combination of one optional argument
-        # addition method and one arg parsing method
-        class AddTests(object):
-
-            def __init__(self, tester_cls, add_arguments, parse_args):
-                self._add_arguments = add_arguments
-                self._parse_args = parse_args
-
-                add_arguments_name = self._add_arguments.__name__
-                parse_args_name = self._parse_args.__name__
-                for test_func in [self.test_failures, self.test_successes]:
-                    func_name = test_func.__name__
-                    names = func_name, add_arguments_name, parse_args_name
-                    test_name = '_'.join(names)
-
-                    def wrapper(self, test_func=test_func):
-                        test_func(self)
-                    try:
-                        wrapper.__name__ = test_name
-                    except TypeError:
-                        pass
-                    setattr(tester_cls, test_name, wrapper)
-
-            def _get_parser(self, tester):
-                args = tester.parser_signature.args
-                kwargs = tester.parser_signature.kwargs
-                parser = tester.parser_class(*args, **kwargs)
-                self._add_arguments(parser, tester.argument_signatures)
-                return parser
-
-            def test_failures(self, tester):
-                parser = self._get_parser(tester)
-                for args_str in tester.failures:
-                    args = args_str.split()
-                    raises = tester.assertRaises
-                    raises(ArgumentParserError, parser.parse_args, args)
-
-            def test_successes(self, tester):
-                parser = self._get_parser(tester)
-                for args, expected_ns in tester.successes:
-                    if isinstance(args, str):
-                        args = args.split()
-                    result_ns = self._parse_args(parser, args)
-                    tester.assertEqual(expected_ns, result_ns)
-
-        # add tests for each combination of an optionals adding method
-        # and an arg parsing method
-        for add_arguments in [no_groups, one_group, many_groups]:
-            for parse_args in [listargs, sysargs]:
-                AddTests(cls, add_arguments, parse_args)
-
-bases = TestCase,
-ParserTestCase = ParserTesterMetaclass('ParserTestCase', bases, {})
-
-# ===============
-# Optionals tests
-# ===============
-
-class TestOptionalsSingleDash(ParserTestCase):
-    """Test an Optional with a single-dash option string"""
-
-    argument_signatures = [Sig('-x')]
-    failures = ['-x', 'a', '--foo', '-x --foo', '-x -y']
-    successes = [
-        ('', NS(x=None)),
-        ('-x a', NS(x='a')),
-        ('-xa', NS(x='a')),
-        ('-x -1', NS(x='-1')),
-        ('-x-1', NS(x='-1')),
-    ]
-
-
-class TestOptionalsSingleDashCombined(ParserTestCase):
-    """Test an Optional with a single-dash option string"""
-
-    argument_signatures = [
-        Sig('-x', action='store_true'),
-        Sig('-yyy', action='store_const', const=42),
-        Sig('-z'),
-    ]
-    failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x',
-                '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza']
-    successes = [
-        ('', NS(x=False, yyy=None, z=None)),
-        ('-x', NS(x=True, yyy=None, z=None)),
-        ('-za', NS(x=False, yyy=None, z='a')),
-        ('-z a', NS(x=False, yyy=None, z='a')),
-        ('-xza', NS(x=True, yyy=None, z='a')),
-        ('-xz a', NS(x=True, yyy=None, z='a')),
-        ('-x -za', NS(x=True, yyy=None, z='a')),
-        ('-x -z a', NS(x=True, yyy=None, z='a')),
-        ('-y', NS(x=False, yyy=42, z=None)),
-        ('-yyy', NS(x=False, yyy=42, z=None)),
-        ('-x -yyy -za', NS(x=True, yyy=42, z='a')),
-        ('-x -yyy -z a', NS(x=True, yyy=42, z='a')),
-    ]
-
-
-class TestOptionalsSingleDashLong(ParserTestCase):
-    """Test an Optional with a multi-character single-dash option string"""
-
-    argument_signatures = [Sig('-foo')]
-    failures = ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa']
-    successes = [
-        ('', NS(foo=None)),
-        ('-foo a', NS(foo='a')),
-        ('-foo -1', NS(foo='-1')),
-        ('-fo a', NS(foo='a')),
-        ('-f a', NS(foo='a')),
-    ]
-
-
-class TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase):
-    """Test Optionals where option strings are subsets of each other"""
-
-    argument_signatures = [Sig('-f'), Sig('-foobar'), Sig('-foorab')]
-    failures = ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora']
-    successes = [
-        ('', NS(f=None, foobar=None, foorab=None)),
-        ('-f a', NS(f='a', foobar=None, foorab=None)),
-        ('-fa', NS(f='a', foobar=None, foorab=None)),
-        ('-foa', NS(f='oa', foobar=None, foorab=None)),
-        ('-fooa', NS(f='ooa', foobar=None, foorab=None)),
-        ('-foobar a', NS(f=None, foobar='a', foorab=None)),
-        ('-foorab a', NS(f=None, foobar=None, foorab='a')),
-    ]
-
-
-class TestOptionalsSingleDashAmbiguous(ParserTestCase):
-    """Test Optionals that partially match but are not subsets"""
-
-    argument_signatures = [Sig('-foobar'), Sig('-foorab')]
-    failures = ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b']
-    successes = [
-        ('', NS(foobar=None, foorab=None)),
-        ('-foob a', NS(foobar='a', foorab=None)),
-        ('-foor a', NS(foobar=None, foorab='a')),
-        ('-fooba a', NS(foobar='a', foorab=None)),
-        ('-foora a', NS(foobar=None, foorab='a')),
-        ('-foobar a', NS(foobar='a', foorab=None)),
-        ('-foorab a', NS(foobar=None, foorab='a')),
-    ]
-
-
-class TestOptionalsNumeric(ParserTestCase):
-    """Test an Optional with a short opt string"""
-
-    argument_signatures = [Sig('-1', dest='one')]
-    failures = ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2']
-    successes = [
-        ('', NS(one=None)),
-        ('-1 a', NS(one='a')),
-        ('-1a', NS(one='a')),
-        ('-1-2', NS(one='-2')),
-    ]
-
-
-class TestOptionalsDoubleDash(ParserTestCase):
-    """Test an Optional with a double-dash option string"""
-
-    argument_signatures = [Sig('--foo')]
-    failures = ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar']
-    successes = [
-        ('', NS(foo=None)),
-        ('--foo a', NS(foo='a')),
-        ('--foo=a', NS(foo='a')),
-        ('--foo -2.5', NS(foo='-2.5')),
-        ('--foo=-2.5', NS(foo='-2.5')),
-    ]
-
-
-class TestOptionalsDoubleDashPartialMatch(ParserTestCase):
-    """Tests partial matching with a double-dash option string"""
-
-    argument_signatures = [
-        Sig('--badger', action='store_true'),
-        Sig('--bat'),
-    ]
-    failures = ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5']
-    successes = [
-        ('', NS(badger=False, bat=None)),
-        ('--bat X', NS(badger=False, bat='X')),
-        ('--bad', NS(badger=True, bat=None)),
-        ('--badg', NS(badger=True, bat=None)),
-        ('--badge', NS(badger=True, bat=None)),
-        ('--badger', NS(badger=True, bat=None)),
-    ]
-
-
-class TestOptionalsDoubleDashPrefixMatch(ParserTestCase):
-    """Tests when one double-dash option string is a prefix of another"""
-
-    argument_signatures = [
-        Sig('--badger', action='store_true'),
-        Sig('--ba'),
-    ]
-    failures = ['--bar', '--b', '--ba', '--b=2', '--badge 5']
-    successes = [
-        ('', NS(badger=False, ba=None)),
-        ('--ba X', NS(badger=False, ba='X')),
-        ('--ba=X', NS(badger=False, ba='X')),
-        ('--bad', NS(badger=True, ba=None)),
-        ('--badg', NS(badger=True, ba=None)),
-        ('--badge', NS(badger=True, ba=None)),
-        ('--badger', NS(badger=True, ba=None)),
-    ]
-
-
-class TestOptionalsSingleDoubleDash(ParserTestCase):
-    """Test an Optional with single- and double-dash option strings"""
-
-    argument_signatures = [
-        Sig('-f', action='store_true'),
-        Sig('--bar'),
-        Sig('-baz', action='store_const', const=42),
-    ]
-    failures = ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B']
-    successes = [
-        ('', NS(f=False, bar=None, baz=None)),
-        ('-f', NS(f=True, bar=None, baz=None)),
-        ('--ba B', NS(f=False, bar='B', baz=None)),
-        ('-f --bar B', NS(f=True, bar='B', baz=None)),
-        ('-f -b', NS(f=True, bar=None, baz=42)),
-        ('-ba -f', NS(f=True, bar=None, baz=42)),
-    ]
-
-
-class TestOptionalsAlternatePrefixChars(ParserTestCase):
-    """Test an Optional with a double-dash option string"""
-
-    parser_signature = Sig(prefix_chars='+:/', add_help=False)
-    argument_signatures = [
-        Sig('+f', action='store_true'),
-        Sig('::bar'),
-        Sig('/baz', action='store_const', const=42),
-    ]
-    failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
-    successes = [
-        ('', NS(f=False, bar=None, baz=None)),
-        ('+f', NS(f=True, bar=None, baz=None)),
-        ('::ba B', NS(f=False, bar='B', baz=None)),
-        ('+f ::bar B', NS(f=True, bar='B', baz=None)),
-        ('+f /b', NS(f=True, bar=None, baz=42)),
-        ('/ba +f', NS(f=True, bar=None, baz=42)),
-    ]
-
-
-class TestOptionalsShortLong(ParserTestCase):
-    """Test a combination of single- and double-dash option strings"""
-
-    argument_signatures = [
-        Sig('-v', '--verbose', '-n', '--noisy', action='store_true'),
-    ]
-    failures = ['--x --verbose', '-N', 'a', '-v x']
-    successes = [
-        ('', NS(verbose=False)),
-        ('-v', NS(verbose=True)),
-        ('--verbose', NS(verbose=True)),
-        ('-n', NS(verbose=True)),
-        ('--noisy', NS(verbose=True)),
-    ]
-
-
-class TestOptionalsDest(ParserTestCase):
-    """Tests various means of setting destination"""
-
-    argument_signatures = [Sig('--foo-bar'), Sig('--baz', dest='zabbaz')]
-    failures = ['a']
-    successes = [
-        ('--foo-bar f', NS(foo_bar='f', zabbaz=None)),
-        ('--baz g', NS(foo_bar=None, zabbaz='g')),
-        ('--foo-bar h --baz i', NS(foo_bar='h', zabbaz='i')),
-        ('--baz j --foo-bar k', NS(foo_bar='k', zabbaz='j')),
-    ]
-
-
-class TestOptionalsDefault(ParserTestCase):
-    """Tests specifying a default for an Optional"""
-
-    argument_signatures = [Sig('-x'), Sig('-y', default=42)]
-    failures = ['a']
-    successes = [
-        ('', NS(x=None, y=42)),
-        ('-xx', NS(x='x', y=42)),
-        ('-yy', NS(x=None, y='y')),
-    ]
-
-
-class TestOptionalsNargsDefault(ParserTestCase):
-    """Tests not specifying the number of args for an Optional"""
-
-    argument_signatures = [Sig('-x')]
-    failures = ['a', '-x']
-    successes = [
-        ('', NS(x=None)),
-        ('-x a', NS(x='a')),
-    ]
-
-
-class TestOptionalsNargs1(ParserTestCase):
-    """Tests specifying the 1 arg for an Optional"""
-
-    argument_signatures = [Sig('-x', nargs=1)]
-    failures = ['a', '-x']
-    successes = [
-        ('', NS(x=None)),
-        ('-x a', NS(x=['a'])),
-    ]
-
-
-class TestOptionalsNargs3(ParserTestCase):
-    """Tests specifying the 3 args for an Optional"""
-
-    argument_signatures = [Sig('-x', nargs=3)]
-    failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
-    successes = [
-        ('', NS(x=None)),
-        ('-x a b c', NS(x=['a', 'b', 'c'])),
-    ]
-
-
-class TestOptionalsNargsOptional(ParserTestCase):
-    """Tests specifying an Optional arg for an Optional"""
-
-    argument_signatures = [
-        Sig('-w', nargs='?'),
-        Sig('-x', nargs='?', const=42),
-        Sig('-y', nargs='?', default='spam'),
-        Sig('-z', nargs='?', type=int, const='42', default='84'),
-    ]
-    failures = ['2']
-    successes = [
-        ('', NS(w=None, x=None, y='spam', z=84)),
-        ('-w', NS(w=None, x=None, y='spam', z=84)),
-        ('-w 2', NS(w='2', x=None, y='spam', z=84)),
-        ('-x', NS(w=None, x=42, y='spam', z=84)),
-        ('-x 2', NS(w=None, x='2', y='spam', z=84)),
-        ('-y', NS(w=None, x=None, y=None, z=84)),
-        ('-y 2', NS(w=None, x=None, y='2', z=84)),
-        ('-z', NS(w=None, x=None, y='spam', z=42)),
-        ('-z 2', NS(w=None, x=None, y='spam', z=2)),
-    ]
-
-
-class TestOptionalsNargsZeroOrMore(ParserTestCase):
-    """Tests specifying an args for an Optional that accepts zero or more"""
-
-    argument_signatures = [
-        Sig('-x', nargs='*'),
-        Sig('-y', nargs='*', default='spam'),
-    ]
-    failures = ['a']
-    successes = [
-        ('', NS(x=None, y='spam')),
-        ('-x', NS(x=[], y='spam')),
-        ('-x a', NS(x=['a'], y='spam')),
-        ('-x a b', NS(x=['a', 'b'], y='spam')),
-        ('-y', NS(x=None, y=[])),
-        ('-y a', NS(x=None, y=['a'])),
-        ('-y a b', NS(x=None, y=['a', 'b'])),
-    ]
-
-
-class TestOptionalsNargsOneOrMore(ParserTestCase):
-    """Tests specifying an args for an Optional that accepts one or more"""
-
-    argument_signatures = [
-        Sig('-x', nargs='+'),
-        Sig('-y', nargs='+', default='spam'),
-    ]
-    failures = ['a', '-x', '-y', 'a -x', 'a -y b']
-    successes = [
-        ('', NS(x=None, y='spam')),
-        ('-x a', NS(x=['a'], y='spam')),
-        ('-x a b', NS(x=['a', 'b'], y='spam')),
-        ('-y a', NS(x=None, y=['a'])),
-        ('-y a b', NS(x=None, y=['a', 'b'])),
-    ]
-
-
-class TestOptionalsChoices(ParserTestCase):
-    """Tests specifying the choices for an Optional"""
-
-    argument_signatures = [
-        Sig('-f', choices='abc'),
-        Sig('-g', type=int, choices=range(5))]
-    failures = ['a', '-f d', '-fad', '-ga', '-g 6']
-    successes = [
-        ('', NS(f=None, g=None)),
-        ('-f a', NS(f='a', g=None)),
-        ('-f c', NS(f='c', g=None)),
-        ('-g 0', NS(f=None, g=0)),
-        ('-g 03', NS(f=None, g=3)),
-        ('-fb -g4', NS(f='b', g=4)),
-    ]
-
-
-class TestOptionalsRequired(ParserTestCase):
-    """Tests the an optional action that is required"""
-
-    argument_signatures = [
-        Sig('-x', type=int, required=True),
-    ]
-    failures = ['a', '']
-    successes = [
-        ('-x 1', NS(x=1)),
-        ('-x42', NS(x=42)),
-    ]
-
-
-class TestOptionalsActionStore(ParserTestCase):
-    """Tests the store action for an Optional"""
-
-    argument_signatures = [Sig('-x', action='store')]
-    failures = ['a', 'a -x']
-    successes = [
-        ('', NS(x=None)),
-        ('-xfoo', NS(x='foo')),
-    ]
-
-
-class TestOptionalsActionStoreConst(ParserTestCase):
-    """Tests the store_const action for an Optional"""
-
-    argument_signatures = [Sig('-y', action='store_const', const=object)]
-    failures = ['a']
-    successes = [
-        ('', NS(y=None)),
-        ('-y', NS(y=object)),
-    ]
-
-
-class TestOptionalsActionStoreFalse(ParserTestCase):
-    """Tests the store_false action for an Optional"""
-
-    argument_signatures = [Sig('-z', action='store_false')]
-    failures = ['a', '-za', '-z a']
-    successes = [
-        ('', NS(z=True)),
-        ('-z', NS(z=False)),
-    ]
-
-
-class TestOptionalsActionStoreTrue(ParserTestCase):
-    """Tests the store_true action for an Optional"""
-
-    argument_signatures = [Sig('--apple', action='store_true')]
-    failures = ['a', '--apple=b', '--apple b']
-    successes = [
-        ('', NS(apple=False)),
-        ('--apple', NS(apple=True)),
-    ]
-
-
-class TestOptionalsActionAppend(ParserTestCase):
-    """Tests the append action for an Optional"""
-
-    argument_signatures = [Sig('--baz', action='append')]
-    failures = ['a', '--baz', 'a --baz', '--baz a b']
-    successes = [
-        ('', NS(baz=None)),
-        ('--baz a', NS(baz=['a'])),
-        ('--baz a --baz b', NS(baz=['a', 'b'])),
-    ]
-
-
-class TestOptionalsActionAppendWithDefault(ParserTestCase):
-    """Tests the append action for an Optional"""
-
-    argument_signatures = [Sig('--baz', action='append', default=['X'])]
-    failures = ['a', '--baz', 'a --baz', '--baz a b']
-    successes = [
-        ('', NS(baz=['X'])),
-        ('--baz a', NS(baz=['X', 'a'])),
-        ('--baz a --baz b', NS(baz=['X', 'a', 'b'])),
-    ]
-
-
-class TestOptionalsActionAppendConst(ParserTestCase):
-    """Tests the append_const action for an Optional"""
-
-    argument_signatures = [
-        Sig('-b', action='append_const', const=Exception),
-        Sig('-c', action='append', dest='b'),
-    ]
-    failures = ['a', '-c', 'a -c', '-bx', '-b x']
-    successes = [
-        ('', NS(b=None)),
-        ('-b', NS(b=[Exception])),
-        ('-b -cx -b -cyz', NS(b=[Exception, 'x', Exception, 'yz'])),
-    ]
-
-
-class TestOptionalsActionAppendConstWithDefault(ParserTestCase):
-    """Tests the append_const action for an Optional"""
-
-    argument_signatures = [
-        Sig('-b', action='append_const', const=Exception, default=['X']),
-        Sig('-c', action='append', dest='b'),
-    ]
-    failures = ['a', '-c', 'a -c', '-bx', '-b x']
-    successes = [
-        ('', NS(b=['X'])),
-        ('-b', NS(b=['X', Exception])),
-        ('-b -cx -b -cyz', NS(b=['X', Exception, 'x', Exception, 'yz'])),
-    ]
-
-
-class TestOptionalsActionCount(ParserTestCase):
-    """Tests the count action for an Optional"""
-
-    argument_signatures = [Sig('-x', action='count')]
-    failures = ['a', '-x a', '-x b', '-x a -x b']
-    successes = [
-        ('', NS(x=None)),
-        ('-x', NS(x=1)),
-    ]
-
-
-# ================
-# Positional tests
-# ================
-
-class TestPositionalsNargsNone(ParserTestCase):
-    """Test a Positional that doesn't specify nargs"""
-
-    argument_signatures = [Sig('foo')]
-    failures = ['', '-x', 'a b']
-    successes = [
-        ('a', NS(foo='a')),
-    ]
-
-
-class TestPositionalsNargs1(ParserTestCase):
-    """Test a Positional that specifies an nargs of 1"""
-
-    argument_signatures = [Sig('foo', nargs=1)]
-    failures = ['', '-x', 'a b']
-    successes = [
-        ('a', NS(foo=['a'])),
-    ]
-
-
-class TestPositionalsNargs2(ParserTestCase):
-    """Test a Positional that specifies an nargs of 2"""
-
-    argument_signatures = [Sig('foo', nargs=2)]
-    failures = ['', 'a', '-x', 'a b c']
-    successes = [
-        ('a b', NS(foo=['a', 'b'])),
-    ]
-
-
-class TestPositionalsNargsZeroOrMore(ParserTestCase):
-    """Test a Positional that specifies unlimited nargs"""
-
-    argument_signatures = [Sig('foo', nargs='*')]
-    failures = ['-x']
-    successes = [
-        ('', NS(foo=[])),
-        ('a', NS(foo=['a'])),
-        ('a b', NS(foo=['a', 'b'])),
-    ]
-
-
-class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase):
-    """Test a Positional that specifies unlimited nargs and a default"""
-
-    argument_signatures = [Sig('foo', nargs='*', default='bar')]
-    failures = ['-x']
-    successes = [
-        ('', NS(foo='bar')),
-        ('a', NS(foo=['a'])),
-        ('a b', NS(foo=['a', 'b'])),
-    ]
-
-
-class TestPositionalsNargsOneOrMore(ParserTestCase):
-    """Test a Positional that specifies one or more nargs"""
-
-    argument_signatures = [Sig('foo', nargs='+')]
-    failures = ['', '-x']
-    successes = [
-        ('a', NS(foo=['a'])),
-        ('a b', NS(foo=['a', 'b'])),
-    ]
-
-
-class TestPositionalsNargsOptional(ParserTestCase):
-    """Tests an Optional Positional"""
-
-    argument_signatures = [Sig('foo', nargs='?')]
-    failures = ['-x', 'a b']
-    successes = [
-        ('', NS(foo=None)),
-        ('a', NS(foo='a')),
-    ]
-
-
-class TestPositionalsNargsOptionalDefault(ParserTestCase):
-    """Tests an Optional Positional with a default value"""
-
-    argument_signatures = [Sig('foo', nargs='?', default=42)]
-    failures = ['-x', 'a b']
-    successes = [
-        ('', NS(foo=42)),
-        ('a', NS(foo='a')),
-    ]
-
-
-class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase):
-    """Tests an Optional Positional with a default value
-    that needs to be converted to the appropriate type.
-    """
-
-    argument_signatures = [
-        Sig('foo', nargs='?', type=int, default='42'),
-    ]
-    failures = ['-x', 'a b', '1 2']
-    successes = [
-        ('', NS(foo=42)),
-        ('1', NS(foo=1)),
-    ]
-
-
-class TestPositionalsNargsNoneNone(ParserTestCase):
-    """Test two Positionals that don't specify nargs"""
-
-    argument_signatures = [Sig('foo'), Sig('bar')]
-    failures = ['', '-x', 'a', 'a b c']
-    successes = [
-        ('a b', NS(foo='a', bar='b')),
-    ]
-
-
-class TestPositionalsNargsNone1(ParserTestCase):
-    """Test a Positional with no nargs followed by one with 1"""
-
-    argument_signatures = [Sig('foo'), Sig('bar', nargs=1)]
-    failures = ['', '--foo', 'a', 'a b c']
-    successes = [
-        ('a b', NS(foo='a', bar=['b'])),
-    ]
-
-
-class TestPositionalsNargs2None(ParserTestCase):
-    """Test a Positional with 2 nargs followed by one with none"""
-
-    argument_signatures = [Sig('foo', nargs=2), Sig('bar')]
-    failures = ['', '--foo', 'a', 'a b', 'a b c d']
-    successes = [
-        ('a b c', NS(foo=['a', 'b'], bar='c')),
-    ]
-
-
-class TestPositionalsNargsNoneZeroOrMore(ParserTestCase):
-    """Test a Positional with no nargs followed by one with unlimited"""
-
-    argument_signatures = [Sig('foo'), Sig('bar', nargs='*')]
-    failures = ['', '--foo']
-    successes = [
-        ('a', NS(foo='a', bar=[])),
-        ('a b', NS(foo='a', bar=['b'])),
-        ('a b c', NS(foo='a', bar=['b', 'c'])),
-    ]
-
-
-class TestPositionalsNargsNoneOneOrMore(ParserTestCase):
-    """Test a Positional with no nargs followed by one with one or more"""
-
-    argument_signatures = [Sig('foo'), Sig('bar', nargs='+')]
-    failures = ['', '--foo', 'a']
-    successes = [
-        ('a b', NS(foo='a', bar=['b'])),
-        ('a b c', NS(foo='a', bar=['b', 'c'])),
-    ]
-
-
-class TestPositionalsNargsNoneOptional(ParserTestCase):
-    """Test a Positional with no nargs followed by one with an Optional"""
-
-    argument_signatures = [Sig('foo'), Sig('bar', nargs='?')]
-    failures = ['', '--foo', 'a b c']
-    successes = [
-        ('a', NS(foo='a', bar=None)),
-        ('a b', NS(foo='a', bar='b')),
-    ]
-
-
-class TestPositionalsNargsZeroOrMoreNone(ParserTestCase):
-    """Test a Positional with unlimited nargs followed by one with none"""
-
-    argument_signatures = [Sig('foo', nargs='*'), Sig('bar')]
-    failures = ['', '--foo']
-    successes = [
-        ('a', NS(foo=[], bar='a')),
-        ('a b', NS(foo=['a'], bar='b')),
-        ('a b c', NS(foo=['a', 'b'], bar='c')),
-    ]
-
-
-class TestPositionalsNargsOneOrMoreNone(ParserTestCase):
-    """Test a Positional with one or more nargs followed by one with none"""
-
-    argument_signatures = [Sig('foo', nargs='+'), Sig('bar')]
-    failures = ['', '--foo', 'a']
-    successes = [
-        ('a b', NS(foo=['a'], bar='b')),
-        ('a b c', NS(foo=['a', 'b'], bar='c')),
-    ]
-
-
-class TestPositionalsNargsOptionalNone(ParserTestCase):
-    """Test a Positional with an Optional nargs followed by one with none"""
-
-    argument_signatures = [Sig('foo', nargs='?', default=42), Sig('bar')]
-    failures = ['', '--foo', 'a b c']
-    successes = [
-        ('a', NS(foo=42, bar='a')),
-        ('a b', NS(foo='a', bar='b')),
-    ]
-
-
-class TestPositionalsNargs2ZeroOrMore(ParserTestCase):
-    """Test a Positional with 2 nargs followed by one with unlimited"""
-
-    argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='*')]
-    failures = ['', '--foo', 'a']
-    successes = [
-        ('a b', NS(foo=['a', 'b'], bar=[])),
-        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
-    ]
-
-
-class TestPositionalsNargs2OneOrMore(ParserTestCase):
-    """Test a Positional with 2 nargs followed by one with one or more"""
-
-    argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='+')]
-    failures = ['', '--foo', 'a', 'a b']
-    successes = [
-        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
-    ]
-
-
-class TestPositionalsNargs2Optional(ParserTestCase):
-    """Test a Positional with 2 nargs followed by one optional"""
-
-    argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='?')]
-    failures = ['', '--foo', 'a', 'a b c d']
-    successes = [
-        ('a b', NS(foo=['a', 'b'], bar=None)),
-        ('a b c', NS(foo=['a', 'b'], bar='c')),
-    ]
-
-
-class TestPositionalsNargsZeroOrMore1(ParserTestCase):
-    """Test a Positional with unlimited nargs followed by one with 1"""
-
-    argument_signatures = [Sig('foo', nargs='*'), Sig('bar', nargs=1)]
-    failures = ['', '--foo', ]
-    successes = [
-        ('a', NS(foo=[], bar=['a'])),
-        ('a b', NS(foo=['a'], bar=['b'])),
-        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
-    ]
-
-
-class TestPositionalsNargsOneOrMore1(ParserTestCase):
-    """Test a Positional with one or more nargs followed by one with 1"""
-
-    argument_signatures = [Sig('foo', nargs='+'), Sig('bar', nargs=1)]
-    failures = ['', '--foo', 'a']
-    successes = [
-        ('a b', NS(foo=['a'], bar=['b'])),
-        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
-    ]
-
-
-class TestPositionalsNargsOptional1(ParserTestCase):
-    """Test a Positional with an Optional nargs followed by one with 1"""
-
-    argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs=1)]
-    failures = ['', '--foo', 'a b c']
-    successes = [
-        ('a', NS(foo=None, bar=['a'])),
-        ('a b', NS(foo='a', bar=['b'])),
-    ]
-
-
-class TestPositionalsNargsNoneZeroOrMore1(ParserTestCase):
-    """Test three Positionals: no nargs, unlimited nargs and 1 nargs"""
-
-    argument_signatures = [
-        Sig('foo'),
-        Sig('bar', nargs='*'),
-        Sig('baz', nargs=1),
-    ]
-    failures = ['', '--foo', 'a']
-    successes = [
-        ('a b', NS(foo='a', bar=[], baz=['b'])),
-        ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
-    ]
-
-
-class TestPositionalsNargsNoneOneOrMore1(ParserTestCase):
-    """Test three Positionals: no nargs, one or more nargs and 1 nargs"""
-
-    argument_signatures = [
-        Sig('foo'),
-        Sig('bar', nargs='+'),
-        Sig('baz', nargs=1),
-    ]
-    failures = ['', '--foo', 'a', 'b']
-    successes = [
-        ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
-        ('a b c d', NS(foo='a', bar=['b', 'c'], baz=['d'])),
-    ]
-
-
-class TestPositionalsNargsNoneOptional1(ParserTestCase):
-    """Test three Positionals: no nargs, optional narg and 1 nargs"""
-
-    argument_signatures = [
-        Sig('foo'),
-        Sig('bar', nargs='?', default=0.625),
-        Sig('baz', nargs=1),
-    ]
-    failures = ['', '--foo', 'a']
-    successes = [
-        ('a b', NS(foo='a', bar=0.625, baz=['b'])),
-        ('a b c', NS(foo='a', bar='b', baz=['c'])),
-    ]
-
-
-class TestPositionalsNargsOptionalOptional(ParserTestCase):
-    """Test two optional nargs"""
-
-    argument_signatures = [
-        Sig('foo', nargs='?'),
-        Sig('bar', nargs='?', default=42),
-    ]
-    failures = ['--foo', 'a b c']
-    successes = [
-        ('', NS(foo=None, bar=42)),
-        ('a', NS(foo='a', bar=42)),
-        ('a b', NS(foo='a', bar='b')),
-    ]
-
-
-class TestPositionalsNargsOptionalZeroOrMore(ParserTestCase):
-    """Test an Optional narg followed by unlimited nargs"""
-
-    argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='*')]
-    failures = ['--foo']
-    successes = [
-        ('', NS(foo=None, bar=[])),
-        ('a', NS(foo='a', bar=[])),
-        ('a b', NS(foo='a', bar=['b'])),
-        ('a b c', NS(foo='a', bar=['b', 'c'])),
-    ]
-
-
-class TestPositionalsNargsOptionalOneOrMore(ParserTestCase):
-    """Test an Optional narg followed by one or more nargs"""
-
-    argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='+')]
-    failures = ['', '--foo']
-    successes = [
-        ('a', NS(foo=None, bar=['a'])),
-        ('a b', NS(foo='a', bar=['b'])),
-        ('a b c', NS(foo='a', bar=['b', 'c'])),
-    ]
-
-
-class TestPositionalsChoicesString(ParserTestCase):
-    """Test a set of single-character choices"""
-
-    argument_signatures = [Sig('spam', choices=set('abcdefg'))]
-    failures = ['', '--foo', 'h', '42', 'ef']
-    successes = [
-        ('a', NS(spam='a')),
-        ('g', NS(spam='g')),
-    ]
-
-
-class TestPositionalsChoicesInt(ParserTestCase):
-    """Test a set of integer choices"""
-
-    argument_signatures = [Sig('spam', type=int, choices=range(20))]
-    failures = ['', '--foo', 'h', '42', 'ef']
-    successes = [
-        ('4', NS(spam=4)),
-        ('15', NS(spam=15)),
-    ]
-
-
-class TestPositionalsActionAppend(ParserTestCase):
-    """Test the 'append' action"""
-
-    argument_signatures = [
-        Sig('spam', action='append'),
-        Sig('spam', action='append', nargs=2),
-    ]
-    failures = ['', '--foo', 'a', 'a b', 'a b c d']
-    successes = [
-        ('a b c', NS(spam=['a', ['b', 'c']])),
-    ]
-
-# ========================================
-# Combined optionals and positionals tests
-# ========================================
-
-class TestOptionalsNumericAndPositionals(ParserTestCase):
-    """Tests negative number args when numeric options are present"""
-
-    argument_signatures = [
-        Sig('x', nargs='?'),
-        Sig('-4', dest='y', action='store_true'),
-    ]
-    failures = ['-2', '-315']
-    successes = [
-        ('', NS(x=None, y=False)),
-        ('a', NS(x='a', y=False)),
-        ('-4', NS(x=None, y=True)),
-        ('-4 a', NS(x='a', y=True)),
-    ]
-
-
-class TestOptionalsAlmostNumericAndPositionals(ParserTestCase):
-    """Tests negative number args when almost numeric options are present"""
-
-    argument_signatures = [
-        Sig('x', nargs='?'),
-        Sig('-k4', dest='y', action='store_true'),
-    ]
-    failures = ['-k3']
-    successes = [
-        ('', NS(x=None, y=False)),
-        ('-2', NS(x='-2', y=False)),
-        ('a', NS(x='a', y=False)),
-        ('-k4', NS(x=None, y=True)),
-        ('-k4 a', NS(x='a', y=True)),
-    ]
-
-
-class TestEmptyAndSpaceContainingArguments(ParserTestCase):
-
-    argument_signatures = [
-        Sig('x', nargs='?'),
-        Sig('-y', '--yyy', dest='y'),
-    ]
-    failures = ['-y']
-    successes = [
-        ([''], NS(x='', y=None)),
-        (['a badger'], NS(x='a badger', y=None)),
-        (['-a badger'], NS(x='-a badger', y=None)),
-        (['-y', ''], NS(x=None, y='')),
-        (['-y', 'a badger'], NS(x=None, y='a badger')),
-        (['-y', '-a badger'], NS(x=None, y='-a badger')),
-        (['--yyy=a badger'], NS(x=None, y='a badger')),
-        (['--yyy=-a badger'], NS(x=None, y='-a badger')),
-    ]
-
-
-class TestPrefixCharacterOnlyArguments(ParserTestCase):
-
-    parser_signature = Sig(prefix_chars='-+')
-    argument_signatures = [
-        Sig('-', dest='x', nargs='?', const='badger'),
-        Sig('+', dest='y', type=int, default=42),
-        Sig('-+-', dest='z', action='store_true'),
-    ]
-    failures = ['-y', '+ -']
-    successes = [
-        ('', NS(x=None, y=42, z=False)),
-        ('-', NS(x='badger', y=42, z=False)),
-        ('- X', NS(x='X', y=42, z=False)),
-        ('+ -3', NS(x=None, y=-3, z=False)),
-        ('-+-', NS(x=None, y=42, z=True)),
-        ('- ===', NS(x='===', y=42, z=False)),
-    ]
-
-
-class TestNargsZeroOrMore(ParserTestCase):
-    """Tests specifying an args for an Optional that accepts zero or more"""
-
-    argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')]
-    failures = []
-    successes = [
-        ('', NS(x=None, y=[])),
-        ('-x', NS(x=[], y=[])),
-        ('-x a', NS(x=['a'], y=[])),
-        ('-x a -- b', NS(x=['a'], y=['b'])),
-        ('a', NS(x=None, y=['a'])),
-        ('a -x', NS(x=[], y=['a'])),
-        ('a -x b', NS(x=['b'], y=['a'])),
-    ]
-
-
-class TestNargsRemainder(ParserTestCase):
-    """Tests specifying a positional with nargs=REMAINDER"""
-
-    argument_signatures = [Sig('x'), Sig('y', nargs='...'), Sig('-z')]
-    failures = ['', '-z', '-z Z']
-    successes = [
-        ('X', NS(x='X', y=[], z=None)),
-        ('-z Z X', NS(x='X', y=[], z='Z')),
-        ('X A B -z Z', NS(x='X', y=['A', 'B', '-z', 'Z'], z=None)),
-        ('X Y --foo', NS(x='X', y=['Y', '--foo'], z=None)),
-    ]
-
-
-class TestOptionLike(ParserTestCase):
-    """Tests options that may or may not be arguments"""
-
-    argument_signatures = [
-        Sig('-x', type=float),
-        Sig('-3', type=float, dest='y'),
-        Sig('z', nargs='*'),
-    ]
-    failures = ['-x', '-y2.5', '-xa', '-x -a',
-                '-x -3', '-x -3.5', '-3 -3.5',
-                '-x -2.5', '-x -2.5 a', '-3 -.5',
-                'a x -1', '-x -1 a', '-3 -1 a']
-    successes = [
-        ('', NS(x=None, y=None, z=[])),
-        ('-x 2.5', NS(x=2.5, y=None, z=[])),
-        ('-x 2.5 a', NS(x=2.5, y=None, z=['a'])),
-        ('-3.5', NS(x=None, y=0.5, z=[])),
-        ('-3-.5', NS(x=None, y=-0.5, z=[])),
-        ('-3 .5', NS(x=None, y=0.5, z=[])),
-        ('a -3.5', NS(x=None, y=0.5, z=['a'])),
-        ('a', NS(x=None, y=None, z=['a'])),
-        ('a -x 1', NS(x=1.0, y=None, z=['a'])),
-        ('-x 1 a', NS(x=1.0, y=None, z=['a'])),
-        ('-3 1 a', NS(x=None, y=1.0, z=['a'])),
-    ]
-
-
-class TestDefaultSuppress(ParserTestCase):
-    """Test actions with suppressed defaults"""
-
-    argument_signatures = [
-        Sig('foo', nargs='?', default=argparse.SUPPRESS),
-        Sig('bar', nargs='*', default=argparse.SUPPRESS),
-        Sig('--baz', action='store_true', default=argparse.SUPPRESS),
-    ]
-    failures = ['-x']
-    successes = [
-        ('', NS()),
-        ('a', NS(foo='a')),
-        ('a b', NS(foo='a', bar=['b'])),
-        ('--baz', NS(baz=True)),
-        ('a --baz', NS(foo='a', baz=True)),
-        ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
-    ]
-
-
-class TestParserDefaultSuppress(ParserTestCase):
-    """Test actions with a parser-level default of SUPPRESS"""
-
-    parser_signature = Sig(argument_default=argparse.SUPPRESS)
-    argument_signatures = [
-        Sig('foo', nargs='?'),
-        Sig('bar', nargs='*'),
-        Sig('--baz', action='store_true'),
-    ]
-    failures = ['-x']
-    successes = [
-        ('', NS()),
-        ('a', NS(foo='a')),
-        ('a b', NS(foo='a', bar=['b'])),
-        ('--baz', NS(baz=True)),
-        ('a --baz', NS(foo='a', baz=True)),
-        ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
-    ]
-
-
-class TestParserDefault42(ParserTestCase):
-    """Test actions with a parser-level default of 42"""
-
-    parser_signature = Sig(argument_default=42, version='1.0')
-    argument_signatures = [
-        Sig('foo', nargs='?'),
-        Sig('bar', nargs='*'),
-        Sig('--baz', action='store_true'),
-    ]
-    failures = ['-x']
-    successes = [
-        ('', NS(foo=42, bar=42, baz=42)),
-        ('a', NS(foo='a', bar=42, baz=42)),
-        ('a b', NS(foo='a', bar=['b'], baz=42)),
-        ('--baz', NS(foo=42, bar=42, baz=True)),
-        ('a --baz', NS(foo='a', bar=42, baz=True)),
-        ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
-    ]
-
-
-class TestArgumentsFromFile(TempDirMixin, ParserTestCase):
-    """Test reading arguments from a file"""
-
-    def setUp(self):
-        super(TestArgumentsFromFile, self).setUp()
-        file_texts = [
-            ('hello', 'hello world!\n'),
-            ('recursive', '-a\n'
-                          'A\n'
-                          '@hello'),
-            ('invalid', '@no-such-path\n'),
-        ]
-        for path, text in file_texts:
-            file = open(path, 'w')
-            file.write(text)
-            file.close()
-
-    parser_signature = Sig(fromfile_prefix_chars='@')
-    argument_signatures = [
-        Sig('-a'),
-        Sig('x'),
-        Sig('y', nargs='+'),
-    ]
-    failures = ['', '-b', 'X', '@invalid', '@missing']
-    successes = [
-        ('X Y', NS(a=None, x='X', y=['Y'])),
-        ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])),
-        ('@hello X', NS(a=None, x='hello world!', y=['X'])),
-        ('X @hello', NS(a=None, x='X', y=['hello world!'])),
-        ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])),
-        ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])),
-    ]
-
-
-class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase):
-    """Test reading arguments from a file"""
-
-    def setUp(self):
-        super(TestArgumentsFromFileConverter, self).setUp()
-        file_texts = [
-            ('hello', 'hello world!\n'),
-        ]
-        for path, text in file_texts:
-            file = open(path, 'w')
-            file.write(text)
-            file.close()
-
-    class FromFileConverterArgumentParser(ErrorRaisingArgumentParser):
-
-        def convert_arg_line_to_args(self, arg_line):
-            for arg in arg_line.split():
-                if not arg.strip():
-                    continue
-                yield arg
-    parser_class = FromFileConverterArgumentParser
-    parser_signature = Sig(fromfile_prefix_chars='@')
-    argument_signatures = [
-        Sig('y', nargs='+'),
-    ]
-    failures = []
-    successes = [
-        ('@hello X', NS(y=['hello', 'world!', 'X'])),
-    ]
-
-
-# =====================
-# Type conversion tests
-# =====================
-
-class TestFileTypeRepr(TestCase):
-
-    def test_r(self):
-        type = argparse.FileType('r')
-        self.assertEqual("FileType('r')", repr(type))
-
-    def test_wb_1(self):
-        type = argparse.FileType('wb', 1)
-        self.assertEqual("FileType('wb', 1)", repr(type))
-
-
-class RFile(object):
-    seen = {}
-
-    def __init__(self, name):
-        self.name = name
-
-    def __eq__(self, other):
-        if other in self.seen:
-            text = self.seen[other]
-        else:
-            text = self.seen[other] = other.read()
-            other.close()
-        if not isinstance(text, str):
-            text = text.decode('ascii')
-        return self.name == other.name == text
-
-
-class TestFileTypeR(TempDirMixin, ParserTestCase):
-    """Test the FileType option/argument type for reading files"""
-
-    def setUp(self):
-        super(TestFileTypeR, self).setUp()
-        for file_name in ['foo', 'bar']:
-            file = open(os.path.join(self.temp_dir, file_name), 'w')
-            file.write(file_name)
-            file.close()
-
-    argument_signatures = [
-        Sig('-x', type=argparse.FileType()),
-        Sig('spam', type=argparse.FileType('r')),
-    ]
-    failures = ['-x', '-x bar']
-    successes = [
-        ('foo', NS(x=None, spam=RFile('foo'))),
-        ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
-        ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
-        ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
-    ]
-
-
-class TestFileTypeRB(TempDirMixin, ParserTestCase):
-    """Test the FileType option/argument type for reading files"""
-
-    def setUp(self):
-        super(TestFileTypeRB, self).setUp()
-        for file_name in ['foo', 'bar']:
-            file = open(os.path.join(self.temp_dir, file_name), 'w')
-            file.write(file_name)
-            file.close()
-
-    argument_signatures = [
-        Sig('-x', type=argparse.FileType('rb')),
-        Sig('spam', type=argparse.FileType('rb')),
-    ]
-    failures = ['-x', '-x bar']
-    successes = [
-        ('foo', NS(x=None, spam=RFile('foo'))),
-        ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
-        ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
-        ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
-    ]
-
-
-class WFile(object):
-    seen = set()
-
-    def __init__(self, name):
-        self.name = name
-
-    def __eq__(self, other):
-        if other not in self.seen:
-            text = 'Check that file is writable.'
-            if 'b' in other.mode:
-                text = text.encode('ascii')
-            other.write(text)
-            other.close()
-            self.seen.add(other)
-        return self.name == other.name
-
-
-class TestFileTypeW(TempDirMixin, ParserTestCase):
-    """Test the FileType option/argument type for writing files"""
-
-    argument_signatures = [
-        Sig('-x', type=argparse.FileType('w')),
-        Sig('spam', type=argparse.FileType('w')),
-    ]
-    failures = ['-x', '-x bar']
-    successes = [
-        ('foo', NS(x=None, spam=WFile('foo'))),
-        ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
-        ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
-        ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
-    ]
-
-
-class TestFileTypeWB(TempDirMixin, ParserTestCase):
-
-    argument_signatures = [
-        Sig('-x', type=argparse.FileType('wb')),
-        Sig('spam', type=argparse.FileType('wb')),
-    ]
-    failures = ['-x', '-x bar']
-    successes = [
-        ('foo', NS(x=None, spam=WFile('foo'))),
-        ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
-        ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
-        ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
-    ]
-
-
-class TestTypeCallable(ParserTestCase):
-    """Test some callables as option/argument types"""
-
-    argument_signatures = [
-        Sig('--eggs', type=complex),
-        Sig('spam', type=float),
-    ]
-    failures = ['a', '42j', '--eggs a', '--eggs 2i']
-    successes = [
-        ('--eggs=42 42', NS(eggs=42, spam=42.0)),
-        ('--eggs 2j -- -1.5', NS(eggs=2j, spam=-1.5)),
-        ('1024.675', NS(eggs=None, spam=1024.675)),
-    ]
-
-
-class TestTypeUserDefined(ParserTestCase):
-    """Test a user-defined option/argument type"""
-
-    class MyType(TestCase):
-
-        def __init__(self, value):
-            self.value = value
-
-        def __eq__(self, other):
-            return (type(self), self.value) == (type(other), other.value)
-
-    argument_signatures = [
-        Sig('-x', type=MyType),
-        Sig('spam', type=MyType),
-    ]
-    failures = []
-    successes = [
-        ('a -x b', NS(x=MyType('b'), spam=MyType('a'))),
-        ('-xf g', NS(x=MyType('f'), spam=MyType('g'))),
-    ]
-
-
-class TestTypeClassicClass(ParserTestCase):
-    """Test a classic class type"""
-
-    class C:
-
-        def __init__(self, value):
-            self.value = value
-
-        def __eq__(self, other):
-            return (type(self), self.value) == (type(other), other.value)
-
-    argument_signatures = [
-        Sig('-x', type=C),
-        Sig('spam', type=C),
-    ]
-    failures = []
-    successes = [
-        ('a -x b', NS(x=C('b'), spam=C('a'))),
-        ('-xf g', NS(x=C('f'), spam=C('g'))),
-    ]
-
-
-class TestTypeRegistration(TestCase):
-    """Test a user-defined type by registering it"""
-
-    def test(self):
-
-        def get_my_type(string):
-            return 'my_type{%s}' % string
-
-        parser = argparse.ArgumentParser()
-        parser.register('type', 'my_type', get_my_type)
-        parser.add_argument('-x', type='my_type')
-        parser.add_argument('y', type='my_type')
-
-        self.assertEqual(parser.parse_args('1'.split()),
-                         NS(x=None, y='my_type{1}'))
-        self.assertEqual(parser.parse_args('-x 1 42'.split()),
-                         NS(x='my_type{1}', y='my_type{42}'))
-
-
-# ============
-# Action tests
-# ============
-
-class TestActionUserDefined(ParserTestCase):
-    """Test a user-defined option/argument action"""
-
-    class OptionalAction(argparse.Action):
-
-        def __call__(self, parser, namespace, value, option_string=None):
-            try:
-                # check destination and option string
-                assert self.dest == 'spam', 'dest: %s' % self.dest
-                assert option_string == '-s', 'flag: %s' % option_string
-                # when option is before argument, badger=2, and when
-                # option is after argument, badger=<whatever was set>
-                expected_ns = NS(spam=0.25)
-                if value in [0.125, 0.625]:
-                    expected_ns.badger = 2
-                elif value in [2.0]:
-                    expected_ns.badger = 84
-                else:
-                    raise AssertionError('value: %s' % value)
-                assert expected_ns == namespace, ('expected %s, got %s' %
-                                                  (expected_ns, namespace))
-            except AssertionError:
-                e = sys.exc_info()[1]
-                raise ArgumentParserError('opt_action failed: %s' % e)
-            setattr(namespace, 'spam', value)
-
-    class PositionalAction(argparse.Action):
-
-        def __call__(self, parser, namespace, value, option_string=None):
-            try:
-                assert option_string is None, ('option_string: %s' %
-                                               option_string)
-                # check destination
-                assert self.dest == 'badger', 'dest: %s' % self.dest
-                # when argument is before option, spam=0.25, and when
-                # option is after argument, spam=<whatever was set>
-                expected_ns = NS(badger=2)
-                if value in [42, 84]:
-                    expected_ns.spam = 0.25
-                elif value in [1]:
-                    expected_ns.spam = 0.625
-                elif value in [2]:
-                    expected_ns.spam = 0.125
-                else:
-                    raise AssertionError('value: %s' % value)
-                assert expected_ns == namespace, ('expected %s, got %s' %
-                                                  (expected_ns, namespace))
-            except AssertionError:
-                e = sys.exc_info()[1]
-                raise ArgumentParserError('arg_action failed: %s' % e)
-            setattr(namespace, 'badger', value)
-
-    argument_signatures = [
-        Sig('-s', dest='spam', action=OptionalAction,
-            type=float, default=0.25),
-        Sig('badger', action=PositionalAction,
-            type=int, nargs='?', default=2),
-    ]
-    failures = []
-    successes = [
-        ('-s0.125', NS(spam=0.125, badger=2)),
-        ('42', NS(spam=0.25, badger=42)),
-        ('-s 0.625 1', NS(spam=0.625, badger=1)),
-        ('84 -s2', NS(spam=2.0, badger=84)),
-    ]
-
-
-class TestActionRegistration(TestCase):
-    """Test a user-defined action supplied by registering it"""
-
-    class MyAction(argparse.Action):
-
-        def __call__(self, parser, namespace, values, option_string=None):
-            setattr(namespace, self.dest, 'foo[%s]' % values)
-
-    def test(self):
-
-        parser = argparse.ArgumentParser()
-        parser.register('action', 'my_action', self.MyAction)
-        parser.add_argument('badger', action='my_action')
-
-        self.assertEqual(parser.parse_args(['1']), NS(badger='foo[1]'))
-        self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]'))
-
-
-# ================
-# Subparsers tests
-# ================
-
-class TestAddSubparsers(TestCase):
-    """Test the add_subparsers method"""
-
-    def assertArgumentParserError(self, *args, **kwargs):
-        self.assertRaises(ArgumentParserError, *args, **kwargs)
-
-    def _get_parser(self, subparser_help=False):
-        # create a parser with a subparsers argument
-        parser = ErrorRaisingArgumentParser(
-            prog='PROG', description='main description')
-        parser.add_argument(
-            '--foo', action='store_true', help='foo help')
-        parser.add_argument(
-            'bar', type=float, help='bar help')
-
-        # check that only one subparsers argument can be added
-        subparsers = parser.add_subparsers(help='command help')
-        self.assertArgumentParserError(parser.add_subparsers)
-
-        # add first sub-parser
-        parser1_kwargs = dict(description='1 description')
-        if subparser_help:
-            parser1_kwargs['help'] = '1 help'
-        parser1 = subparsers.add_parser('1', **parser1_kwargs)
-        parser1.add_argument('-w', type=int, help='w help')
-        parser1.add_argument('x', choices='abc', help='x help')
-
-        # add second sub-parser
-        parser2_kwargs = dict(description='2 description')
-        if subparser_help:
-            parser2_kwargs['help'] = '2 help'
-        parser2 = subparsers.add_parser('2', **parser2_kwargs)
-        parser2.add_argument('-y', choices='123', help='y help')
-        parser2.add_argument('z', type=complex, nargs='*', help='z help')
-
-        # return the main parser
-        return parser
-
-    def setUp(self):
-        self.parser = self._get_parser()
-        self.command_help_parser = self._get_parser(subparser_help=True)
-
-    def test_parse_args_failures(self):
-        # check some failure cases:
-        for args_str in ['', 'a', 'a a', '0.5 a', '0.5 1',
-                         '0.5 1 -y', '0.5 2 -w']:
-            args = args_str.split()
-            self.assertArgumentParserError(self.parser.parse_args, args)
-
-    def test_parse_args(self):
-        # check some non-failure cases:
-        self.assertEqual(
-            self.parser.parse_args('0.5 1 b -w 7'.split()),
-            NS(foo=False, bar=0.5, w=7, x='b'),
-        )
-        self.assertEqual(
-            self.parser.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()),
-            NS(foo=True, bar=0.25, y='2', z=[3j, -1j]),
-        )
-        self.assertEqual(
-            self.parser.parse_args('--foo 0.125 1 c'.split()),
-            NS(foo=True, bar=0.125, w=None, x='c'),
-        )
-
-    def test_dest(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.add_argument('--foo', action='store_true')
-        subparsers = parser.add_subparsers(dest='bar')
-        parser1 = subparsers.add_parser('1')
-        parser1.add_argument('baz')
-        self.assertEqual(NS(foo=False, bar='1', baz='2'),
-                         parser.parse_args('1 2'.split()))
-
-    def test_help(self):
-        self.assertEqual(self.parser.format_usage(),
-                         'usage: PROG [-h] [--foo] bar {1,2} ...\n')
-        self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
-            usage: PROG [-h] [--foo] bar {1,2} ...
-
-            main description
-
-            positional arguments:
-              bar         bar help
-              {1,2}       command help
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              --foo       foo help
-            '''))
-
-    def test_parser_command_help(self):
-        self.assertEqual(self.command_help_parser.format_usage(),
-                         'usage: PROG [-h] [--foo] bar {1,2} ...\n')
-        self.assertEqual(self.command_help_parser.format_help(),
-                         textwrap.dedent('''\
-            usage: PROG [-h] [--foo] bar {1,2} ...
-
-            main description
-
-            positional arguments:
-              bar         bar help
-              {1,2}       command help
-                1         1 help
-                2         2 help
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              --foo       foo help
-            '''))
-
-    def test_subparser_title_help(self):
-        parser = ErrorRaisingArgumentParser(prog='PROG',
-                                            description='main description')
-        parser.add_argument('--foo', action='store_true', help='foo help')
-        parser.add_argument('bar', help='bar help')
-        subparsers = parser.add_subparsers(title='subcommands',
-                                           description='command help',
-                                           help='additional text')
-        parser1 = subparsers.add_parser('1')
-        parser2 = subparsers.add_parser('2')
-        self.assertEqual(parser.format_usage(),
-                         'usage: PROG [-h] [--foo] bar {1,2} ...\n')
-        self.assertEqual(parser.format_help(), textwrap.dedent('''\
-            usage: PROG [-h] [--foo] bar {1,2} ...
-
-            main description
-
-            positional arguments:
-              bar         bar help
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              --foo       foo help
-
-            subcommands:
-              command help
-
-              {1,2}       additional text
-            '''))
-
-    def _test_subparser_help(self, args_str, expected_help):
-        try:
-            self.parser.parse_args(args_str.split())
-        except ArgumentParserError:
-            err = sys.exc_info()[1]
-            if err.stdout != expected_help:
-                print(repr(expected_help))
-                print(repr(err.stdout))
-            self.assertEqual(err.stdout, expected_help)
-
-    def test_subparser1_help(self):
-        self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\
-            usage: PROG bar 1 [-h] [-w W] {a,b,c}
-
-            1 description
-
-            positional arguments:
-              {a,b,c}     x help
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              -w W        w help
-            '''))
-
-    def test_subparser2_help(self):
-        self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\
-            usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]]
-
-            2 description
-
-            positional arguments:
-              z           z help
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              -y {1,2,3}  y help
-            '''))
-
-# ============
-# Groups tests
-# ============
-
-class TestPositionalsGroups(TestCase):
-    """Tests that order of group positionals matches construction order"""
-
-    def test_nongroup_first(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.add_argument('foo')
-        group = parser.add_argument_group('g')
-        group.add_argument('bar')
-        parser.add_argument('baz')
-        expected = NS(foo='1', bar='2', baz='3')
-        result = parser.parse_args('1 2 3'.split())
-        self.failUnlessEqual(expected, result)
-
-    def test_group_first(self):
-        parser = ErrorRaisingArgumentParser()
-        group = parser.add_argument_group('xxx')
-        group.add_argument('foo')
-        parser.add_argument('bar')
-        parser.add_argument('baz')
-        expected = NS(foo='1', bar='2', baz='3')
-        result = parser.parse_args('1 2 3'.split())
-        self.failUnlessEqual(expected, result)
-
-    def test_interleaved_groups(self):
-        parser = ErrorRaisingArgumentParser()
-        group = parser.add_argument_group('xxx')
-        parser.add_argument('foo')
-        group.add_argument('bar')
-        parser.add_argument('baz')
-        group = parser.add_argument_group('yyy')
-        group.add_argument('frell')
-        expected = NS(foo='1', bar='2', baz='3', frell='4')
-        result = parser.parse_args('1 2 3 4'.split())
-        self.failUnlessEqual(expected, result)
-
-# ===================
-# Parent parser tests
-# ===================
-
-class TestParentParsers(TestCase):
-    """Tests that parsers can be created with parent parsers"""
-
-    def assertArgumentParserError(self, *args, **kwargs):
-        self.assertRaises(ArgumentParserError, *args, **kwargs)
-
-    def setUp(self):
-        self.wxyz_parent = ErrorRaisingArgumentParser(add_help=False)
-        self.wxyz_parent.add_argument('--w')
-        x_group = self.wxyz_parent.add_argument_group('x')
-        x_group.add_argument('-y')
-        self.wxyz_parent.add_argument('z')
-
-        self.abcd_parent = ErrorRaisingArgumentParser(add_help=False)
-        self.abcd_parent.add_argument('a')
-        self.abcd_parent.add_argument('-b')
-        c_group = self.abcd_parent.add_argument_group('c')
-        c_group.add_argument('--d')
-
-        self.w_parent = ErrorRaisingArgumentParser(add_help=False)
-        self.w_parent.add_argument('--w')
-
-        self.z_parent = ErrorRaisingArgumentParser(add_help=False)
-        self.z_parent.add_argument('z')
-
-        # parents with mutually exclusive groups
-        self.ab_mutex_parent = ErrorRaisingArgumentParser(add_help=False)
-        group = self.ab_mutex_parent.add_mutually_exclusive_group()
-        group.add_argument('-a', action='store_true')
-        group.add_argument('-b', action='store_true')
-
-    def test_single_parent(self):
-        parser = ErrorRaisingArgumentParser(parents=[self.wxyz_parent])
-        self.assertEqual(parser.parse_args('-y 1 2 --w 3'.split()),
-                         NS(w='3', y='1', z='2'))
-
-    def test_single_parent_mutex(self):
-        self._test_mutex_ab(self.ab_mutex_parent.parse_args)
-        parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent])
-        self._test_mutex_ab(parser.parse_args)
-
-    def test_single_granparent_mutex(self):
-        parents = [self.ab_mutex_parent]
-        parser = ErrorRaisingArgumentParser(add_help=False, parents=parents)
-        parser = ErrorRaisingArgumentParser(parents=[parser])
-        self._test_mutex_ab(parser.parse_args)
-
-    def _test_mutex_ab(self, parse_args):
-        self.assertEqual(parse_args([]), NS(a=False, b=False))
-        self.assertEqual(parse_args(['-a']), NS(a=True, b=False))
-        self.assertEqual(parse_args(['-b']), NS(a=False, b=True))
-        self.assertArgumentParserError(parse_args, ['-a', '-b'])
-        self.assertArgumentParserError(parse_args, ['-b', '-a'])
-        self.assertArgumentParserError(parse_args, ['-c'])
-        self.assertArgumentParserError(parse_args, ['-a', '-c'])
-        self.assertArgumentParserError(parse_args, ['-b', '-c'])
-
-    def test_multiple_parents(self):
-        parents = [self.abcd_parent, self.wxyz_parent]
-        parser = ErrorRaisingArgumentParser(parents=parents)
-        self.assertEqual(parser.parse_args('--d 1 --w 2 3 4'.split()),
-                         NS(a='3', b=None, d='1', w='2', y=None, z='4'))
-
-    def test_multiple_parents_mutex(self):
-        parents = [self.ab_mutex_parent, self.wxyz_parent]
-        parser = ErrorRaisingArgumentParser(parents=parents)
-        self.assertEqual(parser.parse_args('-a --w 2 3'.split()),
-                         NS(a=True, b=False, w='2', y=None, z='3'))
-        self.assertArgumentParserError(
-            parser.parse_args, '-a --w 2 3 -b'.split())
-        self.assertArgumentParserError(
-            parser.parse_args, '-a -b --w 2 3'.split())
-
-    def test_conflicting_parents(self):
-        self.assertRaises(
-            argparse.ArgumentError,
-            argparse.ArgumentParser,
-            parents=[self.w_parent, self.wxyz_parent])
-
-    def test_conflicting_parents_mutex(self):
-        self.assertRaises(
-            argparse.ArgumentError,
-            argparse.ArgumentParser,
-            parents=[self.abcd_parent, self.ab_mutex_parent])
-
-    def test_same_argument_name_parents(self):
-        parents = [self.wxyz_parent, self.z_parent]
-        parser = ErrorRaisingArgumentParser(parents=parents)
-        self.assertEqual(parser.parse_args('1 2'.split()),
-                         NS(w=None, y=None, z='2'))
-
-    def test_subparser_parents(self):
-        parser = ErrorRaisingArgumentParser()
-        subparsers = parser.add_subparsers()
-        abcde_parser = subparsers.add_parser('bar', parents=[self.abcd_parent])
-        abcde_parser.add_argument('e')
-        self.assertEqual(parser.parse_args('bar -b 1 --d 2 3 4'.split()),
-                         NS(a='3', b='1', d='2', e='4'))
-
-    def test_subparser_parents_mutex(self):
-        parser = ErrorRaisingArgumentParser()
-        subparsers = parser.add_subparsers()
-        parents = [self.ab_mutex_parent]
-        abc_parser = subparsers.add_parser('foo', parents=parents)
-        c_group = abc_parser.add_argument_group('c_group')
-        c_group.add_argument('c')
-        parents = [self.wxyz_parent, self.ab_mutex_parent]
-        wxyzabe_parser = subparsers.add_parser('bar', parents=parents)
-        wxyzabe_parser.add_argument('e')
-        self.assertEqual(parser.parse_args('foo -a 4'.split()),
-                         NS(a=True, b=False, c='4'))
-        self.assertEqual(parser.parse_args('bar -b  --w 2 3 4'.split()),
-                         NS(a=False, b=True, w='2', y=None, z='3', e='4'))
-        self.assertArgumentParserError(
-            parser.parse_args, 'foo -a -b 4'.split())
-        self.assertArgumentParserError(
-            parser.parse_args, 'bar -b -a 4'.split())
-
-    def test_parent_help(self):
-        parents = [self.abcd_parent, self.wxyz_parent]
-        parser = ErrorRaisingArgumentParser(parents=parents)
-        parser_help = parser.format_help()
-        self.assertEqual(parser_help, textwrap.dedent('''\
-            usage: test_argparse.py [-h] [-b B] [--d D] [--w W] [-y Y] a z
-
-            positional arguments:
-              a
-              z
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              -b B
-              --w W
-
-            c:
-              --d D
-
-            x:
-              -y Y
-        '''))
-
-    def test_groups_parents(self):
-        parent = ErrorRaisingArgumentParser(add_help=False)
-        g = parent.add_argument_group(title='g', description='gd')
-        g.add_argument('-w')
-        g.add_argument('-x')
-        m = parent.add_mutually_exclusive_group()
-        m.add_argument('-y')
-        m.add_argument('-z')
-        parser = ErrorRaisingArgumentParser(parents=[parent])
-
-        self.assertRaises(ArgumentParserError, parser.parse_args,
-            ['-y', 'Y', '-z', 'Z'])
-
-        parser_help = parser.format_help()
-        self.assertEqual(parser_help, textwrap.dedent('''\
-            usage: test_argparse.py [-h] [-w W] [-x X] [-y Y | -z Z]
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              -y Y
-              -z Z
-
-            g:
-              gd
-
-              -w W
-              -x X
-        '''))
-
-# ==============================
-# Mutually exclusive group tests
-# ==============================
-
-class TestMutuallyExclusiveGroupErrors(TestCase):
-
-    def test_invalid_add_argument_group(self):
-        parser = ErrorRaisingArgumentParser()
-        raises = self.assertRaises
-        raises(TypeError, parser.add_mutually_exclusive_group, title='foo')
-
-    def test_invalid_add_argument(self):
-        parser = ErrorRaisingArgumentParser()
-        group = parser.add_mutually_exclusive_group()
-        add_argument = group.add_argument
-        raises = self.assertRaises
-        raises(ValueError, add_argument, '--foo', required=True)
-        raises(ValueError, add_argument, 'bar')
-        raises(ValueError, add_argument, 'bar', nargs='+')
-        raises(ValueError, add_argument, 'bar', nargs=1)
-        raises(ValueError, add_argument, 'bar', nargs=argparse.PARSER)
-
-
-class MEMixin(object):
-
-    def test_failures_when_not_required(self):
-        parse_args = self.get_parser(required=False).parse_args
-        error = ArgumentParserError
-        for args_string in self.failures:
-            self.assertRaises(error, parse_args, args_string.split())
-
-    def test_failures_when_required(self):
-        parse_args = self.get_parser(required=True).parse_args
-        error = ArgumentParserError
-        for args_string in self.failures + ['']:
-            self.assertRaises(error, parse_args, args_string.split())
-
-    def test_successes_when_not_required(self):
-        parse_args = self.get_parser(required=False).parse_args
-        successes = self.successes + self.successes_when_not_required
-        for args_string, expected_ns in successes:
-            actual_ns = parse_args(args_string.split())
-            self.assertEqual(actual_ns, expected_ns)
-
-    def test_successes_when_required(self):
-        parse_args = self.get_parser(required=True).parse_args
-        for args_string, expected_ns in self.successes:
-            actual_ns = parse_args(args_string.split())
-            self.assertEqual(actual_ns, expected_ns)
-
-    def test_usage_when_not_required(self):
-        format_usage = self.get_parser(required=False).format_usage
-        expected_usage = self.usage_when_not_required
-        self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
-
-    def test_usage_when_required(self):
-        format_usage = self.get_parser(required=True).format_usage
-        expected_usage = self.usage_when_required
-        self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
-
-    def test_help_when_not_required(self):
-        format_help = self.get_parser(required=False).format_help
-        help = self.usage_when_not_required + self.help
-        self.assertEqual(format_help(), textwrap.dedent(help))
-
-    def test_help_when_required(self):
-        format_help = self.get_parser(required=True).format_help
-        help = self.usage_when_required + self.help
-        self.assertEqual(format_help(), textwrap.dedent(help))
-
-
-class TestMutuallyExclusiveSimple(MEMixin, TestCase):
-
-    def get_parser(self, required=None):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        group = parser.add_mutually_exclusive_group(required=required)
-        group.add_argument('--bar', help='bar help')
-        group.add_argument('--baz', nargs='?', const='Z', help='baz help')
-        return parser
-
-    failures = ['--bar X --baz Y', '--bar X --baz']
-    successes = [
-        ('--bar X', NS(bar='X', baz=None)),
-        ('--bar X --bar Z', NS(bar='Z', baz=None)),
-        ('--baz Y', NS(bar=None, baz='Y')),
-        ('--baz', NS(bar=None, baz='Z')),
-    ]
-    successes_when_not_required = [
-        ('', NS(bar=None, baz=None)),
-    ]
-
-    usage_when_not_required = '''\
-        usage: PROG [-h] [--bar BAR | --baz [BAZ]]
-        '''
-    usage_when_required = '''\
-        usage: PROG [-h] (--bar BAR | --baz [BAZ])
-        '''
-    help = '''\
-
-        optional arguments:
-          -h, --help   show this help message and exit
-          --bar BAR    bar help
-          --baz [BAZ]  baz help
-        '''
-
-
-class TestMutuallyExclusiveLong(MEMixin, TestCase):
-
-    def get_parser(self, required=None):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        parser.add_argument('--abcde', help='abcde help')
-        parser.add_argument('--fghij', help='fghij help')
-        group = parser.add_mutually_exclusive_group(required=required)
-        group.add_argument('--klmno', help='klmno help')
-        group.add_argument('--pqrst', help='pqrst help')
-        return parser
-
-    failures = ['--klmno X --pqrst Y']
-    successes = [
-        ('--klmno X', NS(abcde=None, fghij=None, klmno='X', pqrst=None)),
-        ('--abcde Y --klmno X',
-            NS(abcde='Y', fghij=None, klmno='X', pqrst=None)),
-        ('--pqrst X', NS(abcde=None, fghij=None, klmno=None, pqrst='X')),
-        ('--pqrst X --fghij Y',
-            NS(abcde=None, fghij='Y', klmno=None, pqrst='X')),
-    ]
-    successes_when_not_required = [
-        ('', NS(abcde=None, fghij=None, klmno=None, pqrst=None)),
-    ]
-
-    usage_when_not_required = '''\
-    usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
-                [--klmno KLMNO | --pqrst PQRST]
-    '''
-    usage_when_required = '''\
-    usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
-                (--klmno KLMNO | --pqrst PQRST)
-    '''
-    help = '''\
-
-    optional arguments:
-      -h, --help     show this help message and exit
-      --abcde ABCDE  abcde help
-      --fghij FGHIJ  fghij help
-      --klmno KLMNO  klmno help
-      --pqrst PQRST  pqrst help
-    '''
-
-
-class TestMutuallyExclusiveFirstSuppressed(MEMixin, TestCase):
-
-    def get_parser(self, required):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        group = parser.add_mutually_exclusive_group(required=required)
-        group.add_argument('-x', help=argparse.SUPPRESS)
-        group.add_argument('-y', action='store_false', help='y help')
-        return parser
-
-    failures = ['-x X -y']
-    successes = [
-        ('-x X', NS(x='X', y=True)),
-        ('-x X -x Y', NS(x='Y', y=True)),
-        ('-y', NS(x=None, y=False)),
-    ]
-    successes_when_not_required = [
-        ('', NS(x=None, y=True)),
-    ]
-
-    usage_when_not_required = '''\
-        usage: PROG [-h] [-y]
-        '''
-    usage_when_required = '''\
-        usage: PROG [-h] -y
-        '''
-    help = '''\
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          -y          y help
-        '''
-
-
-class TestMutuallyExclusiveManySuppressed(MEMixin, TestCase):
-
-    def get_parser(self, required):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        group = parser.add_mutually_exclusive_group(required=required)
-        add = group.add_argument
-        add('--spam', action='store_true', help=argparse.SUPPRESS)
-        add('--badger', action='store_false', help=argparse.SUPPRESS)
-        add('--bladder', help=argparse.SUPPRESS)
-        return parser
-
-    failures = [
-        '--spam --badger',
-        '--badger --bladder B',
-        '--bladder B --spam',
-    ]
-    successes = [
-        ('--spam', NS(spam=True, badger=True, bladder=None)),
-        ('--badger', NS(spam=False, badger=False, bladder=None)),
-        ('--bladder B', NS(spam=False, badger=True, bladder='B')),
-        ('--spam --spam', NS(spam=True, badger=True, bladder=None)),
-    ]
-    successes_when_not_required = [
-        ('', NS(spam=False, badger=True, bladder=None)),
-    ]
-
-    usage_when_required = usage_when_not_required = '''\
-        usage: PROG [-h]
-        '''
-    help = '''\
-
-        optional arguments:
-          -h, --help  show this help message and exit
-        '''
-
-
-class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
-
-    def get_parser(self, required):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        group = parser.add_mutually_exclusive_group(required=required)
-        group.add_argument('--foo', action='store_true', help='FOO')
-        group.add_argument('--spam', help='SPAM')
-        group.add_argument('badger', nargs='*', default='X', help='BADGER')
-        return parser
-
-    failures = [
-        '--foo --spam S',
-        '--spam S X',
-        'X --foo',
-        'X Y Z --spam S',
-        '--foo X Y',
-    ]
-    successes = [
-        ('--foo', NS(foo=True, spam=None, badger='X')),
-        ('--spam S', NS(foo=False, spam='S', badger='X')),
-        ('X', NS(foo=False, spam=None, badger=['X'])),
-        ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
-    ]
-    successes_when_not_required = [
-        ('', NS(foo=False, spam=None, badger='X')),
-    ]
-
-    usage_when_not_required = '''\
-        usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]]
-        '''
-    usage_when_required = '''\
-        usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...])
-        '''
-    help = '''\
-
-        positional arguments:
-          badger       BADGER
-
-        optional arguments:
-          -h, --help   show this help message and exit
-          --foo        FOO
-          --spam SPAM  SPAM
-        '''
-
-
-class TestMutuallyExclusiveOptionalsMixed(MEMixin, TestCase):
-
-    def get_parser(self, required):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        parser.add_argument('-x', action='store_true', help='x help')
-        group = parser.add_mutually_exclusive_group(required=required)
-        group.add_argument('-a', action='store_true', help='a help')
-        group.add_argument('-b', action='store_true', help='b help')
-        parser.add_argument('-y', action='store_true', help='y help')
-        group.add_argument('-c', action='store_true', help='c help')
-        return parser
-
-    failures = ['-a -b', '-b -c', '-a -c', '-a -b -c']
-    successes = [
-        ('-a', NS(a=True, b=False, c=False, x=False, y=False)),
-        ('-b', NS(a=False, b=True, c=False, x=False, y=False)),
-        ('-c', NS(a=False, b=False, c=True, x=False, y=False)),
-        ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)),
-        ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)),
-        ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)),
-    ]
-    successes_when_not_required = [
-        ('', NS(a=False, b=False, c=False, x=False, y=False)),
-        ('-x', NS(a=False, b=False, c=False, x=True, y=False)),
-        ('-y', NS(a=False, b=False, c=False, x=False, y=True)),
-    ]
-
-    usage_when_required = usage_when_not_required = '''\
-        usage: PROG [-h] [-x] [-a] [-b] [-y] [-c]
-        '''
-    help = '''\
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          -x          x help
-          -a          a help
-          -b          b help
-          -y          y help
-          -c          c help
-        '''
-
-
-class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase):
-
-    def get_parser(self, required):
-        parser = ErrorRaisingArgumentParser(prog='PROG')
-        parser.add_argument('x', help='x help')
-        parser.add_argument('-y', action='store_true', help='y help')
-        group = parser.add_mutually_exclusive_group(required=required)
-        group.add_argument('a', nargs='?', help='a help')
-        group.add_argument('-b', action='store_true', help='b help')
-        group.add_argument('-c', action='store_true', help='c help')
-        return parser
-
-    failures = ['X A -b', '-b -c', '-c X A']
-    successes = [
-        ('X A', NS(a='A', b=False, c=False, x='X', y=False)),
-        ('X -b', NS(a=None, b=True, c=False, x='X', y=False)),
-        ('X -c', NS(a=None, b=False, c=True, x='X', y=False)),
-        ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)),
-        ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)),
-    ]
-    successes_when_not_required = [
-        ('X', NS(a=None, b=False, c=False, x='X', y=False)),
-        ('X -y', NS(a=None, b=False, c=False, x='X', y=True)),
-    ]
-
-    usage_when_required = usage_when_not_required = '''\
-        usage: PROG [-h] [-y] [-b] [-c] x [a]
-        '''
-    help = '''\
-
-        positional arguments:
-          x           x help
-          a           a help
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          -y          y help
-          -b          b help
-          -c          c help
-        '''
-
-# =================================================
-# Mutually exclusive group in parent parser tests
-# =================================================
-
-class MEPBase(object):
-
-    def get_parser(self, required=None):
-        parent = super(MEPBase, self).get_parser(required=required)
-        parser = ErrorRaisingArgumentParser(
-            prog=parent.prog, add_help=False, parents=[parent])
-        return parser
-
-
-class TestMutuallyExclusiveGroupErrorsParent(
-    MEPBase, TestMutuallyExclusiveGroupErrors):
-    pass
-
-
-class TestMutuallyExclusiveSimpleParent(
-    MEPBase, TestMutuallyExclusiveSimple):
-    pass
-
-
-class TestMutuallyExclusiveLongParent(
-    MEPBase, TestMutuallyExclusiveLong):
-    pass
-
-
-class TestMutuallyExclusiveFirstSuppressedParent(
-    MEPBase, TestMutuallyExclusiveFirstSuppressed):
-    pass
-
-
-class TestMutuallyExclusiveManySuppressedParent(
-    MEPBase, TestMutuallyExclusiveManySuppressed):
-    pass
-
-
-class TestMutuallyExclusiveOptionalAndPositionalParent(
-    MEPBase, TestMutuallyExclusiveOptionalAndPositional):
-    pass
-
-
-class TestMutuallyExclusiveOptionalsMixedParent(
-    MEPBase, TestMutuallyExclusiveOptionalsMixed):
-    pass
-
-
-class TestMutuallyExclusiveOptionalsAndPositionalsMixedParent(
-    MEPBase, TestMutuallyExclusiveOptionalsAndPositionalsMixed):
-    pass
-
-# =================
-# Set default tests
-# =================
-
-class TestSetDefaults(TestCase):
-
-    def test_set_defaults_no_args(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.set_defaults(x='foo')
-        parser.set_defaults(y='bar', z=1)
-        self.assertEqual(NS(x='foo', y='bar', z=1),
-                         parser.parse_args([]))
-        self.assertEqual(NS(x='foo', y='bar', z=1),
-                         parser.parse_args([], NS()))
-        self.assertEqual(NS(x='baz', y='bar', z=1),
-                         parser.parse_args([], NS(x='baz')))
-        self.assertEqual(NS(x='baz', y='bar', z=2),
-                         parser.parse_args([], NS(x='baz', z=2)))
-
-    def test_set_defaults_with_args(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.set_defaults(x='foo', y='bar')
-        parser.add_argument('-x', default='xfoox')
-        self.assertEqual(NS(x='xfoox', y='bar'),
-                         parser.parse_args([]))
-        self.assertEqual(NS(x='xfoox', y='bar'),
-                         parser.parse_args([], NS()))
-        self.assertEqual(NS(x='baz', y='bar'),
-                         parser.parse_args([], NS(x='baz')))
-        self.assertEqual(NS(x='1', y='bar'),
-                         parser.parse_args('-x 1'.split()))
-        self.assertEqual(NS(x='1', y='bar'),
-                         parser.parse_args('-x 1'.split(), NS()))
-        self.assertEqual(NS(x='1', y='bar'),
-                         parser.parse_args('-x 1'.split(), NS(x='baz')))
-
-    def test_set_defaults_subparsers(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.set_defaults(x='foo')
-        subparsers = parser.add_subparsers()
-        parser_a = subparsers.add_parser('a')
-        parser_a.set_defaults(y='bar')
-        self.assertEqual(NS(x='foo', y='bar'),
-                         parser.parse_args('a'.split()))
-
-    def test_set_defaults_parents(self):
-        parent = ErrorRaisingArgumentParser(add_help=False)
-        parent.set_defaults(x='foo')
-        parser = ErrorRaisingArgumentParser(parents=[parent])
-        self.assertEqual(NS(x='foo'), parser.parse_args([]))
-
-    def test_set_defaults_same_as_add_argument(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.set_defaults(w='W', x='X', y='Y', z='Z')
-        parser.add_argument('-w')
-        parser.add_argument('-x', default='XX')
-        parser.add_argument('y', nargs='?')
-        parser.add_argument('z', nargs='?', default='ZZ')
-
-        # defaults set previously
-        self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
-                         parser.parse_args([]))
-
-        # reset defaults
-        parser.set_defaults(w='WW', x='X', y='YY', z='Z')
-        self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
-                         parser.parse_args([]))
-
-    def test_set_defaults_same_as_add_argument_group(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.set_defaults(w='W', x='X', y='Y', z='Z')
-        group = parser.add_argument_group('foo')
-        group.add_argument('-w')
-        group.add_argument('-x', default='XX')
-        group.add_argument('y', nargs='?')
-        group.add_argument('z', nargs='?', default='ZZ')
-
-
-        # defaults set previously
-        self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
-                         parser.parse_args([]))
-
-        # reset defaults
-        parser.set_defaults(w='WW', x='X', y='YY', z='Z')
-        self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
-                         parser.parse_args([]))
-
-# =================
-# Get default tests
-# =================
-
-class TestGetDefault(TestCase):
-
-    def test_get_default(self):
-        parser = ErrorRaisingArgumentParser()
-        self.assertEqual(None, parser.get_default("foo"))
-        self.assertEqual(None, parser.get_default("bar"))
-
-        parser.add_argument("--foo")
-        self.assertEqual(None, parser.get_default("foo"))
-        self.assertEqual(None, parser.get_default("bar"))
-
-        parser.add_argument("--bar", type=int, default=42)
-        self.assertEqual(None, parser.get_default("foo"))
-        self.assertEqual(42, parser.get_default("bar"))
-
-        parser.set_defaults(foo="badger")
-        self.assertEqual("badger", parser.get_default("foo"))
-        self.assertEqual(42, parser.get_default("bar"))
-
-# ==========================
-# Namespace 'contains' tests
-# ==========================
-
-class TestNamespaceContainsSimple(TestCase):
-
-    def test_empty(self):
-        ns = argparse.Namespace()
-        self.assertEquals('' in ns, False)
-        self.assertEquals('' not in ns, True)
-        self.assertEquals('x' in ns, False)
-
-    def test_non_empty(self):
-        ns = argparse.Namespace(x=1, y=2)
-        self.assertEquals('x' in ns, True)
-        self.assertEquals('x' not in ns, False)
-        self.assertEquals('y' in ns, True)
-        self.assertEquals('' in ns, False)
-        self.assertEquals('xx' in ns, False)
-        self.assertEquals('z' in ns, False)
-
-# =====================
-# Help formatting tests
-# =====================
-
-class TestHelpFormattingMetaclass(type):
-
-    def __init__(cls, name, bases, bodydict):
-        if name == 'HelpTestCase':
-            return
-
-        class AddTests(object):
-
-            def __init__(self, test_class, func_suffix, std_name):
-                self.func_suffix = func_suffix
-                self.std_name = std_name
-
-                for test_func in [self.test_format,
-                                  self.test_print,
-                                  self.test_print_file]:
-                    test_name = '%s_%s' % (test_func.__name__, func_suffix)
-
-                    def test_wrapper(self, test_func=test_func):
-                        test_func(self)
-                    try:
-                        test_wrapper.__name__ = test_name
-                    except TypeError:
-                        pass
-                    setattr(test_class, test_name, test_wrapper)
-
-            def _get_parser(self, tester):
-                parser = argparse.ArgumentParser(
-                    *tester.parser_signature.args,
-                    **tester.parser_signature.kwargs)
-                for argument_sig in tester.argument_signatures:
-                    parser.add_argument(*argument_sig.args,
-                                        **argument_sig.kwargs)
-                group_signatures = tester.argument_group_signatures
-                for group_sig, argument_sigs in group_signatures:
-                    group = parser.add_argument_group(*group_sig.args,
-                                                      **group_sig.kwargs)
-                    for argument_sig in argument_sigs:
-                        group.add_argument(*argument_sig.args,
-                                           **argument_sig.kwargs)
-                return parser
-
-            def _test(self, tester, parser_text):
-                expected_text = getattr(tester, self.func_suffix)
-                expected_text = textwrap.dedent(expected_text)
-                if expected_text != parser_text:
-                    print(repr(expected_text))
-                    print(repr(parser_text))
-                    for char1, char2 in zip(expected_text, parser_text):
-                        if char1 != char2:
-                            print('first diff: %r %r' % (char1, char2))
-                            break
-                tester.assertEqual(expected_text, parser_text)
-
-            def test_format(self, tester):
-                parser = self._get_parser(tester)
-                format = getattr(parser, 'format_%s' % self.func_suffix)
-                self._test(tester, format())
-
-            def test_print(self, tester):
-                parser = self._get_parser(tester)
-                print_ = getattr(parser, 'print_%s' % self.func_suffix)
-                old_stream = getattr(sys, self.std_name)
-                setattr(sys, self.std_name, StringIO())
-                try:
-                    print_()
-                    parser_text = getattr(sys, self.std_name).getvalue()
-                finally:
-                    setattr(sys, self.std_name, old_stream)
-                self._test(tester, parser_text)
-
-            def test_print_file(self, tester):
-                parser = self._get_parser(tester)
-                print_ = getattr(parser, 'print_%s' % self.func_suffix)
-                sfile = StringIO()
-                print_(sfile)
-                parser_text = sfile.getvalue()
-                self._test(tester, parser_text)
-
-        # add tests for {format,print}_{usage,help,version}
-        for func_suffix, std_name in [('usage', 'stdout'),
-                                      ('help', 'stdout'),
-                                      ('version', 'stderr')]:
-            AddTests(cls, func_suffix, std_name)
-
-bases = TestCase,
-HelpTestCase = TestHelpFormattingMetaclass('HelpTestCase', bases, {})
-
-
-class TestHelpBiggerOptionals(HelpTestCase):
-    """Make sure that argument help aligns when options are longer"""
-
-    parser_signature = Sig(prog='PROG', description='DESCRIPTION',
-                           epilog='EPILOG', version='0.1')
-    argument_signatures = [
-        Sig('-x', action='store_true', help='X HELP'),
-        Sig('--y', help='Y HELP'),
-        Sig('foo', help='FOO HELP'),
-        Sig('bar', help='BAR HELP'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-v] [-x] [--y Y] foo bar
-        '''
-    help = usage + '''\
-
-        DESCRIPTION
-
-        positional arguments:
-          foo            FOO HELP
-          bar            BAR HELP
-
-        optional arguments:
-          -h, --help     show this help message and exit
-          -v, --version  show program's version number and exit
-          -x             X HELP
-          --y Y          Y HELP
-
-        EPILOG
-    '''
-    version = '''\
-        0.1
-        '''
-
-
-class TestHelpBiggerOptionalGroups(HelpTestCase):
-    """Make sure that argument help aligns when options are longer"""
-
-    parser_signature = Sig(prog='PROG', description='DESCRIPTION',
-                           epilog='EPILOG', version='0.1')
-    argument_signatures = [
-        Sig('-x', action='store_true', help='X HELP'),
-        Sig('--y', help='Y HELP'),
-        Sig('foo', help='FOO HELP'),
-        Sig('bar', help='BAR HELP'),
-    ]
-    argument_group_signatures = [
-        (Sig('GROUP TITLE', description='GROUP DESCRIPTION'), [
-            Sig('baz', help='BAZ HELP'),
-            Sig('-z', nargs='+', help='Z HELP')]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz
-        '''
-    help = usage + '''\
-
-        DESCRIPTION
-
-        positional arguments:
-          foo            FOO HELP
-          bar            BAR HELP
-
-        optional arguments:
-          -h, --help     show this help message and exit
-          -v, --version  show program's version number and exit
-          -x             X HELP
-          --y Y          Y HELP
-
-        GROUP TITLE:
-          GROUP DESCRIPTION
-
-          baz            BAZ HELP
-          -z Z [Z ...]   Z HELP
-
-        EPILOG
-    '''
-    version = '''\
-        0.1
-        '''
-
-
-class TestHelpBiggerPositionals(HelpTestCase):
-    """Make sure that help aligns when arguments are longer"""
-
-    parser_signature = Sig(usage='USAGE', description='DESCRIPTION')
-    argument_signatures = [
-        Sig('-x', action='store_true', help='X HELP'),
-        Sig('--y', help='Y HELP'),
-        Sig('ekiekiekifekang', help='EKI HELP'),
-        Sig('bar', help='BAR HELP'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: USAGE
-        '''
-    help = usage + '''\
-
-        DESCRIPTION
-
-        positional arguments:
-          ekiekiekifekang  EKI HELP
-          bar              BAR HELP
-
-        optional arguments:
-          -h, --help       show this help message and exit
-          -x               X HELP
-          --y Y            Y HELP
-        '''
-
-    version = ''
-
-
-class TestHelpReformatting(HelpTestCase):
-    """Make sure that text after short names starts on the first line"""
-
-    parser_signature = Sig(
-        prog='PROG',
-        description='   oddly    formatted\n'
-                    'description\n'
-                    '\n'
-                    'that is so long that it should go onto multiple '
-                    'lines when wrapped')
-    argument_signatures = [
-        Sig('-x', metavar='XX', help='oddly\n'
-                                     '    formatted -x help'),
-        Sig('y', metavar='yyy', help='normal y help'),
-    ]
-    argument_group_signatures = [
-        (Sig('title', description='\n'
-                                  '    oddly formatted group\n'
-                                  '\n'
-                                  'description'),
-         [Sig('-a', action='store_true',
-              help=' oddly \n'
-                   'formatted    -a  help  \n'
-                   '    again, so long that it should be wrapped over '
-                   'multiple lines')]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [-x XX] [-a] yyy
-        '''
-    help = usage + '''\
-
-        oddly formatted description that is so long that it should go onto \
-multiple
-        lines when wrapped
-
-        positional arguments:
-          yyy         normal y help
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          -x XX       oddly formatted -x help
-
-        title:
-          oddly formatted group description
-
-          -a          oddly formatted -a help again, so long that it should \
-be wrapped
-                      over multiple lines
-        '''
-    version = ''
-
-
-class TestHelpWrappingShortNames(HelpTestCase):
-    """Make sure that text after short names starts on the first line"""
-
-    parser_signature = Sig(prog='PROG', description= 'D\nD' * 30)
-    argument_signatures = [
-        Sig('-x', metavar='XX', help='XHH HX' * 20),
-        Sig('y', metavar='yyy', help='YH YH' * 20),
-    ]
-    argument_group_signatures = [
-        (Sig('ALPHAS'), [
-            Sig('-a', action='store_true', help='AHHH HHA' * 10)]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [-x XX] [-a] yyy
-        '''
-    help = usage + '''\
-
-        D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
-DD DD DD
-        DD DD DD DD D
-
-        positional arguments:
-          yyy         YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
-YHYH YHYH
-                      YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          -x XX       XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \
-HXXHH HXXHH
-                      HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX
-
-        ALPHAS:
-          -a          AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \
-HHAAHHH
-                      HHAAHHH HHAAHHH HHA
-        '''
-    version = ''
-
-
-class TestHelpWrappingLongNames(HelpTestCase):
-    """Make sure that text after long names starts on the next line"""
-
-    parser_signature = Sig(usage='USAGE', description= 'D D' * 30,
-                           version='V V'*30)
-    argument_signatures = [
-        Sig('-x', metavar='X' * 25, help='XH XH' * 20),
-        Sig('y', metavar='y' * 25, help='YH YH' * 20),
-    ]
-    argument_group_signatures = [
-        (Sig('ALPHAS'), [
-            Sig('-a', metavar='A' * 25, help='AH AH' * 20),
-            Sig('z', metavar='z' * 25, help='ZH ZH' * 20)]),
-    ]
-    usage = '''\
-        usage: USAGE
-        '''
-    help = usage + '''\
-
-        D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
-DD DD DD
-        DD DD DD DD D
-
-        positional arguments:
-          yyyyyyyyyyyyyyyyyyyyyyyyy
-                                YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
-YHYH YHYH
-                                YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
-
-        optional arguments:
-          -h, --help            show this help message and exit
-          -v, --version         show program's version number and exit
-          -x XXXXXXXXXXXXXXXXXXXXXXXXX
-                                XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \
-XHXH XHXH
-                                XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH
-
-        ALPHAS:
-          -a AAAAAAAAAAAAAAAAAAAAAAAAA
-                                AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \
-AHAH AHAH
-                                AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH
-          zzzzzzzzzzzzzzzzzzzzzzzzz
-                                ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \
-ZHZH ZHZH
-                                ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH
-        '''
-    version = '''\
-        V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \
-VV VV VV
-        VV VV VV VV V
-        '''
-
-
-class TestHelpUsage(HelpTestCase):
-    """Test basic usage messages"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-w', nargs='+', help='w'),
-        Sig('-x', nargs='*', help='x'),
-        Sig('a', help='a'),
-        Sig('b', help='b', nargs=2),
-        Sig('c', help='c', nargs='?'),
-    ]
-    argument_group_signatures = [
-        (Sig('group'), [
-            Sig('-y', nargs='?', help='y'),
-            Sig('-z', nargs=3, help='z'),
-            Sig('d', help='d', nargs='*'),
-            Sig('e', help='e', nargs='+'),
-        ])
-    ]
-    usage = '''\
-        usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z]
-                    a b b [c] [d [d ...]] e [e ...]
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          a               a
-          b               b
-          c               c
-
-        optional arguments:
-          -h, --help      show this help message and exit
-          -w W [W ...]    w
-          -x [X [X ...]]  x
-
-        group:
-          -y [Y]          y
-          -z Z Z Z        z
-          d               d
-          e               e
-        '''
-    version = ''
-
-
-class TestHelpOnlyUserGroups(HelpTestCase):
-    """Test basic usage messages"""
-
-    parser_signature = Sig(prog='PROG', add_help=False)
-    argument_signatures = []
-    argument_group_signatures = [
-        (Sig('xxxx'), [
-            Sig('-x', help='x'),
-            Sig('a', help='a'),
-        ]),
-        (Sig('yyyy'), [
-            Sig('b', help='b'),
-            Sig('-y', help='y'),
-        ]),
-    ]
-    usage = '''\
-        usage: PROG [-x X] [-y Y] a b
-        '''
-    help = usage + '''\
-
-        xxxx:
-          -x X  x
-          a     a
-
-        yyyy:
-          b     b
-          -y Y  y
-        '''
-    version = ''
-
-
-class TestHelpUsageLongProg(HelpTestCase):
-    """Test usage messages where the prog is long"""
-
-    parser_signature = Sig(prog='P' * 60)
-    argument_signatures = [
-        Sig('-w', metavar='W'),
-        Sig('-x', metavar='X'),
-        Sig('a'),
-        Sig('b'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-               [-h] [-w W] [-x X] a b
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          a
-          b
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          -w W
-          -x X
-        '''
-    version = ''
-
-
-class TestHelpUsageLongProgOptionsWrap(HelpTestCase):
-    """Test usage messages where the prog is long and the optionals wrap"""
-
-    parser_signature = Sig(prog='P' * 60)
-    argument_signatures = [
-        Sig('-w', metavar='W' * 25),
-        Sig('-x', metavar='X' * 25),
-        Sig('-y', metavar='Y' * 25),
-        Sig('-z', metavar='Z' * 25),
-        Sig('a'),
-        Sig('b'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-               [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
-[-x XXXXXXXXXXXXXXXXXXXXXXXXX]
-               [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
-               a b
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          a
-          b
-
-        optional arguments:
-          -h, --help            show this help message and exit
-          -w WWWWWWWWWWWWWWWWWWWWWWWWW
-          -x XXXXXXXXXXXXXXXXXXXXXXXXX
-          -y YYYYYYYYYYYYYYYYYYYYYYYYY
-          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
-        '''
-    version = ''
-
-
-class TestHelpUsageLongProgPositionalsWrap(HelpTestCase):
-    """Test usage messages where the prog is long and the positionals wrap"""
-
-    parser_signature = Sig(prog='P' * 60, add_help=False)
-    argument_signatures = [
-        Sig('a' * 25),
-        Sig('b' * 25),
-        Sig('c' * 25),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
-               aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
-               ccccccccccccccccccccccccc
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          aaaaaaaaaaaaaaaaaaaaaaaaa
-          bbbbbbbbbbbbbbbbbbbbbbbbb
-          ccccccccccccccccccccccccc
-        '''
-    version = ''
-
-
-class TestHelpUsageOptionalsWrap(HelpTestCase):
-    """Test usage messages where the optionals wrap"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-w', metavar='W' * 25),
-        Sig('-x', metavar='X' * 25),
-        Sig('-y', metavar='Y' * 25),
-        Sig('-z', metavar='Z' * 25),
-        Sig('a'),
-        Sig('b'),
-        Sig('c'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
-[-x XXXXXXXXXXXXXXXXXXXXXXXXX]
-                    [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \
-[-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
-                    a b c
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          a
-          b
-          c
-
-        optional arguments:
-          -h, --help            show this help message and exit
-          -w WWWWWWWWWWWWWWWWWWWWWWWWW
-          -x XXXXXXXXXXXXXXXXXXXXXXXXX
-          -y YYYYYYYYYYYYYYYYYYYYYYYYY
-          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
-        '''
-    version = ''
-
-
-class TestHelpUsagePositionalsWrap(HelpTestCase):
-    """Test usage messages where the positionals wrap"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-x'),
-        Sig('-y'),
-        Sig('-z'),
-        Sig('a' * 25),
-        Sig('b' * 25),
-        Sig('c' * 25),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-x X] [-y Y] [-z Z]
-                    aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
-                    ccccccccccccccccccccccccc
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          aaaaaaaaaaaaaaaaaaaaaaaaa
-          bbbbbbbbbbbbbbbbbbbbbbbbb
-          ccccccccccccccccccccccccc
-
-        optional arguments:
-          -h, --help            show this help message and exit
-          -x X
-          -y Y
-          -z Z
-        '''
-    version = ''
-
-
-class TestHelpUsageOptionalsPositionalsWrap(HelpTestCase):
-    """Test usage messages where the optionals and positionals wrap"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-x', metavar='X' * 25),
-        Sig('-y', metavar='Y' * 25),
-        Sig('-z', metavar='Z' * 25),
-        Sig('a' * 25),
-        Sig('b' * 25),
-        Sig('c' * 25),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
-[-y YYYYYYYYYYYYYYYYYYYYYYYYY]
-                    [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
-                    aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
-                    ccccccccccccccccccccccccc
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          aaaaaaaaaaaaaaaaaaaaaaaaa
-          bbbbbbbbbbbbbbbbbbbbbbbbb
-          ccccccccccccccccccccccccc
-
-        optional arguments:
-          -h, --help            show this help message and exit
-          -x XXXXXXXXXXXXXXXXXXXXXXXXX
-          -y YYYYYYYYYYYYYYYYYYYYYYYYY
-          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
-        '''
-    version = ''
-
-
-class TestHelpUsageOptionalsOnlyWrap(HelpTestCase):
-    """Test usage messages where there are only optionals and they wrap"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-x', metavar='X' * 25),
-        Sig('-y', metavar='Y' * 25),
-        Sig('-z', metavar='Z' * 25),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
-[-y YYYYYYYYYYYYYYYYYYYYYYYYY]
-                    [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
-        '''
-    help = usage + '''\
-
-        optional arguments:
-          -h, --help            show this help message and exit
-          -x XXXXXXXXXXXXXXXXXXXXXXXXX
-          -y YYYYYYYYYYYYYYYYYYYYYYYYY
-          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
-        '''
-    version = ''
-
-
-class TestHelpUsagePositionalsOnlyWrap(HelpTestCase):
-    """Test usage messages where there are only positionals and they wrap"""
-
-    parser_signature = Sig(prog='PROG', add_help=False)
-    argument_signatures = [
-        Sig('a' * 25),
-        Sig('b' * 25),
-        Sig('c' * 25),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
-                    ccccccccccccccccccccccccc
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          aaaaaaaaaaaaaaaaaaaaaaaaa
-          bbbbbbbbbbbbbbbbbbbbbbbbb
-          ccccccccccccccccccccccccc
-        '''
-    version = ''
-
-
-class TestHelpVariableExpansion(HelpTestCase):
-    """Test that variables are expanded properly in help messages"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-x', type=int,
-            help='x %(prog)s %(default)s %(type)s %%'),
-        Sig('-y', action='store_const', default=42, const='XXX',
-            help='y %(prog)s %(default)s %(const)s'),
-        Sig('--foo', choices='abc',
-            help='foo %(prog)s %(default)s %(choices)s'),
-        Sig('--bar', default='baz', choices=[1, 2], metavar='BBB',
-            help='bar %(prog)s %(default)s %(dest)s'),
-        Sig('spam', help='spam %(prog)s %(default)s'),
-        Sig('badger', default=0.5, help='badger %(prog)s %(default)s'),
-    ]
-    argument_group_signatures = [
-        (Sig('group'), [
-            Sig('-a', help='a %(prog)s %(default)s'),
-            Sig('-b', default=-1, help='b %(prog)s %(default)s'),
-        ])
-    ]
-    usage = ('''\
-        usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B]
-                    spam badger
-        ''')
-    help = usage + '''\
-
-        positional arguments:
-          spam           spam PROG None
-          badger         badger PROG 0.5
-
-        optional arguments:
-          -h, --help     show this help message and exit
-          -x X           x PROG None int %
-          -y             y PROG 42 XXX
-          --foo {a,b,c}  foo PROG None a, b, c
-          --bar BBB      bar PROG baz bar
-
-        group:
-          -a A           a PROG None
-          -b B           b PROG -1
-        '''
-    version = ''
-
-
-class TestHelpVariableExpansionUsageSupplied(HelpTestCase):
-    """Test that variables are expanded properly when usage= is present"""
-
-    parser_signature = Sig(prog='PROG', usage='%(prog)s FOO')
-    argument_signatures = []
-    argument_group_signatures = []
-    usage = ('''\
-        usage: PROG FOO
-        ''')
-    help = usage + '''\
-
-        optional arguments:
-          -h, --help  show this help message and exit
-        '''
-    version = ''
-
-
-class TestHelpVariableExpansionNoArguments(HelpTestCase):
-    """Test that variables are expanded properly with no arguments"""
-
-    parser_signature = Sig(prog='PROG', add_help=False)
-    argument_signatures = []
-    argument_group_signatures = []
-    usage = ('''\
-        usage: PROG
-        ''')
-    help = usage
-    version = ''
-
-
-class TestHelpSuppressUsage(HelpTestCase):
-    """Test that items can be suppressed in usage messages"""
-
-    parser_signature = Sig(prog='PROG', usage=argparse.SUPPRESS)
-    argument_signatures = [
-        Sig('--foo', help='foo help'),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = []
-    help = '''\
-        positional arguments:
-          spam        spam help
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO   foo help
-        '''
-    usage = ''
-    version = ''
-
-
-class TestHelpSuppressOptional(HelpTestCase):
-    """Test that optional arguments can be suppressed in help messages"""
-
-    parser_signature = Sig(prog='PROG', add_help=False)
-    argument_signatures = [
-        Sig('--foo', help=argparse.SUPPRESS),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG spam
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          spam  spam help
-        '''
-    version = ''
-
-
-class TestHelpSuppressOptionalGroup(HelpTestCase):
-    """Test that optional groups can be suppressed in help messages"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('--foo', help='foo help'),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = [
-        (Sig('group'), [Sig('--bar', help=argparse.SUPPRESS)]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [--foo FOO] spam
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          spam        spam help
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO   foo help
-        '''
-    version = ''
-
-
-class TestHelpSuppressPositional(HelpTestCase):
-    """Test that positional arguments can be suppressed in help messages"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('--foo', help='foo help'),
-        Sig('spam', help=argparse.SUPPRESS),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [--foo FOO]
-        '''
-    help = usage + '''\
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO   foo help
-        '''
-    version = ''
-
-
-class TestHelpRequiredOptional(HelpTestCase):
-    """Test that required options don't look optional"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('--foo', required=True, help='foo help'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] --foo FOO
-        '''
-    help = usage + '''\
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO   foo help
-        '''
-    version = ''
-
-
-class TestHelpAlternatePrefixChars(HelpTestCase):
-    """Test that options display with different prefix characters"""
-
-    parser_signature = Sig(prog='PROG', prefix_chars='^;', add_help=False)
-    argument_signatures = [
-        Sig('^^foo', action='store_true', help='foo help'),
-        Sig(';b', ';;bar', help='bar help'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [^^foo] [;b BAR]
-        '''
-    help = usage + '''\
-
-        optional arguments:
-          ^^foo              foo help
-          ;b BAR, ;;bar BAR  bar help
-        '''
-    version = ''
-
-
-class TestHelpNoHelpOptional(HelpTestCase):
-    """Test that the --help argument can be suppressed help messages"""
-
-    parser_signature = Sig(prog='PROG', add_help=False)
-    argument_signatures = [
-        Sig('--foo', help='foo help'),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [--foo FOO] spam
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          spam       spam help
-
-        optional arguments:
-          --foo FOO  foo help
-        '''
-    version = ''
-
-
-class TestHelpVersionOptional(HelpTestCase):
-    """Test that the --version argument can be suppressed help messages"""
-
-    parser_signature = Sig(prog='PROG', version='1.0')
-    argument_signatures = [
-        Sig('--foo', help='foo help'),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-v] [--foo FOO] spam
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          spam           spam help
-
-        optional arguments:
-          -h, --help     show this help message and exit
-          -v, --version  show program's version number and exit
-          --foo FOO      foo help
-        '''
-    version = '''\
-        1.0
-        '''
-
-
-class TestHelpNone(HelpTestCase):
-    """Test that no errors occur if no help is specified"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('--foo'),
-        Sig('spam'),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [--foo FOO] spam
-        '''
-    help = usage + '''\
-
-        positional arguments:
-          spam
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO
-        '''
-    version = ''
-
-
-class TestHelpTupleMetavar(HelpTestCase):
-    """Test specifying metavar as a tuple"""
-
-    parser_signature = Sig(prog='PROG')
-    argument_signatures = [
-        Sig('-w', help='w', nargs='+', metavar=('W1', 'W2')),
-        Sig('-x', help='x', nargs='*', metavar=('X1', 'X2')),
-        Sig('-y', help='y', nargs=3, metavar=('Y1', 'Y2', 'Y3')),
-        Sig('-z', help='z', nargs='?', metavar=('Z1', )),
-    ]
-    argument_group_signatures = []
-    usage = '''\
-        usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \
-[-z [Z1]]
-        '''
-    help = usage + '''\
-
-        optional arguments:
-          -h, --help        show this help message and exit
-          -w W1 [W2 ...]    w
-          -x [X1 [X2 ...]]  x
-          -y Y1 Y2 Y3       y
-          -z [Z1]           z
-        '''
-    version = ''
-
-
-class TestHelpRawText(HelpTestCase):
-    """Test the RawTextHelpFormatter"""
-
-    parser_signature = Sig(
-        prog='PROG', formatter_class=argparse.RawTextHelpFormatter,
-        description='Keep the formatting\n'
-                    '    exactly as it is written\n'
-                    '\n'
-                    'here\n')
-
-    argument_signatures = [
-        Sig('--foo', help='    foo help should also\n'
-                          'appear as given here'),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = [
-        (Sig('title', description='    This text\n'
-                                  '  should be indented\n'
-                                  '    exactly like it is here\n'),
-         [Sig('--bar', help='bar help')]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [--foo FOO] [--bar BAR] spam
-        '''
-    help = usage + '''\
-
-        Keep the formatting
-            exactly as it is written
-
-        here
-
-        positional arguments:
-          spam        spam help
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO       foo help should also
-                      appear as given here
-
-        title:
-              This text
-            should be indented
-              exactly like it is here
-
-          --bar BAR   bar help
-        '''
-    version = ''
-
-
-class TestHelpRawDescription(HelpTestCase):
-    """Test the RawTextHelpFormatter"""
-
-    parser_signature = Sig(
-        prog='PROG', formatter_class=argparse.RawDescriptionHelpFormatter,
-        description='Keep the formatting\n'
-                    '    exactly as it is written\n'
-                    '\n'
-                    'here\n')
-
-    argument_signatures = [
-        Sig('--foo', help='  foo help should not\n'
-                          '    retain this odd formatting'),
-        Sig('spam', help='spam help'),
-    ]
-    argument_group_signatures = [
-        (Sig('title', description='    This text\n'
-                                  '  should be indented\n'
-                                  '    exactly like it is here\n'),
-         [Sig('--bar', help='bar help')]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [--foo FOO] [--bar BAR] spam
-        '''
-    help = usage + '''\
-
-        Keep the formatting
-            exactly as it is written
-
-        here
-
-        positional arguments:
-          spam        spam help
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO   foo help should not retain this odd formatting
-
-        title:
-              This text
-            should be indented
-              exactly like it is here
-
-          --bar BAR   bar help
-        '''
-    version = ''
-
-
-class TestHelpArgumentDefaults(HelpTestCase):
-    """Test the ArgumentDefaultsHelpFormatter"""
-
-    parser_signature = Sig(
-        prog='PROG', formatter_class=argparse.ArgumentDefaultsHelpFormatter,
-        description='description')
-
-    argument_signatures = [
-        Sig('--foo', help='foo help - oh and by the way, %(default)s'),
-        Sig('--bar', action='store_true', help='bar help'),
-        Sig('spam', help='spam help'),
-        Sig('badger', nargs='?', default='wooden', help='badger help'),
-    ]
-    argument_group_signatures = [
-        (Sig('title', description='description'),
-         [Sig('--baz', type=int, default=42, help='baz help')]),
-    ]
-    usage = '''\
-        usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
-        '''
-    help = usage + '''\
-
-        description
-
-        positional arguments:
-          spam        spam help
-          badger      badger help (default: wooden)
-
-        optional arguments:
-          -h, --help  show this help message and exit
-          --foo FOO   foo help - oh and by the way, None
-          --bar       bar help (default: False)
-
-        title:
-          description
-
-          --baz BAZ   baz help (default: 42)
-        '''
-    version = ''
-
-# =====================================
-# Optional/Positional constructor tests
-# =====================================
-
-class TestInvalidArgumentConstructors(TestCase):
-    """Test a bunch of invalid Argument constructors"""
-
-    def assertTypeError(self, *args, **kwargs):
-        parser = argparse.ArgumentParser()
-        self.assertRaises(TypeError, parser.add_argument,
-                          *args, **kwargs)
-
-    def assertValueError(self, *args, **kwargs):
-        parser = argparse.ArgumentParser()
-        self.assertRaises(ValueError, parser.add_argument,
-                          *args, **kwargs)
-
-    def test_invalid_keyword_arguments(self):
-        self.assertTypeError('-x', bar=None)
-        self.assertTypeError('-y', callback='foo')
-        self.assertTypeError('-y', callback_args=())
-        self.assertTypeError('-y', callback_kwargs={})
-
-    def test_missing_destination(self):
-        self.assertTypeError()
-        for action in ['append', 'store']:
-            self.assertTypeError(action=action)
-
-    def test_invalid_option_strings(self):
-        self.assertValueError('--')
-        self.assertValueError('---')
-
-    def test_invalid_type(self):
-        self.assertValueError('--foo', type='int')
-
-    def test_invalid_action(self):
-        self.assertValueError('-x', action='foo')
-        self.assertValueError('foo', action='baz')
-        parser = argparse.ArgumentParser()
-        try:
-            parser.add_argument("--foo", action="store-true")
-        except ValueError:
-            e = sys.exc_info()[1]
-            expected = 'unknown action'
-            msg = 'expected %r, found %r' % (expected, e)
-            self.failUnless(expected in str(e), msg)
-
-    def test_multiple_dest(self):
-        parser = argparse.ArgumentParser()
-        parser.add_argument(dest='foo')
-        try:
-            parser.add_argument('bar', dest='baz')
-        except ValueError:
-            e = sys.exc_info()[1]
-            expected = 'dest supplied twice for positional argument'
-            msg = 'expected %r, found %r' % (expected, e)
-            self.failUnless(expected in str(e), msg)
-
-    def test_no_argument_actions(self):
-        for action in ['store_const', 'store_true', 'store_false',
-                       'append_const', 'count']:
-            for attrs in [dict(type=int), dict(nargs='+'),
-                          dict(choices='ab')]:
-                self.assertTypeError('-x', action=action, **attrs)
-
-    def test_no_argument_no_const_actions(self):
-        # options with zero arguments
-        for action in ['store_true', 'store_false', 'count']:
-
-            # const is always disallowed
-            self.assertTypeError('-x', const='foo', action=action)
-
-            # nargs is always disallowed
-            self.assertTypeError('-x', nargs='*', action=action)
-
-    def test_more_than_one_argument_actions(self):
-        for action in ['store', 'append']:
-
-            # nargs=0 is disallowed
-            self.assertValueError('-x', nargs=0, action=action)
-            self.assertValueError('spam', nargs=0, action=action)
-
-            # const is disallowed with non-optional arguments
-            for nargs in [1, '*', '+']:
-                self.assertValueError('-x', const='foo',
-                                      nargs=nargs, action=action)
-                self.assertValueError('spam', const='foo',
-                                      nargs=nargs, action=action)
-
-    def test_required_const_actions(self):
-        for action in ['store_const', 'append_const']:
-
-            # nargs is always disallowed
-            self.assertTypeError('-x', nargs='+', action=action)
-
-    def test_parsers_action_missing_params(self):
-        self.assertTypeError('command', action='parsers')
-        self.assertTypeError('command', action='parsers', prog='PROG')
-        self.assertTypeError('command', action='parsers',
-                             parser_class=argparse.ArgumentParser)
-
-    def test_required_positional(self):
-        self.assertTypeError('foo', required=True)
-
-    def test_user_defined_action(self):
-
-        class Success(Exception):
-            pass
-
-        class Action(object):
-
-            def __init__(self,
-                         option_strings,
-                         dest,
-                         const,
-                         default,
-                         required=False):
-                if dest == 'spam':
-                    if const is Success:
-                        if default is Success:
-                            raise Success()
-
-            def __call__(self, *args, **kwargs):
-                pass
-
-        parser = argparse.ArgumentParser()
-        self.assertRaises(Success, parser.add_argument, '--spam',
-                          action=Action, default=Success, const=Success)
-        self.assertRaises(Success, parser.add_argument, 'spam',
-                          action=Action, default=Success, const=Success)
-
-# ================================
-# Actions returned by add_argument
-# ================================
-
-class TestActionsReturned(TestCase):
-
-    def test_dest(self):
-        parser = argparse.ArgumentParser()
-        action = parser.add_argument('--foo')
-        self.assertEqual(action.dest, 'foo')
-        action = parser.add_argument('-b', '--bar')
-        self.assertEqual(action.dest, 'bar')
-        action = parser.add_argument('-x', '-y')
-        self.assertEqual(action.dest, 'x')
-
-    def test_misc(self):
-        parser = argparse.ArgumentParser()
-        action = parser.add_argument('--foo', nargs='?', const=42,
-                                     default=84, type=int, choices=[1, 2],
-                                     help='FOO', metavar='BAR', dest='baz')
-        self.assertEqual(action.nargs, '?')
-        self.assertEqual(action.const, 42)
-        self.assertEqual(action.default, 84)
-        self.assertEqual(action.type, int)
-        self.assertEqual(action.choices, [1, 2])
-        self.assertEqual(action.help, 'FOO')
-        self.assertEqual(action.metavar, 'BAR')
-        self.assertEqual(action.dest, 'baz')
-
-
-# ================================
-# Argument conflict handling tests
-# ================================
-
-class TestConflictHandling(TestCase):
-
-    def test_bad_type(self):
-        self.assertRaises(ValueError, argparse.ArgumentParser,
-                          conflict_handler='foo')
-
-    def test_conflict_error(self):
-        parser = argparse.ArgumentParser()
-        parser.add_argument('-x')
-        self.assertRaises(argparse.ArgumentError,
-                          parser.add_argument, '-x')
-        parser.add_argument('--spam')
-        self.assertRaises(argparse.ArgumentError,
-                          parser.add_argument, '--spam')
-
-    def test_resolve_error(self):
-        get_parser = argparse.ArgumentParser
-        parser = get_parser(prog='PROG', conflict_handler='resolve')
-
-        parser.add_argument('-x', help='OLD X')
-        parser.add_argument('-x', help='NEW X')
-        self.assertEqual(parser.format_help(), textwrap.dedent('''\
-            usage: PROG [-h] [-x X]
-
-            optional arguments:
-              -h, --help  show this help message and exit
-              -x X        NEW X
-            '''))
-
-        parser.add_argument('--spam', metavar='OLD_SPAM')
-        parser.add_argument('--spam', metavar='NEW_SPAM')
-        self.assertEqual(parser.format_help(), textwrap.dedent('''\
-            usage: PROG [-h] [-x X] [--spam NEW_SPAM]
-
-            optional arguments:
-              -h, --help       show this help message and exit
-              -x X             NEW X
-              --spam NEW_SPAM
-            '''))
-
-
-# =============================
-# Help and Version option tests
-# =============================
-
-class TestOptionalsHelpVersionActions(TestCase):
-    """Test the help and version actions"""
-
-    def _get_error(self, func, *args, **kwargs):
-        try:
-            func(*args, **kwargs)
-        except ArgumentParserError:
-            return sys.exc_info()[1]
-        else:
-            self.assertRaises(ArgumentParserError, func, *args, **kwargs)
-
-    def assertPrintHelpExit(self, parser, args_str):
-        self.assertEqual(
-            parser.format_help(),
-            self._get_error(parser.parse_args, args_str.split()).stdout)
-
-    def assertPrintVersionExit(self, parser, args_str):
-        self.assertEqual(
-            parser.format_version(),
-            self._get_error(parser.parse_args, args_str.split()).stderr)
-
-    def assertArgumentParserError(self, parser, *args):
-        self.assertRaises(ArgumentParserError, parser.parse_args, args)
-
-    def test_version(self):
-        parser = ErrorRaisingArgumentParser(version='1.0')
-        self.assertPrintHelpExit(parser, '-h')
-        self.assertPrintHelpExit(parser, '--help')
-        self.assertPrintVersionExit(parser, '-v')
-        self.assertPrintVersionExit(parser, '--version')
-
-    def test_version_format(self):
-        parser = ErrorRaisingArgumentParser(prog='PPP', version='%(prog)s 3.5')
-        msg = self._get_error(parser.parse_args, ['-v']).stderr
-        self.assertEqual('PPP 3.5\n', msg)
-
-    def test_version_no_help(self):
-        parser = ErrorRaisingArgumentParser(add_help=False, version='1.0')
-        self.assertArgumentParserError(parser, '-h')
-        self.assertArgumentParserError(parser, '--help')
-        self.assertPrintVersionExit(parser, '-v')
-        self.assertPrintVersionExit(parser, '--version')
-
-    def test_version_action(self):
-        parser = ErrorRaisingArgumentParser(prog='XXX')
-        parser.add_argument('-V', action='version', version='%(prog)s 3.7')
-        msg = self._get_error(parser.parse_args, ['-V']).stderr
-        self.assertEqual('XXX 3.7\n', msg)
-
-    def test_no_help(self):
-        parser = ErrorRaisingArgumentParser(add_help=False)
-        self.assertArgumentParserError(parser, '-h')
-        self.assertArgumentParserError(parser, '--help')
-        self.assertArgumentParserError(parser, '-v')
-        self.assertArgumentParserError(parser, '--version')
-
-    def test_alternate_help_version(self):
-        parser = ErrorRaisingArgumentParser()
-        parser.add_argument('-x', action='help')
-        parser.add_argument('-y', action='version')
-        self.assertPrintHelpExit(parser, '-x')
-        self.assertPrintVersionExit(parser, '-y')
-        self.assertArgumentParserError(parser, '-v')
-        self.assertArgumentParserError(parser, '--version')
-
-    def test_help_version_extra_arguments(self):
-        parser = ErrorRaisingArgumentParser(version='1.0')
-        parser.add_argument('-x', action='store_true')
-        parser.add_argument('y')
-
-        # try all combinations of valid prefixes and suffixes
-        valid_prefixes = ['', '-x', 'foo', '-x bar', 'baz -x']
-        valid_suffixes = valid_prefixes + ['--bad-option', 'foo bar baz']
-        for prefix in valid_prefixes:
-            for suffix in valid_suffixes:
-                format = '%s %%s %s' % (prefix, suffix)
-            self.assertPrintHelpExit(parser, format % '-h')
-            self.assertPrintHelpExit(parser, format % '--help')
-            self.assertPrintVersionExit(parser, format % '-v')
-            self.assertPrintVersionExit(parser, format % '--version')
-
-
-# ======================
-# str() and repr() tests
-# ======================
-
-class TestStrings(TestCase):
-    """Test str()  and repr() on Optionals and Positionals"""
-
-    def assertStringEqual(self, obj, result_string):
-        for func in [str, repr]:
-            self.assertEqual(func(obj), result_string)
-
-    def test_optional(self):
-        option = argparse.Action(
-            option_strings=['--foo', '-a', '-b'],
-            dest='b',
-            type='int',
-            nargs='+',
-            default=42,
-            choices=[1, 2, 3],
-            help='HELP',
-            metavar='METAVAR')
-        string = (
-            "Action(option_strings=['--foo', '-a', '-b'], dest='b', "
-            "nargs='+', const=None, default=42, type='int', "
-            "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
-        self.assertStringEqual(option, string)
-
-    def test_argument(self):
-        argument = argparse.Action(
-            option_strings=[],
-            dest='x',
-            type=float,
-            nargs='?',
-            default=2.5,
-            choices=[0.5, 1.5, 2.5],
-            help='H HH H',
-            metavar='MV MV MV')
-        string = (
-            "Action(option_strings=[], dest='x', nargs='?', "
-            "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
-            "help='H HH H', metavar='MV MV MV')" % float)
-        self.assertStringEqual(argument, string)
-
-    def test_namespace(self):
-        ns = argparse.Namespace(foo=42, bar='spam')
-        string = "Namespace(bar='spam', foo=42)"
-        self.assertStringEqual(ns, string)
-
-    def test_parser(self):
-        parser = argparse.ArgumentParser(prog='PROG')
-        string = (
-            "ArgumentParser(prog='PROG', usage=None, description=None, "
-            "version=None, formatter_class=%r, conflict_handler='error', "
-            "add_help=True)" % argparse.HelpFormatter)
-        self.assertStringEqual(parser, string)
-
-# ===============
-# Namespace tests
-# ===============
-
-class TestNamespace(TestCase):
-
-    def test_constructor(self):
-        ns = argparse.Namespace()
-        self.assertRaises(AttributeError, getattr, ns, 'x')
-
-        ns = argparse.Namespace(a=42, b='spam')
-        self.assertEqual(ns.a, 42)
-        self.assertEqual(ns.b, 'spam')
-
-    def test_equality(self):
-        ns1 = argparse.Namespace(a=1, b=2)
-        ns2 = argparse.Namespace(b=2, a=1)
-        ns3 = argparse.Namespace(a=1)
-        ns4 = argparse.Namespace(b=2)
-
-        self.assertEqual(ns1, ns2)
-        self.assertNotEqual(ns1, ns3)
-        self.assertNotEqual(ns1, ns4)
-        self.assertNotEqual(ns2, ns3)
-        self.assertNotEqual(ns2, ns4)
-        self.failUnless(ns1 != ns3)
-        self.failUnless(ns1 != ns4)
-        self.failUnless(ns2 != ns3)
-        self.failUnless(ns2 != ns4)
-
-
-# ===================
-# File encoding tests
-# ===================
-
-class TestEncoding(TestCase):
-
-    def _test_module_encoding(self, path):
-        path, _ = os.path.splitext(path)
-        path += ".py"
-        codecs.open(path, 'r', 'utf8').read()
-
-    def test_argparse_module_encoding(self):
-        self._test_module_encoding(argparse.__file__)
-
-    def test_test_argparse_module_encoding(self):
-        self._test_module_encoding(__file__)
-
-# ===================
-# ArgumentError tests
-# ===================
-
-class TestArgumentError(TestCase):
-
-    def test_argument_error(self):
-        msg = "my error here"
-        error = argparse.ArgumentError(None, msg)
-        self.failUnlessEqual(str(error), msg)
-
-# =======================
-# ArgumentTypeError tests
-# =======================
-
-class TestArgumentError(TestCase):
-
-    def test_argument_type_error(self):
-
-        def spam(string):
-            raise argparse.ArgumentTypeError('spam!')
-
-        parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
-        parser.add_argument('x', type=spam)
-        try:
-            parser.parse_args(['XXX'])
-        except ArgumentParserError:
-            expected = 'usage: PROG x\nPROG: error: argument x: spam!\n'
-            msg = sys.exc_info()[1].stderr
-            self.failUnlessEqual(expected, msg)
-        else:
-            self.fail()
-
-# ======================
-# parse_known_args tests
-# ======================
-
-class TestParseKnownArgs(TestCase):
-
-    def test_optionals(self):
-        parser = argparse.ArgumentParser()
-        parser.add_argument('--foo')
-        args, extras = parser.parse_known_args('--foo F --bar --baz'.split())
-        self.failUnlessEqual(NS(foo='F'), args)
-        self.failUnlessEqual(['--bar', '--baz'], extras)
-
-    def test_mixed(self):
-        parser = argparse.ArgumentParser()
-        parser.add_argument('-v', nargs='?', const=1, type=int)
-        parser.add_argument('--spam', action='store_false')
-        parser.add_argument('badger')
-
-        argv = ["B", "C", "--foo", "-v", "3", "4"]
-        args, extras = parser.parse_known_args(argv)
-        self.failUnlessEqual(NS(v=3, spam=True, badger="B"), args)
-        self.failUnlessEqual(["C", "--foo", "4"], extras)
-
-# ============================
-# from argparse import * tests
-# ============================
-
-class TestImportStar(TestCase):
-
-    def test(self):
-        for name in argparse.__all__:
-            self.failUnless(hasattr(argparse, name))
-
-
-if __name__ == '__main__':
-    unittest.main()
+# -*- coding: utf-8 -*-
+
+# Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy
+# of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import codecs
+import os
+import shutil
+import sys
+import textwrap
+import tempfile
+import unittest
+import argparse
+
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+try:
+    sorted
+except NameError:
+
+    def sorted(iterable, reverse=False):
+        result = list(iterable)
+        result.sort()
+        if reverse:
+            result.reverse()
+        return result
+
+# silence Python 2.6 buggy warnings about Exception.message
+if sys.version_info[:2] == (2, 6):
+    import warnings
+    warnings.filterwarnings(
+        action='ignore',
+        message='BaseException.message has been deprecated as of Python 2.6',
+        category=DeprecationWarning)
+
+# silence warnings about version argument - these are expected
+import warnings
+warnings.filterwarnings(
+    action='ignore',
+    message='The "version" argument to ArgumentParser is deprecated.',
+    category=DeprecationWarning)
+warnings.filterwarnings(
+    action='ignore',
+    message='The format_version method is deprecated',
+    category=DeprecationWarning)
+warnings.filterwarnings(
+    action='ignore',
+    message='The print_version method is deprecated',
+    category=DeprecationWarning)
+
+
+class TestCase(unittest.TestCase):
+
+    def assertEqual(self, obj1, obj2):
+        if obj1 != obj2:
+            print('')
+            print(repr(obj1))
+            print(repr(obj2))
+            print(obj1)
+            print(obj2)
+        super(TestCase, self).assertEqual(obj1, obj2)
+
+
+class TempDirMixin(object):
+
+    def setUp(self):
+        self.temp_dir = tempfile.mkdtemp()
+        self.old_dir = os.getcwd()
+        os.chdir(self.temp_dir)
+
+    def tearDown(self):
+        os.chdir(self.old_dir)
+        while True:
+            try:
+                shutil.rmtree(self.temp_dir)
+            except WindowsError:
+                continue
+            else:
+                break
+
+
+class Sig(object):
+
+    def __init__(self, *args, **kwargs):
+        self.args = args
+        self.kwargs = kwargs
+
+
+class NS(object):
+
+    def __init__(self, **kwargs):
+        self.__dict__.update(kwargs)
+
+    def __repr__(self):
+        sorted_items = sorted(self.__dict__.items())
+        kwarg_str = ', '.join(['%s=%r' % tup for tup in sorted_items])
+        return '%s(%s)' % (type(self).__name__, kwarg_str)
+
+    def __eq__(self, other):
+        return vars(self) == vars(other)
+
+    def __ne__(self, other):
+        return not (self == other)
+
+
+class ArgumentParserError(Exception):
+
+    def __init__(self, message, stdout=None, stderr=None, error_code=None):
+        Exception.__init__(self, message, stdout, stderr)
+        self.message = message
+        self.stdout = stdout
+        self.stderr = stderr
+        self.error_code = error_code
+
+
+def stderr_to_parser_error(parse_args, *args, **kwargs):
+    # if this is being called recursively and stderr or stdout is already being
+    # redirected, simply call the function and let the enclosing function
+    # catch the exception
+    if isinstance(sys.stderr, StringIO) or isinstance(sys.stdout, StringIO):
+        return parse_args(*args, **kwargs)
+
+    # if this is not being called recursively, redirect stderr and
+    # use it as the ArgumentParserError message
+    old_stdout = sys.stdout
+    old_stderr = sys.stderr
+    sys.stdout = StringIO()
+    sys.stderr = StringIO()
+    try:
+        try:
+            result = parse_args(*args, **kwargs)
+            for key in list(vars(result)):
+                if getattr(result, key) is sys.stdout:
+                    setattr(result, key, old_stdout)
+                if getattr(result, key) is sys.stderr:
+                    setattr(result, key, old_stderr)
+            return result
+        except SystemExit:
+            code = sys.exc_info()[1].code
+            stdout = sys.stdout.getvalue()
+            stderr = sys.stderr.getvalue()
+            raise ArgumentParserError("SystemExit", stdout, stderr, code)
+    finally:
+        sys.stdout = old_stdout
+        sys.stderr = old_stderr
+
+
+class ErrorRaisingArgumentParser(argparse.ArgumentParser):
+
+    def parse_args(self, *args, **kwargs):
+        parse_args = super(ErrorRaisingArgumentParser, self).parse_args
+        return stderr_to_parser_error(parse_args, *args, **kwargs)
+
+    def exit(self, *args, **kwargs):
+        exit = super(ErrorRaisingArgumentParser, self).exit
+        return stderr_to_parser_error(exit, *args, **kwargs)
+
+    def error(self, *args, **kwargs):
+        error = super(ErrorRaisingArgumentParser, self).error
+        return stderr_to_parser_error(error, *args, **kwargs)
+
+
+class ParserTesterMetaclass(type):
+    """Adds parser tests using the class attributes.
+
+    Classes of this type should specify the following attributes:
+
+    argument_signatures -- a list of Sig objects which specify
+        the signatures of Argument objects to be created
+    failures -- a list of args lists that should cause the parser
+        to fail
+    successes -- a list of (initial_args, options, remaining_args) tuples
+        where initial_args specifies the string args to be parsed,
+        options is a dict that should match the vars() of the options
+        parsed out of initial_args, and remaining_args should be any
+        remaining unparsed arguments
+    """
+
+    def __init__(cls, name, bases, bodydict):
+        if name == 'ParserTestCase':
+            return
+
+        # default parser signature is empty
+        if not hasattr(cls, 'parser_signature'):
+            cls.parser_signature = Sig()
+        if not hasattr(cls, 'parser_class'):
+            cls.parser_class = ErrorRaisingArgumentParser
+
+        # ---------------------------------------
+        # functions for adding optional arguments
+        # ---------------------------------------
+        def no_groups(parser, argument_signatures):
+            """Add all arguments directly to the parser"""
+            for sig in argument_signatures:
+                parser.add_argument(*sig.args, **sig.kwargs)
+
+        def one_group(parser, argument_signatures):
+            """Add all arguments under a single group in the parser"""
+            group = parser.add_argument_group('foo')
+            for sig in argument_signatures:
+                group.add_argument(*sig.args, **sig.kwargs)
+
+        def many_groups(parser, argument_signatures):
+            """Add each argument in its own group to the parser"""
+            for i, sig in enumerate(argument_signatures):
+                group = parser.add_argument_group('foo:%i' % i)
+                group.add_argument(*sig.args, **sig.kwargs)
+
+        # --------------------------
+        # functions for parsing args
+        # --------------------------
+        def listargs(parser, args):
+            """Parse the args by passing in a list"""
+            return parser.parse_args(args)
+
+        def sysargs(parser, args):
+            """Parse the args by defaulting to sys.argv"""
+            old_sys_argv = sys.argv
+            sys.argv = [old_sys_argv[0]] + args
+            try:
+                return parser.parse_args()
+            finally:
+                sys.argv = old_sys_argv
+
+        # class that holds the combination of one optional argument
+        # addition method and one arg parsing method
+        class AddTests(object):
+
+            def __init__(self, tester_cls, add_arguments, parse_args):
+                self._add_arguments = add_arguments
+                self._parse_args = parse_args
+
+                add_arguments_name = self._add_arguments.__name__
+                parse_args_name = self._parse_args.__name__
+                for test_func in [self.test_failures, self.test_successes]:
+                    func_name = test_func.__name__
+                    names = func_name, add_arguments_name, parse_args_name
+                    test_name = '_'.join(names)
+
+                    def wrapper(self, test_func=test_func):
+                        test_func(self)
+                    try:
+                        wrapper.__name__ = test_name
+                    except TypeError:
+                        pass
+                    setattr(tester_cls, test_name, wrapper)
+
+            def _get_parser(self, tester):
+                args = tester.parser_signature.args
+                kwargs = tester.parser_signature.kwargs
+                parser = tester.parser_class(*args, **kwargs)
+                self._add_arguments(parser, tester.argument_signatures)
+                return parser
+
+            def test_failures(self, tester):
+                parser = self._get_parser(tester)
+                for args_str in tester.failures:
+                    args = args_str.split()
+                    raises = tester.assertRaises
+                    raises(ArgumentParserError, parser.parse_args, args)
+
+            def test_successes(self, tester):
+                parser = self._get_parser(tester)
+                for args, expected_ns in tester.successes:
+                    if isinstance(args, str):
+                        args = args.split()
+                    result_ns = self._parse_args(parser, args)
+                    tester.assertEqual(expected_ns, result_ns)
+
+        # add tests for each combination of an optionals adding method
+        # and an arg parsing method
+        for add_arguments in [no_groups, one_group, many_groups]:
+            for parse_args in [listargs, sysargs]:
+                AddTests(cls, add_arguments, parse_args)
+
+bases = TestCase,
+ParserTestCase = ParserTesterMetaclass('ParserTestCase', bases, {})
+
+# ===============
+# Optionals tests
+# ===============
+
+class TestOptionalsSingleDash(ParserTestCase):
+    """Test an Optional with a single-dash option string"""
+
+    argument_signatures = [Sig('-x')]
+    failures = ['-x', 'a', '--foo', '-x --foo', '-x -y']
+    successes = [
+        ('', NS(x=None)),
+        ('-x a', NS(x='a')),
+        ('-xa', NS(x='a')),
+        ('-x -1', NS(x='-1')),
+        ('-x-1', NS(x='-1')),
+    ]
+
+
+class TestOptionalsSingleDashCombined(ParserTestCase):
+    """Test an Optional with a single-dash option string"""
+
+    argument_signatures = [
+        Sig('-x', action='store_true'),
+        Sig('-yyy', action='store_const', const=42),
+        Sig('-z'),
+    ]
+    failures = ['a', '--foo', '-xa', '-x --foo', '-x -z', '-z -x',
+                '-yx', '-yz a', '-yyyx', '-yyyza', '-xyza']
+    successes = [
+        ('', NS(x=False, yyy=None, z=None)),
+        ('-x', NS(x=True, yyy=None, z=None)),
+        ('-za', NS(x=False, yyy=None, z='a')),
+        ('-z a', NS(x=False, yyy=None, z='a')),
+        ('-xza', NS(x=True, yyy=None, z='a')),
+        ('-xz a', NS(x=True, yyy=None, z='a')),
+        ('-x -za', NS(x=True, yyy=None, z='a')),
+        ('-x -z a', NS(x=True, yyy=None, z='a')),
+        ('-y', NS(x=False, yyy=42, z=None)),
+        ('-yyy', NS(x=False, yyy=42, z=None)),
+        ('-x -yyy -za', NS(x=True, yyy=42, z='a')),
+        ('-x -yyy -z a', NS(x=True, yyy=42, z='a')),
+    ]
+
+
+class TestOptionalsSingleDashLong(ParserTestCase):
+    """Test an Optional with a multi-character single-dash option string"""
+
+    argument_signatures = [Sig('-foo')]
+    failures = ['-foo', 'a', '--foo', '-foo --foo', '-foo -y', '-fooa']
+    successes = [
+        ('', NS(foo=None)),
+        ('-foo a', NS(foo='a')),
+        ('-foo -1', NS(foo='-1')),
+        ('-fo a', NS(foo='a')),
+        ('-f a', NS(foo='a')),
+    ]
+
+
+class TestOptionalsSingleDashSubsetAmbiguous(ParserTestCase):
+    """Test Optionals where option strings are subsets of each other"""
+
+    argument_signatures = [Sig('-f'), Sig('-foobar'), Sig('-foorab')]
+    failures = ['-f', '-foo', '-fo', '-foo b', '-foob', '-fooba', '-foora']
+    successes = [
+        ('', NS(f=None, foobar=None, foorab=None)),
+        ('-f a', NS(f='a', foobar=None, foorab=None)),
+        ('-fa', NS(f='a', foobar=None, foorab=None)),
+        ('-foa', NS(f='oa', foobar=None, foorab=None)),
+        ('-fooa', NS(f='ooa', foobar=None, foorab=None)),
+        ('-foobar a', NS(f=None, foobar='a', foorab=None)),
+        ('-foorab a', NS(f=None, foobar=None, foorab='a')),
+    ]
+
+
+class TestOptionalsSingleDashAmbiguous(ParserTestCase):
+    """Test Optionals that partially match but are not subsets"""
+
+    argument_signatures = [Sig('-foobar'), Sig('-foorab')]
+    failures = ['-f', '-f a', '-fa', '-foa', '-foo', '-fo', '-foo b']
+    successes = [
+        ('', NS(foobar=None, foorab=None)),
+        ('-foob a', NS(foobar='a', foorab=None)),
+        ('-foor a', NS(foobar=None, foorab='a')),
+        ('-fooba a', NS(foobar='a', foorab=None)),
+        ('-foora a', NS(foobar=None, foorab='a')),
+        ('-foobar a', NS(foobar='a', foorab=None)),
+        ('-foorab a', NS(foobar=None, foorab='a')),
+    ]
+
+
+class TestOptionalsNumeric(ParserTestCase):
+    """Test an Optional with a short opt string"""
+
+    argument_signatures = [Sig('-1', dest='one')]
+    failures = ['-1', 'a', '-1 --foo', '-1 -y', '-1 -1', '-1 -2']
+    successes = [
+        ('', NS(one=None)),
+        ('-1 a', NS(one='a')),
+        ('-1a', NS(one='a')),
+        ('-1-2', NS(one='-2')),
+    ]
+
+
+class TestOptionalsDoubleDash(ParserTestCase):
+    """Test an Optional with a double-dash option string"""
+
+    argument_signatures = [Sig('--foo')]
+    failures = ['--foo', '-f', '-f a', 'a', '--foo -x', '--foo --bar']
+    successes = [
+        ('', NS(foo=None)),
+        ('--foo a', NS(foo='a')),
+        ('--foo=a', NS(foo='a')),
+        ('--foo -2.5', NS(foo='-2.5')),
+        ('--foo=-2.5', NS(foo='-2.5')),
+    ]
+
+
+class TestOptionalsDoubleDashPartialMatch(ParserTestCase):
+    """Tests partial matching with a double-dash option string"""
+
+    argument_signatures = [
+        Sig('--badger', action='store_true'),
+        Sig('--bat'),
+    ]
+    failures = ['--bar', '--b', '--ba', '--b=2', '--ba=4', '--badge 5']
+    successes = [
+        ('', NS(badger=False, bat=None)),
+        ('--bat X', NS(badger=False, bat='X')),
+        ('--bad', NS(badger=True, bat=None)),
+        ('--badg', NS(badger=True, bat=None)),
+        ('--badge', NS(badger=True, bat=None)),
+        ('--badger', NS(badger=True, bat=None)),
+    ]
+
+
+class TestOptionalsDoubleDashPrefixMatch(ParserTestCase):
+    """Tests when one double-dash option string is a prefix of another"""
+
+    argument_signatures = [
+        Sig('--badger', action='store_true'),
+        Sig('--ba'),
+    ]
+    failures = ['--bar', '--b', '--ba', '--b=2', '--badge 5']
+    successes = [
+        ('', NS(badger=False, ba=None)),
+        ('--ba X', NS(badger=False, ba='X')),
+        ('--ba=X', NS(badger=False, ba='X')),
+        ('--bad', NS(badger=True, ba=None)),
+        ('--badg', NS(badger=True, ba=None)),
+        ('--badge', NS(badger=True, ba=None)),
+        ('--badger', NS(badger=True, ba=None)),
+    ]
+
+
+class TestOptionalsSingleDoubleDash(ParserTestCase):
+    """Test an Optional with single- and double-dash option strings"""
+
+    argument_signatures = [
+        Sig('-f', action='store_true'),
+        Sig('--bar'),
+        Sig('-baz', action='store_const', const=42),
+    ]
+    failures = ['--bar', '-fbar', '-fbaz', '-bazf', '-b B', 'B']
+    successes = [
+        ('', NS(f=False, bar=None, baz=None)),
+        ('-f', NS(f=True, bar=None, baz=None)),
+        ('--ba B', NS(f=False, bar='B', baz=None)),
+        ('-f --bar B', NS(f=True, bar='B', baz=None)),
+        ('-f -b', NS(f=True, bar=None, baz=42)),
+        ('-ba -f', NS(f=True, bar=None, baz=42)),
+    ]
+
+
+class TestOptionalsAlternatePrefixChars(ParserTestCase):
+    """Test an Optional with a double-dash option string"""
+
+    parser_signature = Sig(prefix_chars='+:/', add_help=False)
+    argument_signatures = [
+        Sig('+f', action='store_true'),
+        Sig('::bar'),
+        Sig('/baz', action='store_const', const=42),
+    ]
+    failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
+    successes = [
+        ('', NS(f=False, bar=None, baz=None)),
+        ('+f', NS(f=True, bar=None, baz=None)),
+        ('::ba B', NS(f=False, bar='B', baz=None)),
+        ('+f ::bar B', NS(f=True, bar='B', baz=None)),
+        ('+f /b', NS(f=True, bar=None, baz=42)),
+        ('/ba +f', NS(f=True, bar=None, baz=42)),
+    ]
+
+
+class TestOptionalsShortLong(ParserTestCase):
+    """Test a combination of single- and double-dash option strings"""
+
+    argument_signatures = [
+        Sig('-v', '--verbose', '-n', '--noisy', action='store_true'),
+    ]
+    failures = ['--x --verbose', '-N', 'a', '-v x']
+    successes = [
+        ('', NS(verbose=False)),
+        ('-v', NS(verbose=True)),
+        ('--verbose', NS(verbose=True)),
+        ('-n', NS(verbose=True)),
+        ('--noisy', NS(verbose=True)),
+    ]
+
+
+class TestOptionalsDest(ParserTestCase):
+    """Tests various means of setting destination"""
+
+    argument_signatures = [Sig('--foo-bar'), Sig('--baz', dest='zabbaz')]
+    failures = ['a']
+    successes = [
+        ('--foo-bar f', NS(foo_bar='f', zabbaz=None)),
+        ('--baz g', NS(foo_bar=None, zabbaz='g')),
+        ('--foo-bar h --baz i', NS(foo_bar='h', zabbaz='i')),
+        ('--baz j --foo-bar k', NS(foo_bar='k', zabbaz='j')),
+    ]
+
+
+class TestOptionalsDefault(ParserTestCase):
+    """Tests specifying a default for an Optional"""
+
+    argument_signatures = [Sig('-x'), Sig('-y', default=42)]
+    failures = ['a']
+    successes = [
+        ('', NS(x=None, y=42)),
+        ('-xx', NS(x='x', y=42)),
+        ('-yy', NS(x=None, y='y')),
+    ]
+
+
+class TestOptionalsNargsDefault(ParserTestCase):
+    """Tests not specifying the number of args for an Optional"""
+
+    argument_signatures = [Sig('-x')]
+    failures = ['a', '-x']
+    successes = [
+        ('', NS(x=None)),
+        ('-x a', NS(x='a')),
+    ]
+
+
+class TestOptionalsNargs1(ParserTestCase):
+    """Tests specifying the 1 arg for an Optional"""
+
+    argument_signatures = [Sig('-x', nargs=1)]
+    failures = ['a', '-x']
+    successes = [
+        ('', NS(x=None)),
+        ('-x a', NS(x=['a'])),
+    ]
+
+
+class TestOptionalsNargs3(ParserTestCase):
+    """Tests specifying the 3 args for an Optional"""
+
+    argument_signatures = [Sig('-x', nargs=3)]
+    failures = ['a', '-x', '-x a', '-x a b', 'a -x', 'a -x b']
+    successes = [
+        ('', NS(x=None)),
+        ('-x a b c', NS(x=['a', 'b', 'c'])),
+    ]
+
+
+class TestOptionalsNargsOptional(ParserTestCase):
+    """Tests specifying an Optional arg for an Optional"""
+
+    argument_signatures = [
+        Sig('-w', nargs='?'),
+        Sig('-x', nargs='?', const=42),
+        Sig('-y', nargs='?', default='spam'),
+        Sig('-z', nargs='?', type=int, const='42', default='84'),
+    ]
+    failures = ['2']
+    successes = [
+        ('', NS(w=None, x=None, y='spam', z=84)),
+        ('-w', NS(w=None, x=None, y='spam', z=84)),
+        ('-w 2', NS(w='2', x=None, y='spam', z=84)),
+        ('-x', NS(w=None, x=42, y='spam', z=84)),
+        ('-x 2', NS(w=None, x='2', y='spam', z=84)),
+        ('-y', NS(w=None, x=None, y=None, z=84)),
+        ('-y 2', NS(w=None, x=None, y='2', z=84)),
+        ('-z', NS(w=None, x=None, y='spam', z=42)),
+        ('-z 2', NS(w=None, x=None, y='spam', z=2)),
+    ]
+
+
+class TestOptionalsNargsZeroOrMore(ParserTestCase):
+    """Tests specifying an args for an Optional that accepts zero or more"""
+
+    argument_signatures = [
+        Sig('-x', nargs='*'),
+        Sig('-y', nargs='*', default='spam'),
+    ]
+    failures = ['a']
+    successes = [
+        ('', NS(x=None, y='spam')),
+        ('-x', NS(x=[], y='spam')),
+        ('-x a', NS(x=['a'], y='spam')),
+        ('-x a b', NS(x=['a', 'b'], y='spam')),
+        ('-y', NS(x=None, y=[])),
+        ('-y a', NS(x=None, y=['a'])),
+        ('-y a b', NS(x=None, y=['a', 'b'])),
+    ]
+
+
+class TestOptionalsNargsOneOrMore(ParserTestCase):
+    """Tests specifying an args for an Optional that accepts one or more"""
+
+    argument_signatures = [
+        Sig('-x', nargs='+'),
+        Sig('-y', nargs='+', default='spam'),
+    ]
+    failures = ['a', '-x', '-y', 'a -x', 'a -y b']
+    successes = [
+        ('', NS(x=None, y='spam')),
+        ('-x a', NS(x=['a'], y='spam')),
+        ('-x a b', NS(x=['a', 'b'], y='spam')),
+        ('-y a', NS(x=None, y=['a'])),
+        ('-y a b', NS(x=None, y=['a', 'b'])),
+    ]
+
+
+class TestOptionalsChoices(ParserTestCase):
+    """Tests specifying the choices for an Optional"""
+
+    argument_signatures = [
+        Sig('-f', choices='abc'),
+        Sig('-g', type=int, choices=range(5))]
+    failures = ['a', '-f d', '-fad', '-ga', '-g 6']
+    successes = [
+        ('', NS(f=None, g=None)),
+        ('-f a', NS(f='a', g=None)),
+        ('-f c', NS(f='c', g=None)),
+        ('-g 0', NS(f=None, g=0)),
+        ('-g 03', NS(f=None, g=3)),
+        ('-fb -g4', NS(f='b', g=4)),
+    ]
+
+
+class TestOptionalsRequired(ParserTestCase):
+    """Tests the an optional action that is required"""
+
+    argument_signatures = [
+        Sig('-x', type=int, required=True),
+    ]
+    failures = ['a', '']
+    successes = [
+        ('-x 1', NS(x=1)),
+        ('-x42', NS(x=42)),
+    ]
+
+
+class TestOptionalsActionStore(ParserTestCase):
+    """Tests the store action for an Optional"""
+
+    argument_signatures = [Sig('-x', action='store')]
+    failures = ['a', 'a -x']
+    successes = [
+        ('', NS(x=None)),
+        ('-xfoo', NS(x='foo')),
+    ]
+
+
+class TestOptionalsActionStoreConst(ParserTestCase):
+    """Tests the store_const action for an Optional"""
+
+    argument_signatures = [Sig('-y', action='store_const', const=object)]
+    failures = ['a']
+    successes = [
+        ('', NS(y=None)),
+        ('-y', NS(y=object)),
+    ]
+
+
+class TestOptionalsActionStoreFalse(ParserTestCase):
+    """Tests the store_false action for an Optional"""
+
+    argument_signatures = [Sig('-z', action='store_false')]
+    failures = ['a', '-za', '-z a']
+    successes = [
+        ('', NS(z=True)),
+        ('-z', NS(z=False)),
+    ]
+
+
+class TestOptionalsActionStoreTrue(ParserTestCase):
+    """Tests the store_true action for an Optional"""
+
+    argument_signatures = [Sig('--apple', action='store_true')]
+    failures = ['a', '--apple=b', '--apple b']
+    successes = [
+        ('', NS(apple=False)),
+        ('--apple', NS(apple=True)),
+    ]
+
+
+class TestOptionalsActionAppend(ParserTestCase):
+    """Tests the append action for an Optional"""
+
+    argument_signatures = [Sig('--baz', action='append')]
+    failures = ['a', '--baz', 'a --baz', '--baz a b']
+    successes = [
+        ('', NS(baz=None)),
+        ('--baz a', NS(baz=['a'])),
+        ('--baz a --baz b', NS(baz=['a', 'b'])),
+    ]
+
+
+class TestOptionalsActionAppendWithDefault(ParserTestCase):
+    """Tests the append action for an Optional"""
+
+    argument_signatures = [Sig('--baz', action='append', default=['X'])]
+    failures = ['a', '--baz', 'a --baz', '--baz a b']
+    successes = [
+        ('', NS(baz=['X'])),
+        ('--baz a', NS(baz=['X', 'a'])),
+        ('--baz a --baz b', NS(baz=['X', 'a', 'b'])),
+    ]
+
+
+class TestOptionalsActionAppendConst(ParserTestCase):
+    """Tests the append_const action for an Optional"""
+
+    argument_signatures = [
+        Sig('-b', action='append_const', const=Exception),
+        Sig('-c', action='append', dest='b'),
+    ]
+    failures = ['a', '-c', 'a -c', '-bx', '-b x']
+    successes = [
+        ('', NS(b=None)),
+        ('-b', NS(b=[Exception])),
+        ('-b -cx -b -cyz', NS(b=[Exception, 'x', Exception, 'yz'])),
+    ]
+
+
+class TestOptionalsActionAppendConstWithDefault(ParserTestCase):
+    """Tests the append_const action for an Optional"""
+
+    argument_signatures = [
+        Sig('-b', action='append_const', const=Exception, default=['X']),
+        Sig('-c', action='append', dest='b'),
+    ]
+    failures = ['a', '-c', 'a -c', '-bx', '-b x']
+    successes = [
+        ('', NS(b=['X'])),
+        ('-b', NS(b=['X', Exception])),
+        ('-b -cx -b -cyz', NS(b=['X', Exception, 'x', Exception, 'yz'])),
+    ]
+
+
+class TestOptionalsActionCount(ParserTestCase):
+    """Tests the count action for an Optional"""
+
+    argument_signatures = [Sig('-x', action='count')]
+    failures = ['a', '-x a', '-x b', '-x a -x b']
+    successes = [
+        ('', NS(x=None)),
+        ('-x', NS(x=1)),
+    ]
+
+
+# ================
+# Positional tests
+# ================
+
+class TestPositionalsNargsNone(ParserTestCase):
+    """Test a Positional that doesn't specify nargs"""
+
+    argument_signatures = [Sig('foo')]
+    failures = ['', '-x', 'a b']
+    successes = [
+        ('a', NS(foo='a')),
+    ]
+
+
+class TestPositionalsNargs1(ParserTestCase):
+    """Test a Positional that specifies an nargs of 1"""
+
+    argument_signatures = [Sig('foo', nargs=1)]
+    failures = ['', '-x', 'a b']
+    successes = [
+        ('a', NS(foo=['a'])),
+    ]
+
+
+class TestPositionalsNargs2(ParserTestCase):
+    """Test a Positional that specifies an nargs of 2"""
+
+    argument_signatures = [Sig('foo', nargs=2)]
+    failures = ['', 'a', '-x', 'a b c']
+    successes = [
+        ('a b', NS(foo=['a', 'b'])),
+    ]
+
+
+class TestPositionalsNargsZeroOrMore(ParserTestCase):
+    """Test a Positional that specifies unlimited nargs"""
+
+    argument_signatures = [Sig('foo', nargs='*')]
+    failures = ['-x']
+    successes = [
+        ('', NS(foo=[])),
+        ('a', NS(foo=['a'])),
+        ('a b', NS(foo=['a', 'b'])),
+    ]
+
+
+class TestPositionalsNargsZeroOrMoreDefault(ParserTestCase):
+    """Test a Positional that specifies unlimited nargs and a default"""
+
+    argument_signatures = [Sig('foo', nargs='*', default='bar')]
+    failures = ['-x']
+    successes = [
+        ('', NS(foo='bar')),
+        ('a', NS(foo=['a'])),
+        ('a b', NS(foo=['a', 'b'])),
+    ]
+
+
+class TestPositionalsNargsOneOrMore(ParserTestCase):
+    """Test a Positional that specifies one or more nargs"""
+
+    argument_signatures = [Sig('foo', nargs='+')]
+    failures = ['', '-x']
+    successes = [
+        ('a', NS(foo=['a'])),
+        ('a b', NS(foo=['a', 'b'])),
+    ]
+
+
+class TestPositionalsNargsOptional(ParserTestCase):
+    """Tests an Optional Positional"""
+
+    argument_signatures = [Sig('foo', nargs='?')]
+    failures = ['-x', 'a b']
+    successes = [
+        ('', NS(foo=None)),
+        ('a', NS(foo='a')),
+    ]
+
+
+class TestPositionalsNargsOptionalDefault(ParserTestCase):
+    """Tests an Optional Positional with a default value"""
+
+    argument_signatures = [Sig('foo', nargs='?', default=42)]
+    failures = ['-x', 'a b']
+    successes = [
+        ('', NS(foo=42)),
+        ('a', NS(foo='a')),
+    ]
+
+
+class TestPositionalsNargsOptionalConvertedDefault(ParserTestCase):
+    """Tests an Optional Positional with a default value
+    that needs to be converted to the appropriate type.
+    """
+
+    argument_signatures = [
+        Sig('foo', nargs='?', type=int, default='42'),
+    ]
+    failures = ['-x', 'a b', '1 2']
+    successes = [
+        ('', NS(foo=42)),
+        ('1', NS(foo=1)),
+    ]
+
+
+class TestPositionalsNargsNoneNone(ParserTestCase):
+    """Test two Positionals that don't specify nargs"""
+
+    argument_signatures = [Sig('foo'), Sig('bar')]
+    failures = ['', '-x', 'a', 'a b c']
+    successes = [
+        ('a b', NS(foo='a', bar='b')),
+    ]
+
+
+class TestPositionalsNargsNone1(ParserTestCase):
+    """Test a Positional with no nargs followed by one with 1"""
+
+    argument_signatures = [Sig('foo'), Sig('bar', nargs=1)]
+    failures = ['', '--foo', 'a', 'a b c']
+    successes = [
+        ('a b', NS(foo='a', bar=['b'])),
+    ]
+
+
+class TestPositionalsNargs2None(ParserTestCase):
+    """Test a Positional with 2 nargs followed by one with none"""
+
+    argument_signatures = [Sig('foo', nargs=2), Sig('bar')]
+    failures = ['', '--foo', 'a', 'a b', 'a b c d']
+    successes = [
+        ('a b c', NS(foo=['a', 'b'], bar='c')),
+    ]
+
+
+class TestPositionalsNargsNoneZeroOrMore(ParserTestCase):
+    """Test a Positional with no nargs followed by one with unlimited"""
+
+    argument_signatures = [Sig('foo'), Sig('bar', nargs='*')]
+    failures = ['', '--foo']
+    successes = [
+        ('a', NS(foo='a', bar=[])),
+        ('a b', NS(foo='a', bar=['b'])),
+        ('a b c', NS(foo='a', bar=['b', 'c'])),
+    ]
+
+
+class TestPositionalsNargsNoneOneOrMore(ParserTestCase):
+    """Test a Positional with no nargs followed by one with one or more"""
+
+    argument_signatures = [Sig('foo'), Sig('bar', nargs='+')]
+    failures = ['', '--foo', 'a']
+    successes = [
+        ('a b', NS(foo='a', bar=['b'])),
+        ('a b c', NS(foo='a', bar=['b', 'c'])),
+    ]
+
+
+class TestPositionalsNargsNoneOptional(ParserTestCase):
+    """Test a Positional with no nargs followed by one with an Optional"""
+
+    argument_signatures = [Sig('foo'), Sig('bar', nargs='?')]
+    failures = ['', '--foo', 'a b c']
+    successes = [
+        ('a', NS(foo='a', bar=None)),
+        ('a b', NS(foo='a', bar='b')),
+    ]
+
+
+class TestPositionalsNargsZeroOrMoreNone(ParserTestCase):
+    """Test a Positional with unlimited nargs followed by one with none"""
+
+    argument_signatures = [Sig('foo', nargs='*'), Sig('bar')]
+    failures = ['', '--foo']
+    successes = [
+        ('a', NS(foo=[], bar='a')),
+        ('a b', NS(foo=['a'], bar='b')),
+        ('a b c', NS(foo=['a', 'b'], bar='c')),
+    ]
+
+
+class TestPositionalsNargsOneOrMoreNone(ParserTestCase):
+    """Test a Positional with one or more nargs followed by one with none"""
+
+    argument_signatures = [Sig('foo', nargs='+'), Sig('bar')]
+    failures = ['', '--foo', 'a']
+    successes = [
+        ('a b', NS(foo=['a'], bar='b')),
+        ('a b c', NS(foo=['a', 'b'], bar='c')),
+    ]
+
+
+class TestPositionalsNargsOptionalNone(ParserTestCase):
+    """Test a Positional with an Optional nargs followed by one with none"""
+
+    argument_signatures = [Sig('foo', nargs='?', default=42), Sig('bar')]
+    failures = ['', '--foo', 'a b c']
+    successes = [
+        ('a', NS(foo=42, bar='a')),
+        ('a b', NS(foo='a', bar='b')),
+    ]
+
+
+class TestPositionalsNargs2ZeroOrMore(ParserTestCase):
+    """Test a Positional with 2 nargs followed by one with unlimited"""
+
+    argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='*')]
+    failures = ['', '--foo', 'a']
+    successes = [
+        ('a b', NS(foo=['a', 'b'], bar=[])),
+        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
+    ]
+
+
+class TestPositionalsNargs2OneOrMore(ParserTestCase):
+    """Test a Positional with 2 nargs followed by one with one or more"""
+
+    argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='+')]
+    failures = ['', '--foo', 'a', 'a b']
+    successes = [
+        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
+    ]
+
+
+class TestPositionalsNargs2Optional(ParserTestCase):
+    """Test a Positional with 2 nargs followed by one optional"""
+
+    argument_signatures = [Sig('foo', nargs=2), Sig('bar', nargs='?')]
+    failures = ['', '--foo', 'a', 'a b c d']
+    successes = [
+        ('a b', NS(foo=['a', 'b'], bar=None)),
+        ('a b c', NS(foo=['a', 'b'], bar='c')),
+    ]
+
+
+class TestPositionalsNargsZeroOrMore1(ParserTestCase):
+    """Test a Positional with unlimited nargs followed by one with 1"""
+
+    argument_signatures = [Sig('foo', nargs='*'), Sig('bar', nargs=1)]
+    failures = ['', '--foo', ]
+    successes = [
+        ('a', NS(foo=[], bar=['a'])),
+        ('a b', NS(foo=['a'], bar=['b'])),
+        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
+    ]
+
+
+class TestPositionalsNargsOneOrMore1(ParserTestCase):
+    """Test a Positional with one or more nargs followed by one with 1"""
+
+    argument_signatures = [Sig('foo', nargs='+'), Sig('bar', nargs=1)]
+    failures = ['', '--foo', 'a']
+    successes = [
+        ('a b', NS(foo=['a'], bar=['b'])),
+        ('a b c', NS(foo=['a', 'b'], bar=['c'])),
+    ]
+
+
+class TestPositionalsNargsOptional1(ParserTestCase):
+    """Test a Positional with an Optional nargs followed by one with 1"""
+
+    argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs=1)]
+    failures = ['', '--foo', 'a b c']
+    successes = [
+        ('a', NS(foo=None, bar=['a'])),
+        ('a b', NS(foo='a', bar=['b'])),
+    ]
+
+
+class TestPositionalsNargsNoneZeroOrMore1(ParserTestCase):
+    """Test three Positionals: no nargs, unlimited nargs and 1 nargs"""
+
+    argument_signatures = [
+        Sig('foo'),
+        Sig('bar', nargs='*'),
+        Sig('baz', nargs=1),
+    ]
+    failures = ['', '--foo', 'a']
+    successes = [
+        ('a b', NS(foo='a', bar=[], baz=['b'])),
+        ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
+    ]
+
+
+class TestPositionalsNargsNoneOneOrMore1(ParserTestCase):
+    """Test three Positionals: no nargs, one or more nargs and 1 nargs"""
+
+    argument_signatures = [
+        Sig('foo'),
+        Sig('bar', nargs='+'),
+        Sig('baz', nargs=1),
+    ]
+    failures = ['', '--foo', 'a', 'b']
+    successes = [
+        ('a b c', NS(foo='a', bar=['b'], baz=['c'])),
+        ('a b c d', NS(foo='a', bar=['b', 'c'], baz=['d'])),
+    ]
+
+
+class TestPositionalsNargsNoneOptional1(ParserTestCase):
+    """Test three Positionals: no nargs, optional narg and 1 nargs"""
+
+    argument_signatures = [
+        Sig('foo'),
+        Sig('bar', nargs='?', default=0.625),
+        Sig('baz', nargs=1),
+    ]
+    failures = ['', '--foo', 'a']
+    successes = [
+        ('a b', NS(foo='a', bar=0.625, baz=['b'])),
+        ('a b c', NS(foo='a', bar='b', baz=['c'])),
+    ]
+
+
+class TestPositionalsNargsOptionalOptional(ParserTestCase):
+    """Test two optional nargs"""
+
+    argument_signatures = [
+        Sig('foo', nargs='?'),
+        Sig('bar', nargs='?', default=42),
+    ]
+    failures = ['--foo', 'a b c']
+    successes = [
+        ('', NS(foo=None, bar=42)),
+        ('a', NS(foo='a', bar=42)),
+        ('a b', NS(foo='a', bar='b')),
+    ]
+
+
+class TestPositionalsNargsOptionalZeroOrMore(ParserTestCase):
+    """Test an Optional narg followed by unlimited nargs"""
+
+    argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='*')]
+    failures = ['--foo']
+    successes = [
+        ('', NS(foo=None, bar=[])),
+        ('a', NS(foo='a', bar=[])),
+        ('a b', NS(foo='a', bar=['b'])),
+        ('a b c', NS(foo='a', bar=['b', 'c'])),
+    ]
+
+
+class TestPositionalsNargsOptionalOneOrMore(ParserTestCase):
+    """Test an Optional narg followed by one or more nargs"""
+
+    argument_signatures = [Sig('foo', nargs='?'), Sig('bar', nargs='+')]
+    failures = ['', '--foo']
+    successes = [
+        ('a', NS(foo=None, bar=['a'])),
+        ('a b', NS(foo='a', bar=['b'])),
+        ('a b c', NS(foo='a', bar=['b', 'c'])),
+    ]
+
+
+class TestPositionalsChoicesString(ParserTestCase):
+    """Test a set of single-character choices"""
+
+    argument_signatures = [Sig('spam', choices=set('abcdefg'))]
+    failures = ['', '--foo', 'h', '42', 'ef']
+    successes = [
+        ('a', NS(spam='a')),
+        ('g', NS(spam='g')),
+    ]
+
+
+class TestPositionalsChoicesInt(ParserTestCase):
+    """Test a set of integer choices"""
+
+    argument_signatures = [Sig('spam', type=int, choices=range(20))]
+    failures = ['', '--foo', 'h', '42', 'ef']
+    successes = [
+        ('4', NS(spam=4)),
+        ('15', NS(spam=15)),
+    ]
+
+
+class TestPositionalsActionAppend(ParserTestCase):
+    """Test the 'append' action"""
+
+    argument_signatures = [
+        Sig('spam', action='append'),
+        Sig('spam', action='append', nargs=2),
+    ]
+    failures = ['', '--foo', 'a', 'a b', 'a b c d']
+    successes = [
+        ('a b c', NS(spam=['a', ['b', 'c']])),
+    ]
+
+# ========================================
+# Combined optionals and positionals tests
+# ========================================
+
+class TestOptionalsNumericAndPositionals(ParserTestCase):
+    """Tests negative number args when numeric options are present"""
+
+    argument_signatures = [
+        Sig('x', nargs='?'),
+        Sig('-4', dest='y', action='store_true'),
+    ]
+    failures = ['-2', '-315']
+    successes = [
+        ('', NS(x=None, y=False)),
+        ('a', NS(x='a', y=False)),
+        ('-4', NS(x=None, y=True)),
+        ('-4 a', NS(x='a', y=True)),
+    ]
+
+
+class TestOptionalsAlmostNumericAndPositionals(ParserTestCase):
+    """Tests negative number args when almost numeric options are present"""
+
+    argument_signatures = [
+        Sig('x', nargs='?'),
+        Sig('-k4', dest='y', action='store_true'),
+    ]
+    failures = ['-k3']
+    successes = [
+        ('', NS(x=None, y=False)),
+        ('-2', NS(x='-2', y=False)),
+        ('a', NS(x='a', y=False)),
+        ('-k4', NS(x=None, y=True)),
+        ('-k4 a', NS(x='a', y=True)),
+    ]
+
+
+class TestEmptyAndSpaceContainingArguments(ParserTestCase):
+
+    argument_signatures = [
+        Sig('x', nargs='?'),
+        Sig('-y', '--yyy', dest='y'),
+    ]
+    failures = ['-y']
+    successes = [
+        ([''], NS(x='', y=None)),
+        (['a badger'], NS(x='a badger', y=None)),
+        (['-a badger'], NS(x='-a badger', y=None)),
+        (['-y', ''], NS(x=None, y='')),
+        (['-y', 'a badger'], NS(x=None, y='a badger')),
+        (['-y', '-a badger'], NS(x=None, y='-a badger')),
+        (['--yyy=a badger'], NS(x=None, y='a badger')),
+        (['--yyy=-a badger'], NS(x=None, y='-a badger')),
+    ]
+
+
+class TestPrefixCharacterOnlyArguments(ParserTestCase):
+
+    parser_signature = Sig(prefix_chars='-+')
+    argument_signatures = [
+        Sig('-', dest='x', nargs='?', const='badger'),
+        Sig('+', dest='y', type=int, default=42),
+        Sig('-+-', dest='z', action='store_true'),
+    ]
+    failures = ['-y', '+ -']
+    successes = [
+        ('', NS(x=None, y=42, z=False)),
+        ('-', NS(x='badger', y=42, z=False)),
+        ('- X', NS(x='X', y=42, z=False)),
+        ('+ -3', NS(x=None, y=-3, z=False)),
+        ('-+-', NS(x=None, y=42, z=True)),
+        ('- ===', NS(x='===', y=42, z=False)),
+    ]
+
+
+class TestNargsZeroOrMore(ParserTestCase):
+    """Tests specifying an args for an Optional that accepts zero or more"""
+
+    argument_signatures = [Sig('-x', nargs='*'), Sig('y', nargs='*')]
+    failures = []
+    successes = [
+        ('', NS(x=None, y=[])),
+        ('-x', NS(x=[], y=[])),
+        ('-x a', NS(x=['a'], y=[])),
+        ('-x a -- b', NS(x=['a'], y=['b'])),
+        ('a', NS(x=None, y=['a'])),
+        ('a -x', NS(x=[], y=['a'])),
+        ('a -x b', NS(x=['b'], y=['a'])),
+    ]
+
+
+class TestNargsRemainder(ParserTestCase):
+    """Tests specifying a positional with nargs=REMAINDER"""
+
+    argument_signatures = [Sig('x'), Sig('y', nargs='...'), Sig('-z')]
+    failures = ['', '-z', '-z Z']
+    successes = [
+        ('X', NS(x='X', y=[], z=None)),
+        ('-z Z X', NS(x='X', y=[], z='Z')),
+        ('X A B -z Z', NS(x='X', y=['A', 'B', '-z', 'Z'], z=None)),
+        ('X Y --foo', NS(x='X', y=['Y', '--foo'], z=None)),
+    ]
+
+
+class TestOptionLike(ParserTestCase):
+    """Tests options that may or may not be arguments"""
+
+    argument_signatures = [
+        Sig('-x', type=float),
+        Sig('-3', type=float, dest='y'),
+        Sig('z', nargs='*'),
+    ]
+    failures = ['-x', '-y2.5', '-xa', '-x -a',
+                '-x -3', '-x -3.5', '-3 -3.5',
+                '-x -2.5', '-x -2.5 a', '-3 -.5',
+                'a x -1', '-x -1 a', '-3 -1 a']
+    successes = [
+        ('', NS(x=None, y=None, z=[])),
+        ('-x 2.5', NS(x=2.5, y=None, z=[])),
+        ('-x 2.5 a', NS(x=2.5, y=None, z=['a'])),
+        ('-3.5', NS(x=None, y=0.5, z=[])),
+        ('-3-.5', NS(x=None, y=-0.5, z=[])),
+        ('-3 .5', NS(x=None, y=0.5, z=[])),
+        ('a -3.5', NS(x=None, y=0.5, z=['a'])),
+        ('a', NS(x=None, y=None, z=['a'])),
+        ('a -x 1', NS(x=1.0, y=None, z=['a'])),
+        ('-x 1 a', NS(x=1.0, y=None, z=['a'])),
+        ('-3 1 a', NS(x=None, y=1.0, z=['a'])),
+    ]
+
+
+class TestDefaultSuppress(ParserTestCase):
+    """Test actions with suppressed defaults"""
+
+    argument_signatures = [
+        Sig('foo', nargs='?', default=argparse.SUPPRESS),
+        Sig('bar', nargs='*', default=argparse.SUPPRESS),
+        Sig('--baz', action='store_true', default=argparse.SUPPRESS),
+    ]
+    failures = ['-x']
+    successes = [
+        ('', NS()),
+        ('a', NS(foo='a')),
+        ('a b', NS(foo='a', bar=['b'])),
+        ('--baz', NS(baz=True)),
+        ('a --baz', NS(foo='a', baz=True)),
+        ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
+    ]
+
+
+class TestParserDefaultSuppress(ParserTestCase):
+    """Test actions with a parser-level default of SUPPRESS"""
+
+    parser_signature = Sig(argument_default=argparse.SUPPRESS)
+    argument_signatures = [
+        Sig('foo', nargs='?'),
+        Sig('bar', nargs='*'),
+        Sig('--baz', action='store_true'),
+    ]
+    failures = ['-x']
+    successes = [
+        ('', NS()),
+        ('a', NS(foo='a')),
+        ('a b', NS(foo='a', bar=['b'])),
+        ('--baz', NS(baz=True)),
+        ('a --baz', NS(foo='a', baz=True)),
+        ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
+    ]
+
+
+class TestParserDefault42(ParserTestCase):
+    """Test actions with a parser-level default of 42"""
+
+    parser_signature = Sig(argument_default=42, version='1.0')
+    argument_signatures = [
+        Sig('foo', nargs='?'),
+        Sig('bar', nargs='*'),
+        Sig('--baz', action='store_true'),
+    ]
+    failures = ['-x']
+    successes = [
+        ('', NS(foo=42, bar=42, baz=42)),
+        ('a', NS(foo='a', bar=42, baz=42)),
+        ('a b', NS(foo='a', bar=['b'], baz=42)),
+        ('--baz', NS(foo=42, bar=42, baz=True)),
+        ('a --baz', NS(foo='a', bar=42, baz=True)),
+        ('--baz a b', NS(foo='a', bar=['b'], baz=True)),
+    ]
+
+
+class TestArgumentsFromFile(TempDirMixin, ParserTestCase):
+    """Test reading arguments from a file"""
+
+    def setUp(self):
+        super(TestArgumentsFromFile, self).setUp()
+        file_texts = [
+            ('hello', 'hello world!\n'),
+            ('recursive', '-a\n'
+                          'A\n'
+                          '@hello'),
+            ('invalid', '@no-such-path\n'),
+        ]
+        for path, text in file_texts:
+            file = open(path, 'w')
+            file.write(text)
+            file.close()
+
+    parser_signature = Sig(fromfile_prefix_chars='@')
+    argument_signatures = [
+        Sig('-a'),
+        Sig('x'),
+        Sig('y', nargs='+'),
+    ]
+    failures = ['', '-b', 'X', '@invalid', '@missing']
+    successes = [
+        ('X Y', NS(a=None, x='X', y=['Y'])),
+        ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])),
+        ('@hello X', NS(a=None, x='hello world!', y=['X'])),
+        ('X @hello', NS(a=None, x='X', y=['hello world!'])),
+        ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])),
+        ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])),
+    ]
+
+
+class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase):
+    """Test reading arguments from a file"""
+
+    def setUp(self):
+        super(TestArgumentsFromFileConverter, self).setUp()
+        file_texts = [
+            ('hello', 'hello world!\n'),
+        ]
+        for path, text in file_texts:
+            file = open(path, 'w')
+            file.write(text)
+            file.close()
+
+    class FromFileConverterArgumentParser(ErrorRaisingArgumentParser):
+
+        def convert_arg_line_to_args(self, arg_line):
+            for arg in arg_line.split():
+                if not arg.strip():
+                    continue
+                yield arg
+    parser_class = FromFileConverterArgumentParser
+    parser_signature = Sig(fromfile_prefix_chars='@')
+    argument_signatures = [
+        Sig('y', nargs='+'),
+    ]
+    failures = []
+    successes = [
+        ('@hello X', NS(y=['hello', 'world!', 'X'])),
+    ]
+
+
+# =====================
+# Type conversion tests
+# =====================
+
+class TestFileTypeRepr(TestCase):
+
+    def test_r(self):
+        type = argparse.FileType('r')
+        self.assertEqual("FileType('r')", repr(type))
+
+    def test_wb_1(self):
+        type = argparse.FileType('wb', 1)
+        self.assertEqual("FileType('wb', 1)", repr(type))
+
+
+class RFile(object):
+    seen = {}
+
+    def __init__(self, name):
+        self.name = name
+
+    def __eq__(self, other):
+        if other in self.seen:
+            text = self.seen[other]
+        else:
+            text = self.seen[other] = other.read()
+            other.close()
+        if not isinstance(text, str):
+            text = text.decode('ascii')
+        return self.name == other.name == text
+
+
+class TestFileTypeR(TempDirMixin, ParserTestCase):
+    """Test the FileType option/argument type for reading files"""
+
+    def setUp(self):
+        super(TestFileTypeR, self).setUp()
+        for file_name in ['foo', 'bar']:
+            file = open(os.path.join(self.temp_dir, file_name), 'w')
+            file.write(file_name)
+            file.close()
+
+    argument_signatures = [
+        Sig('-x', type=argparse.FileType()),
+        Sig('spam', type=argparse.FileType('r')),
+    ]
+    failures = ['-x', '-x bar']
+    successes = [
+        ('foo', NS(x=None, spam=RFile('foo'))),
+        ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
+        ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
+        ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
+    ]
+
+
+class TestFileTypeRB(TempDirMixin, ParserTestCase):
+    """Test the FileType option/argument type for reading files"""
+
+    def setUp(self):
+        super(TestFileTypeRB, self).setUp()
+        for file_name in ['foo', 'bar']:
+            file = open(os.path.join(self.temp_dir, file_name), 'w')
+            file.write(file_name)
+            file.close()
+
+    argument_signatures = [
+        Sig('-x', type=argparse.FileType('rb')),
+        Sig('spam', type=argparse.FileType('rb')),
+    ]
+    failures = ['-x', '-x bar']
+    successes = [
+        ('foo', NS(x=None, spam=RFile('foo'))),
+        ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
+        ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
+        ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
+    ]
+
+
+class WFile(object):
+    seen = set()
+
+    def __init__(self, name):
+        self.name = name
+
+    def __eq__(self, other):
+        if other not in self.seen:
+            text = 'Check that file is writable.'
+            if 'b' in other.mode:
+                text = text.encode('ascii')
+            other.write(text)
+            other.close()
+            self.seen.add(other)
+        return self.name == other.name
+
+
+class TestFileTypeW(TempDirMixin, ParserTestCase):
+    """Test the FileType option/argument type for writing files"""
+
+    argument_signatures = [
+        Sig('-x', type=argparse.FileType('w')),
+        Sig('spam', type=argparse.FileType('w')),
+    ]
+    failures = ['-x', '-x bar']
+    successes = [
+        ('foo', NS(x=None, spam=WFile('foo'))),
+        ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
+        ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
+        ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
+    ]
+
+
+class TestFileTypeWB(TempDirMixin, ParserTestCase):
+
+    argument_signatures = [
+        Sig('-x', type=argparse.FileType('wb')),
+        Sig('spam', type=argparse.FileType('wb')),
+    ]
+    failures = ['-x', '-x bar']
+    successes = [
+        ('foo', NS(x=None, spam=WFile('foo'))),
+        ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
+        ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))),
+        ('-x - -', NS(x=sys.stdout, spam=sys.stdout)),
+    ]
+
+
+class TestTypeCallable(ParserTestCase):
+    """Test some callables as option/argument types"""
+
+    argument_signatures = [
+        Sig('--eggs', type=complex),
+        Sig('spam', type=float),
+    ]
+    failures = ['a', '42j', '--eggs a', '--eggs 2i']
+    successes = [
+        ('--eggs=42 42', NS(eggs=42, spam=42.0)),
+        ('--eggs 2j -- -1.5', NS(eggs=2j, spam=-1.5)),
+        ('1024.675', NS(eggs=None, spam=1024.675)),
+    ]
+
+
+class TestTypeUserDefined(ParserTestCase):
+    """Test a user-defined option/argument type"""
+
+    class MyType(TestCase):
+
+        def __init__(self, value):
+            self.value = value
+
+        def __eq__(self, other):
+            return (type(self), self.value) == (type(other), other.value)
+
+    argument_signatures = [
+        Sig('-x', type=MyType),
+        Sig('spam', type=MyType),
+    ]
+    failures = []
+    successes = [
+        ('a -x b', NS(x=MyType('b'), spam=MyType('a'))),
+        ('-xf g', NS(x=MyType('f'), spam=MyType('g'))),
+    ]
+
+
+class TestTypeClassicClass(ParserTestCase):
+    """Test a classic class type"""
+
+    class C:
+
+        def __init__(self, value):
+            self.value = value
+
+        def __eq__(self, other):
+            return (type(self), self.value) == (type(other), other.value)
+
+    argument_signatures = [
+        Sig('-x', type=C),
+        Sig('spam', type=C),
+    ]
+    failures = []
+    successes = [
+        ('a -x b', NS(x=C('b'), spam=C('a'))),
+        ('-xf g', NS(x=C('f'), spam=C('g'))),
+    ]
+
+
+class TestTypeRegistration(TestCase):
+    """Test a user-defined type by registering it"""
+
+    def test(self):
+
+        def get_my_type(string):
+            return 'my_type{%s}' % string
+
+        parser = argparse.ArgumentParser()
+        parser.register('type', 'my_type', get_my_type)
+        parser.add_argument('-x', type='my_type')
+        parser.add_argument('y', type='my_type')
+
+        self.assertEqual(parser.parse_args('1'.split()),
+                         NS(x=None, y='my_type{1}'))
+        self.assertEqual(parser.parse_args('-x 1 42'.split()),
+                         NS(x='my_type{1}', y='my_type{42}'))
+
+
+# ============
+# Action tests
+# ============
+
+class TestActionUserDefined(ParserTestCase):
+    """Test a user-defined option/argument action"""
+
+    class OptionalAction(argparse.Action):
+
+        def __call__(self, parser, namespace, value, option_string=None):
+            try:
+                # check destination and option string
+                assert self.dest == 'spam', 'dest: %s' % self.dest
+                assert option_string == '-s', 'flag: %s' % option_string
+                # when option is before argument, badger=2, and when
+                # option is after argument, badger=<whatever was set>
+                expected_ns = NS(spam=0.25)
+                if value in [0.125, 0.625]:
+                    expected_ns.badger = 2
+                elif value in [2.0]:
+                    expected_ns.badger = 84
+                else:
+                    raise AssertionError('value: %s' % value)
+                assert expected_ns == namespace, ('expected %s, got %s' %
+                                                  (expected_ns, namespace))
+            except AssertionError:
+                e = sys.exc_info()[1]
+                raise ArgumentParserError('opt_action failed: %s' % e)
+            setattr(namespace, 'spam', value)
+
+    class PositionalAction(argparse.Action):
+
+        def __call__(self, parser, namespace, value, option_string=None):
+            try:
+                assert option_string is None, ('option_string: %s' %
+                                               option_string)
+                # check destination
+                assert self.dest == 'badger', 'dest: %s' % self.dest
+                # when argument is before option, spam=0.25, and when
+                # option is after argument, spam=<whatever was set>
+                expected_ns = NS(badger=2)
+                if value in [42, 84]:
+                    expected_ns.spam = 0.25
+                elif value in [1]:
+                    expected_ns.spam = 0.625
+                elif value in [2]:
+                    expected_ns.spam = 0.125
+                else:
+                    raise AssertionError('value: %s' % value)
+                assert expected_ns == namespace, ('expected %s, got %s' %
+                                                  (expected_ns, namespace))
+            except AssertionError:
+                e = sys.exc_info()[1]
+                raise ArgumentParserError('arg_action failed: %s' % e)
+            setattr(namespace, 'badger', value)
+
+    argument_signatures = [
+        Sig('-s', dest='spam', action=OptionalAction,
+            type=float, default=0.25),
+        Sig('badger', action=PositionalAction,
+            type=int, nargs='?', default=2),
+    ]
+    failures = []
+    successes = [
+        ('-s0.125', NS(spam=0.125, badger=2)),
+        ('42', NS(spam=0.25, badger=42)),
+        ('-s 0.625 1', NS(spam=0.625, badger=1)),
+        ('84 -s2', NS(spam=2.0, badger=84)),
+    ]
+
+
+class TestActionRegistration(TestCase):
+    """Test a user-defined action supplied by registering it"""
+
+    class MyAction(argparse.Action):
+
+        def __call__(self, parser, namespace, values, option_string=None):
+            setattr(namespace, self.dest, 'foo[%s]' % values)
+
+    def test(self):
+
+        parser = argparse.ArgumentParser()
+        parser.register('action', 'my_action', self.MyAction)
+        parser.add_argument('badger', action='my_action')
+
+        self.assertEqual(parser.parse_args(['1']), NS(badger='foo[1]'))
+        self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]'))
+
+
+# ================
+# Subparsers tests
+# ================
+
+class TestAddSubparsers(TestCase):
+    """Test the add_subparsers method"""
+
+    def assertArgumentParserError(self, *args, **kwargs):
+        self.assertRaises(ArgumentParserError, *args, **kwargs)
+
+    def _get_parser(self, subparser_help=False):
+        # create a parser with a subparsers argument
+        parser = ErrorRaisingArgumentParser(
+            prog='PROG', description='main description')
+        parser.add_argument(
+            '--foo', action='store_true', help='foo help')
+        parser.add_argument(
+            'bar', type=float, help='bar help')
+
+        # check that only one subparsers argument can be added
+        subparsers = parser.add_subparsers(help='command help')
+        self.assertArgumentParserError(parser.add_subparsers)
+
+        # add first sub-parser
+        parser1_kwargs = dict(description='1 description')
+        if subparser_help:
+            parser1_kwargs['help'] = '1 help'
+        parser1 = subparsers.add_parser('1', **parser1_kwargs)
+        parser1.add_argument('-w', type=int, help='w help')
+        parser1.add_argument('x', choices='abc', help='x help')
+
+        # add second sub-parser
+        parser2_kwargs = dict(description='2 description')
+        if subparser_help:
+            parser2_kwargs['help'] = '2 help'
+        parser2 = subparsers.add_parser('2', **parser2_kwargs)
+        parser2.add_argument('-y', choices='123', help='y help')
+        parser2.add_argument('z', type=complex, nargs='*', help='z help')
+
+        # return the main parser
+        return parser
+
+    def setUp(self):
+        self.parser = self._get_parser()
+        self.command_help_parser = self._get_parser(subparser_help=True)
+
+    def test_parse_args_failures(self):
+        # check some failure cases:
+        for args_str in ['', 'a', 'a a', '0.5 a', '0.5 1',
+                         '0.5 1 -y', '0.5 2 -w']:
+            args = args_str.split()
+            self.assertArgumentParserError(self.parser.parse_args, args)
+
+    def test_parse_args(self):
+        # check some non-failure cases:
+        self.assertEqual(
+            self.parser.parse_args('0.5 1 b -w 7'.split()),
+            NS(foo=False, bar=0.5, w=7, x='b'),
+        )
+        self.assertEqual(
+            self.parser.parse_args('0.25 --foo 2 -y 2 3j -- -1j'.split()),
+            NS(foo=True, bar=0.25, y='2', z=[3j, -1j]),
+        )
+        self.assertEqual(
+            self.parser.parse_args('--foo 0.125 1 c'.split()),
+            NS(foo=True, bar=0.125, w=None, x='c'),
+        )
+
+    def test_dest(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.add_argument('--foo', action='store_true')
+        subparsers = parser.add_subparsers(dest='bar')
+        parser1 = subparsers.add_parser('1')
+        parser1.add_argument('baz')
+        self.assertEqual(NS(foo=False, bar='1', baz='2'),
+                         parser.parse_args('1 2'.split()))
+
+    def test_help(self):
+        self.assertEqual(self.parser.format_usage(),
+                         'usage: PROG [-h] [--foo] bar {1,2} ...\n')
+        self.assertEqual(self.parser.format_help(), textwrap.dedent('''\
+            usage: PROG [-h] [--foo] bar {1,2} ...
+
+            main description
+
+            positional arguments:
+              bar         bar help
+              {1,2}       command help
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              --foo       foo help
+            '''))
+
+    def test_parser_command_help(self):
+        self.assertEqual(self.command_help_parser.format_usage(),
+                         'usage: PROG [-h] [--foo] bar {1,2} ...\n')
+        self.assertEqual(self.command_help_parser.format_help(),
+                         textwrap.dedent('''\
+            usage: PROG [-h] [--foo] bar {1,2} ...
+
+            main description
+
+            positional arguments:
+              bar         bar help
+              {1,2}       command help
+                1         1 help
+                2         2 help
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              --foo       foo help
+            '''))
+
+    def test_subparser_title_help(self):
+        parser = ErrorRaisingArgumentParser(prog='PROG',
+                                            description='main description')
+        parser.add_argument('--foo', action='store_true', help='foo help')
+        parser.add_argument('bar', help='bar help')
+        subparsers = parser.add_subparsers(title='subcommands',
+                                           description='command help',
+                                           help='additional text')
+        parser1 = subparsers.add_parser('1')
+        parser2 = subparsers.add_parser('2')
+        self.assertEqual(parser.format_usage(),
+                         'usage: PROG [-h] [--foo] bar {1,2} ...\n')
+        self.assertEqual(parser.format_help(), textwrap.dedent('''\
+            usage: PROG [-h] [--foo] bar {1,2} ...
+
+            main description
+
+            positional arguments:
+              bar         bar help
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              --foo       foo help
+
+            subcommands:
+              command help
+
+              {1,2}       additional text
+            '''))
+
+    def _test_subparser_help(self, args_str, expected_help):
+        try:
+            self.parser.parse_args(args_str.split())
+        except ArgumentParserError:
+            err = sys.exc_info()[1]
+            if err.stdout != expected_help:
+                print(repr(expected_help))
+                print(repr(err.stdout))
+            self.assertEqual(err.stdout, expected_help)
+
+    def test_subparser1_help(self):
+        self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\
+            usage: PROG bar 1 [-h] [-w W] {a,b,c}
+
+            1 description
+
+            positional arguments:
+              {a,b,c}     x help
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              -w W        w help
+            '''))
+
+    def test_subparser2_help(self):
+        self._test_subparser_help('5.0 2 -h', textwrap.dedent('''\
+            usage: PROG bar 2 [-h] [-y {1,2,3}] [z [z ...]]
+
+            2 description
+
+            positional arguments:
+              z           z help
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              -y {1,2,3}  y help
+            '''))
+
+# ============
+# Groups tests
+# ============
+
+class TestPositionalsGroups(TestCase):
+    """Tests that order of group positionals matches construction order"""
+
+    def test_nongroup_first(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.add_argument('foo')
+        group = parser.add_argument_group('g')
+        group.add_argument('bar')
+        parser.add_argument('baz')
+        expected = NS(foo='1', bar='2', baz='3')
+        result = parser.parse_args('1 2 3'.split())
+        self.failUnlessEqual(expected, result)
+
+    def test_group_first(self):
+        parser = ErrorRaisingArgumentParser()
+        group = parser.add_argument_group('xxx')
+        group.add_argument('foo')
+        parser.add_argument('bar')
+        parser.add_argument('baz')
+        expected = NS(foo='1', bar='2', baz='3')
+        result = parser.parse_args('1 2 3'.split())
+        self.failUnlessEqual(expected, result)
+
+    def test_interleaved_groups(self):
+        parser = ErrorRaisingArgumentParser()
+        group = parser.add_argument_group('xxx')
+        parser.add_argument('foo')
+        group.add_argument('bar')
+        parser.add_argument('baz')
+        group = parser.add_argument_group('yyy')
+        group.add_argument('frell')
+        expected = NS(foo='1', bar='2', baz='3', frell='4')
+        result = parser.parse_args('1 2 3 4'.split())
+        self.failUnlessEqual(expected, result)
+
+# ===================
+# Parent parser tests
+# ===================
+
+class TestParentParsers(TestCase):
+    """Tests that parsers can be created with parent parsers"""
+
+    def assertArgumentParserError(self, *args, **kwargs):
+        self.assertRaises(ArgumentParserError, *args, **kwargs)
+
+    def setUp(self):
+        self.wxyz_parent = ErrorRaisingArgumentParser(add_help=False)
+        self.wxyz_parent.add_argument('--w')
+        x_group = self.wxyz_parent.add_argument_group('x')
+        x_group.add_argument('-y')
+        self.wxyz_parent.add_argument('z')
+
+        self.abcd_parent = ErrorRaisingArgumentParser(add_help=False)
+        self.abcd_parent.add_argument('a')
+        self.abcd_parent.add_argument('-b')
+        c_group = self.abcd_parent.add_argument_group('c')
+        c_group.add_argument('--d')
+
+        self.w_parent = ErrorRaisingArgumentParser(add_help=False)
+        self.w_parent.add_argument('--w')
+
+        self.z_parent = ErrorRaisingArgumentParser(add_help=False)
+        self.z_parent.add_argument('z')
+
+        # parents with mutually exclusive groups
+        self.ab_mutex_parent = ErrorRaisingArgumentParser(add_help=False)
+        group = self.ab_mutex_parent.add_mutually_exclusive_group()
+        group.add_argument('-a', action='store_true')
+        group.add_argument('-b', action='store_true')
+
+    def test_single_parent(self):
+        parser = ErrorRaisingArgumentParser(parents=[self.wxyz_parent])
+        self.assertEqual(parser.parse_args('-y 1 2 --w 3'.split()),
+                         NS(w='3', y='1', z='2'))
+
+    def test_single_parent_mutex(self):
+        self._test_mutex_ab(self.ab_mutex_parent.parse_args)
+        parser = ErrorRaisingArgumentParser(parents=[self.ab_mutex_parent])
+        self._test_mutex_ab(parser.parse_args)
+
+    def test_single_granparent_mutex(self):
+        parents = [self.ab_mutex_parent]
+        parser = ErrorRaisingArgumentParser(add_help=False, parents=parents)
+        parser = ErrorRaisingArgumentParser(parents=[parser])
+        self._test_mutex_ab(parser.parse_args)
+
+    def _test_mutex_ab(self, parse_args):
+        self.assertEqual(parse_args([]), NS(a=False, b=False))
+        self.assertEqual(parse_args(['-a']), NS(a=True, b=False))
+        self.assertEqual(parse_args(['-b']), NS(a=False, b=True))
+        self.assertArgumentParserError(parse_args, ['-a', '-b'])
+        self.assertArgumentParserError(parse_args, ['-b', '-a'])
+        self.assertArgumentParserError(parse_args, ['-c'])
+        self.assertArgumentParserError(parse_args, ['-a', '-c'])
+        self.assertArgumentParserError(parse_args, ['-b', '-c'])
+
+    def test_multiple_parents(self):
+        parents = [self.abcd_parent, self.wxyz_parent]
+        parser = ErrorRaisingArgumentParser(parents=parents)
+        self.assertEqual(parser.parse_args('--d 1 --w 2 3 4'.split()),
+                         NS(a='3', b=None, d='1', w='2', y=None, z='4'))
+
+    def test_multiple_parents_mutex(self):
+        parents = [self.ab_mutex_parent, self.wxyz_parent]
+        parser = ErrorRaisingArgumentParser(parents=parents)
+        self.assertEqual(parser.parse_args('-a --w 2 3'.split()),
+                         NS(a=True, b=False, w='2', y=None, z='3'))
+        self.assertArgumentParserError(
+            parser.parse_args, '-a --w 2 3 -b'.split())
+        self.assertArgumentParserError(
+            parser.parse_args, '-a -b --w 2 3'.split())
+
+    def test_conflicting_parents(self):
+        self.assertRaises(
+            argparse.ArgumentError,
+            argparse.ArgumentParser,
+            parents=[self.w_parent, self.wxyz_parent])
+
+    def test_conflicting_parents_mutex(self):
+        self.assertRaises(
+            argparse.ArgumentError,
+            argparse.ArgumentParser,
+            parents=[self.abcd_parent, self.ab_mutex_parent])
+
+    def test_same_argument_name_parents(self):
+        parents = [self.wxyz_parent, self.z_parent]
+        parser = ErrorRaisingArgumentParser(parents=parents)
+        self.assertEqual(parser.parse_args('1 2'.split()),
+                         NS(w=None, y=None, z='2'))
+
+    def test_subparser_parents(self):
+        parser = ErrorRaisingArgumentParser()
+        subparsers = parser.add_subparsers()
+        abcde_parser = subparsers.add_parser('bar', parents=[self.abcd_parent])
+        abcde_parser.add_argument('e')
+        self.assertEqual(parser.parse_args('bar -b 1 --d 2 3 4'.split()),
+                         NS(a='3', b='1', d='2', e='4'))
+
+    def test_subparser_parents_mutex(self):
+        parser = ErrorRaisingArgumentParser()
+        subparsers = parser.add_subparsers()
+        parents = [self.ab_mutex_parent]
+        abc_parser = subparsers.add_parser('foo', parents=parents)
+        c_group = abc_parser.add_argument_group('c_group')
+        c_group.add_argument('c')
+        parents = [self.wxyz_parent, self.ab_mutex_parent]
+        wxyzabe_parser = subparsers.add_parser('bar', parents=parents)
+        wxyzabe_parser.add_argument('e')
+        self.assertEqual(parser.parse_args('foo -a 4'.split()),
+                         NS(a=True, b=False, c='4'))
+        self.assertEqual(parser.parse_args('bar -b  --w 2 3 4'.split()),
+                         NS(a=False, b=True, w='2', y=None, z='3', e='4'))
+        self.assertArgumentParserError(
+            parser.parse_args, 'foo -a -b 4'.split())
+        self.assertArgumentParserError(
+            parser.parse_args, 'bar -b -a 4'.split())
+
+    def test_parent_help(self):
+        parents = [self.abcd_parent, self.wxyz_parent]
+        parser = ErrorRaisingArgumentParser(parents=parents)
+        parser_help = parser.format_help()
+        self.assertEqual(parser_help, textwrap.dedent('''\
+            usage: test_argparse.py [-h] [-b B] [--d D] [--w W] [-y Y] a z
+
+            positional arguments:
+              a
+              z
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              -b B
+              --w W
+
+            c:
+              --d D
+
+            x:
+              -y Y
+        '''))
+
+    def test_groups_parents(self):
+        parent = ErrorRaisingArgumentParser(add_help=False)
+        g = parent.add_argument_group(title='g', description='gd')
+        g.add_argument('-w')
+        g.add_argument('-x')
+        m = parent.add_mutually_exclusive_group()
+        m.add_argument('-y')
+        m.add_argument('-z')
+        parser = ErrorRaisingArgumentParser(parents=[parent])
+
+        self.assertRaises(ArgumentParserError, parser.parse_args,
+            ['-y', 'Y', '-z', 'Z'])
+
+        parser_help = parser.format_help()
+        self.assertEqual(parser_help, textwrap.dedent('''\
+            usage: test_argparse.py [-h] [-w W] [-x X] [-y Y | -z Z]
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              -y Y
+              -z Z
+
+            g:
+              gd
+
+              -w W
+              -x X
+        '''))
+
+# ==============================
+# Mutually exclusive group tests
+# ==============================
+
+class TestMutuallyExclusiveGroupErrors(TestCase):
+
+    def test_invalid_add_argument_group(self):
+        parser = ErrorRaisingArgumentParser()
+        raises = self.assertRaises
+        raises(TypeError, parser.add_mutually_exclusive_group, title='foo')
+
+    def test_invalid_add_argument(self):
+        parser = ErrorRaisingArgumentParser()
+        group = parser.add_mutually_exclusive_group()
+        add_argument = group.add_argument
+        raises = self.assertRaises
+        raises(ValueError, add_argument, '--foo', required=True)
+        raises(ValueError, add_argument, 'bar')
+        raises(ValueError, add_argument, 'bar', nargs='+')
+        raises(ValueError, add_argument, 'bar', nargs=1)
+        raises(ValueError, add_argument, 'bar', nargs=argparse.PARSER)
+
+
+class MEMixin(object):
+
+    def test_failures_when_not_required(self):
+        parse_args = self.get_parser(required=False).parse_args
+        error = ArgumentParserError
+        for args_string in self.failures:
+            self.assertRaises(error, parse_args, args_string.split())
+
+    def test_failures_when_required(self):
+        parse_args = self.get_parser(required=True).parse_args
+        error = ArgumentParserError
+        for args_string in self.failures + ['']:
+            self.assertRaises(error, parse_args, args_string.split())
+
+    def test_successes_when_not_required(self):
+        parse_args = self.get_parser(required=False).parse_args
+        successes = self.successes + self.successes_when_not_required
+        for args_string, expected_ns in successes:
+            actual_ns = parse_args(args_string.split())
+            self.assertEqual(actual_ns, expected_ns)
+
+    def test_successes_when_required(self):
+        parse_args = self.get_parser(required=True).parse_args
+        for args_string, expected_ns in self.successes:
+            actual_ns = parse_args(args_string.split())
+            self.assertEqual(actual_ns, expected_ns)
+
+    def test_usage_when_not_required(self):
+        format_usage = self.get_parser(required=False).format_usage
+        expected_usage = self.usage_when_not_required
+        self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
+
+    def test_usage_when_required(self):
+        format_usage = self.get_parser(required=True).format_usage
+        expected_usage = self.usage_when_required
+        self.assertEqual(format_usage(), textwrap.dedent(expected_usage))
+
+    def test_help_when_not_required(self):
+        format_help = self.get_parser(required=False).format_help
+        help = self.usage_when_not_required + self.help
+        self.assertEqual(format_help(), textwrap.dedent(help))
+
+    def test_help_when_required(self):
+        format_help = self.get_parser(required=True).format_help
+        help = self.usage_when_required + self.help
+        self.assertEqual(format_help(), textwrap.dedent(help))
+
+
+class TestMutuallyExclusiveSimple(MEMixin, TestCase):
+
+    def get_parser(self, required=None):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('--bar', help='bar help')
+        group.add_argument('--baz', nargs='?', const='Z', help='baz help')
+        return parser
+
+    failures = ['--bar X --baz Y', '--bar X --baz']
+    successes = [
+        ('--bar X', NS(bar='X', baz=None)),
+        ('--bar X --bar Z', NS(bar='Z', baz=None)),
+        ('--baz Y', NS(bar=None, baz='Y')),
+        ('--baz', NS(bar=None, baz='Z')),
+    ]
+    successes_when_not_required = [
+        ('', NS(bar=None, baz=None)),
+    ]
+
+    usage_when_not_required = '''\
+        usage: PROG [-h] [--bar BAR | --baz [BAZ]]
+        '''
+    usage_when_required = '''\
+        usage: PROG [-h] (--bar BAR | --baz [BAZ])
+        '''
+    help = '''\
+
+        optional arguments:
+          -h, --help   show this help message and exit
+          --bar BAR    bar help
+          --baz [BAZ]  baz help
+        '''
+
+
+class TestMutuallyExclusiveLong(MEMixin, TestCase):
+
+    def get_parser(self, required=None):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        parser.add_argument('--abcde', help='abcde help')
+        parser.add_argument('--fghij', help='fghij help')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('--klmno', help='klmno help')
+        group.add_argument('--pqrst', help='pqrst help')
+        return parser
+
+    failures = ['--klmno X --pqrst Y']
+    successes = [
+        ('--klmno X', NS(abcde=None, fghij=None, klmno='X', pqrst=None)),
+        ('--abcde Y --klmno X',
+            NS(abcde='Y', fghij=None, klmno='X', pqrst=None)),
+        ('--pqrst X', NS(abcde=None, fghij=None, klmno=None, pqrst='X')),
+        ('--pqrst X --fghij Y',
+            NS(abcde=None, fghij='Y', klmno=None, pqrst='X')),
+    ]
+    successes_when_not_required = [
+        ('', NS(abcde=None, fghij=None, klmno=None, pqrst=None)),
+    ]
+
+    usage_when_not_required = '''\
+    usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
+                [--klmno KLMNO | --pqrst PQRST]
+    '''
+    usage_when_required = '''\
+    usage: PROG [-h] [--abcde ABCDE] [--fghij FGHIJ]
+                (--klmno KLMNO | --pqrst PQRST)
+    '''
+    help = '''\
+
+    optional arguments:
+      -h, --help     show this help message and exit
+      --abcde ABCDE  abcde help
+      --fghij FGHIJ  fghij help
+      --klmno KLMNO  klmno help
+      --pqrst PQRST  pqrst help
+    '''
+
+
+class TestMutuallyExclusiveFirstSuppressed(MEMixin, TestCase):
+
+    def get_parser(self, required):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('-x', help=argparse.SUPPRESS)
+        group.add_argument('-y', action='store_false', help='y help')
+        return parser
+
+    failures = ['-x X -y']
+    successes = [
+        ('-x X', NS(x='X', y=True)),
+        ('-x X -x Y', NS(x='Y', y=True)),
+        ('-y', NS(x=None, y=False)),
+    ]
+    successes_when_not_required = [
+        ('', NS(x=None, y=True)),
+    ]
+
+    usage_when_not_required = '''\
+        usage: PROG [-h] [-y]
+        '''
+    usage_when_required = '''\
+        usage: PROG [-h] -y
+        '''
+    help = '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -y          y help
+        '''
+
+
+class TestMutuallyExclusiveManySuppressed(MEMixin, TestCase):
+
+    def get_parser(self, required):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        group = parser.add_mutually_exclusive_group(required=required)
+        add = group.add_argument
+        add('--spam', action='store_true', help=argparse.SUPPRESS)
+        add('--badger', action='store_false', help=argparse.SUPPRESS)
+        add('--bladder', help=argparse.SUPPRESS)
+        return parser
+
+    failures = [
+        '--spam --badger',
+        '--badger --bladder B',
+        '--bladder B --spam',
+    ]
+    successes = [
+        ('--spam', NS(spam=True, badger=True, bladder=None)),
+        ('--badger', NS(spam=False, badger=False, bladder=None)),
+        ('--bladder B', NS(spam=False, badger=True, bladder='B')),
+        ('--spam --spam', NS(spam=True, badger=True, bladder=None)),
+    ]
+    successes_when_not_required = [
+        ('', NS(spam=False, badger=True, bladder=None)),
+    ]
+
+    usage_when_required = usage_when_not_required = '''\
+        usage: PROG [-h]
+        '''
+    help = '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+        '''
+
+
+class TestMutuallyExclusiveOptionalAndPositional(MEMixin, TestCase):
+
+    def get_parser(self, required):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('--foo', action='store_true', help='FOO')
+        group.add_argument('--spam', help='SPAM')
+        group.add_argument('badger', nargs='*', default='X', help='BADGER')
+        return parser
+
+    failures = [
+        '--foo --spam S',
+        '--spam S X',
+        'X --foo',
+        'X Y Z --spam S',
+        '--foo X Y',
+    ]
+    successes = [
+        ('--foo', NS(foo=True, spam=None, badger='X')),
+        ('--spam S', NS(foo=False, spam='S', badger='X')),
+        ('X', NS(foo=False, spam=None, badger=['X'])),
+        ('X Y Z', NS(foo=False, spam=None, badger=['X', 'Y', 'Z'])),
+    ]
+    successes_when_not_required = [
+        ('', NS(foo=False, spam=None, badger='X')),
+    ]
+
+    usage_when_not_required = '''\
+        usage: PROG [-h] [--foo | --spam SPAM | badger [badger ...]]
+        '''
+    usage_when_required = '''\
+        usage: PROG [-h] (--foo | --spam SPAM | badger [badger ...])
+        '''
+    help = '''\
+
+        positional arguments:
+          badger       BADGER
+
+        optional arguments:
+          -h, --help   show this help message and exit
+          --foo        FOO
+          --spam SPAM  SPAM
+        '''
+
+
+class TestMutuallyExclusiveOptionalsMixed(MEMixin, TestCase):
+
+    def get_parser(self, required):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        parser.add_argument('-x', action='store_true', help='x help')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('-a', action='store_true', help='a help')
+        group.add_argument('-b', action='store_true', help='b help')
+        parser.add_argument('-y', action='store_true', help='y help')
+        group.add_argument('-c', action='store_true', help='c help')
+        return parser
+
+    failures = ['-a -b', '-b -c', '-a -c', '-a -b -c']
+    successes = [
+        ('-a', NS(a=True, b=False, c=False, x=False, y=False)),
+        ('-b', NS(a=False, b=True, c=False, x=False, y=False)),
+        ('-c', NS(a=False, b=False, c=True, x=False, y=False)),
+        ('-a -x', NS(a=True, b=False, c=False, x=True, y=False)),
+        ('-y -b', NS(a=False, b=True, c=False, x=False, y=True)),
+        ('-x -y -c', NS(a=False, b=False, c=True, x=True, y=True)),
+    ]
+    successes_when_not_required = [
+        ('', NS(a=False, b=False, c=False, x=False, y=False)),
+        ('-x', NS(a=False, b=False, c=False, x=True, y=False)),
+        ('-y', NS(a=False, b=False, c=False, x=False, y=True)),
+    ]
+
+    usage_when_required = usage_when_not_required = '''\
+        usage: PROG [-h] [-x] [-a] [-b] [-y] [-c]
+        '''
+    help = '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -x          x help
+          -a          a help
+          -b          b help
+          -y          y help
+          -c          c help
+        '''
+
+
+class TestMutuallyExclusiveOptionalsAndPositionalsMixed(MEMixin, TestCase):
+
+    def get_parser(self, required):
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        parser.add_argument('x', help='x help')
+        parser.add_argument('-y', action='store_true', help='y help')
+        group = parser.add_mutually_exclusive_group(required=required)
+        group.add_argument('a', nargs='?', help='a help')
+        group.add_argument('-b', action='store_true', help='b help')
+        group.add_argument('-c', action='store_true', help='c help')
+        return parser
+
+    failures = ['X A -b', '-b -c', '-c X A']
+    successes = [
+        ('X A', NS(a='A', b=False, c=False, x='X', y=False)),
+        ('X -b', NS(a=None, b=True, c=False, x='X', y=False)),
+        ('X -c', NS(a=None, b=False, c=True, x='X', y=False)),
+        ('X A -y', NS(a='A', b=False, c=False, x='X', y=True)),
+        ('X -y -b', NS(a=None, b=True, c=False, x='X', y=True)),
+    ]
+    successes_when_not_required = [
+        ('X', NS(a=None, b=False, c=False, x='X', y=False)),
+        ('X -y', NS(a=None, b=False, c=False, x='X', y=True)),
+    ]
+
+    usage_when_required = usage_when_not_required = '''\
+        usage: PROG [-h] [-y] [-b] [-c] x [a]
+        '''
+    help = '''\
+
+        positional arguments:
+          x           x help
+          a           a help
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -y          y help
+          -b          b help
+          -c          c help
+        '''
+
+# =================================================
+# Mutually exclusive group in parent parser tests
+# =================================================
+
+class MEPBase(object):
+
+    def get_parser(self, required=None):
+        parent = super(MEPBase, self).get_parser(required=required)
+        parser = ErrorRaisingArgumentParser(
+            prog=parent.prog, add_help=False, parents=[parent])
+        return parser
+
+
+class TestMutuallyExclusiveGroupErrorsParent(
+    MEPBase, TestMutuallyExclusiveGroupErrors):
+    pass
+
+
+class TestMutuallyExclusiveSimpleParent(
+    MEPBase, TestMutuallyExclusiveSimple):
+    pass
+
+
+class TestMutuallyExclusiveLongParent(
+    MEPBase, TestMutuallyExclusiveLong):
+    pass
+
+
+class TestMutuallyExclusiveFirstSuppressedParent(
+    MEPBase, TestMutuallyExclusiveFirstSuppressed):
+    pass
+
+
+class TestMutuallyExclusiveManySuppressedParent(
+    MEPBase, TestMutuallyExclusiveManySuppressed):
+    pass
+
+
+class TestMutuallyExclusiveOptionalAndPositionalParent(
+    MEPBase, TestMutuallyExclusiveOptionalAndPositional):
+    pass
+
+
+class TestMutuallyExclusiveOptionalsMixedParent(
+    MEPBase, TestMutuallyExclusiveOptionalsMixed):
+    pass
+
+
+class TestMutuallyExclusiveOptionalsAndPositionalsMixedParent(
+    MEPBase, TestMutuallyExclusiveOptionalsAndPositionalsMixed):
+    pass
+
+# =================
+# Set default tests
+# =================
+
+class TestSetDefaults(TestCase):
+
+    def test_set_defaults_no_args(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.set_defaults(x='foo')
+        parser.set_defaults(y='bar', z=1)
+        self.assertEqual(NS(x='foo', y='bar', z=1),
+                         parser.parse_args([]))
+        self.assertEqual(NS(x='foo', y='bar', z=1),
+                         parser.parse_args([], NS()))
+        self.assertEqual(NS(x='baz', y='bar', z=1),
+                         parser.parse_args([], NS(x='baz')))
+        self.assertEqual(NS(x='baz', y='bar', z=2),
+                         parser.parse_args([], NS(x='baz', z=2)))
+
+    def test_set_defaults_with_args(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.set_defaults(x='foo', y='bar')
+        parser.add_argument('-x', default='xfoox')
+        self.assertEqual(NS(x='xfoox', y='bar'),
+                         parser.parse_args([]))
+        self.assertEqual(NS(x='xfoox', y='bar'),
+                         parser.parse_args([], NS()))
+        self.assertEqual(NS(x='baz', y='bar'),
+                         parser.parse_args([], NS(x='baz')))
+        self.assertEqual(NS(x='1', y='bar'),
+                         parser.parse_args('-x 1'.split()))
+        self.assertEqual(NS(x='1', y='bar'),
+                         parser.parse_args('-x 1'.split(), NS()))
+        self.assertEqual(NS(x='1', y='bar'),
+                         parser.parse_args('-x 1'.split(), NS(x='baz')))
+
+    def test_set_defaults_subparsers(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.set_defaults(x='foo')
+        subparsers = parser.add_subparsers()
+        parser_a = subparsers.add_parser('a')
+        parser_a.set_defaults(y='bar')
+        self.assertEqual(NS(x='foo', y='bar'),
+                         parser.parse_args('a'.split()))
+
+    def test_set_defaults_parents(self):
+        parent = ErrorRaisingArgumentParser(add_help=False)
+        parent.set_defaults(x='foo')
+        parser = ErrorRaisingArgumentParser(parents=[parent])
+        self.assertEqual(NS(x='foo'), parser.parse_args([]))
+
+    def test_set_defaults_same_as_add_argument(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.set_defaults(w='W', x='X', y='Y', z='Z')
+        parser.add_argument('-w')
+        parser.add_argument('-x', default='XX')
+        parser.add_argument('y', nargs='?')
+        parser.add_argument('z', nargs='?', default='ZZ')
+
+        # defaults set previously
+        self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
+                         parser.parse_args([]))
+
+        # reset defaults
+        parser.set_defaults(w='WW', x='X', y='YY', z='Z')
+        self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
+                         parser.parse_args([]))
+
+    def test_set_defaults_same_as_add_argument_group(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.set_defaults(w='W', x='X', y='Y', z='Z')
+        group = parser.add_argument_group('foo')
+        group.add_argument('-w')
+        group.add_argument('-x', default='XX')
+        group.add_argument('y', nargs='?')
+        group.add_argument('z', nargs='?', default='ZZ')
+
+
+        # defaults set previously
+        self.assertEqual(NS(w='W', x='XX', y='Y', z='ZZ'),
+                         parser.parse_args([]))
+
+        # reset defaults
+        parser.set_defaults(w='WW', x='X', y='YY', z='Z')
+        self.assertEqual(NS(w='WW', x='X', y='YY', z='Z'),
+                         parser.parse_args([]))
+
+# =================
+# Get default tests
+# =================
+
+class TestGetDefault(TestCase):
+
+    def test_get_default(self):
+        parser = ErrorRaisingArgumentParser()
+        self.assertEqual(None, parser.get_default("foo"))
+        self.assertEqual(None, parser.get_default("bar"))
+
+        parser.add_argument("--foo")
+        self.assertEqual(None, parser.get_default("foo"))
+        self.assertEqual(None, parser.get_default("bar"))
+
+        parser.add_argument("--bar", type=int, default=42)
+        self.assertEqual(None, parser.get_default("foo"))
+        self.assertEqual(42, parser.get_default("bar"))
+
+        parser.set_defaults(foo="badger")
+        self.assertEqual("badger", parser.get_default("foo"))
+        self.assertEqual(42, parser.get_default("bar"))
+
+# ==========================
+# Namespace 'contains' tests
+# ==========================
+
+class TestNamespaceContainsSimple(TestCase):
+
+    def test_empty(self):
+        ns = argparse.Namespace()
+        self.assertEquals('' in ns, False)
+        self.assertEquals('' not in ns, True)
+        self.assertEquals('x' in ns, False)
+
+    def test_non_empty(self):
+        ns = argparse.Namespace(x=1, y=2)
+        self.assertEquals('x' in ns, True)
+        self.assertEquals('x' not in ns, False)
+        self.assertEquals('y' in ns, True)
+        self.assertEquals('' in ns, False)
+        self.assertEquals('xx' in ns, False)
+        self.assertEquals('z' in ns, False)
+
+# =====================
+# Help formatting tests
+# =====================
+
+class TestHelpFormattingMetaclass(type):
+
+    def __init__(cls, name, bases, bodydict):
+        if name == 'HelpTestCase':
+            return
+
+        class AddTests(object):
+
+            def __init__(self, test_class, func_suffix, std_name):
+                self.func_suffix = func_suffix
+                self.std_name = std_name
+
+                for test_func in [self.test_format,
+                                  self.test_print,
+                                  self.test_print_file]:
+                    test_name = '%s_%s' % (test_func.__name__, func_suffix)
+
+                    def test_wrapper(self, test_func=test_func):
+                        test_func(self)
+                    try:
+                        test_wrapper.__name__ = test_name
+                    except TypeError:
+                        pass
+                    setattr(test_class, test_name, test_wrapper)
+
+            def _get_parser(self, tester):
+                parser = argparse.ArgumentParser(
+                    *tester.parser_signature.args,
+                    **tester.parser_signature.kwargs)
+                for argument_sig in tester.argument_signatures:
+                    parser.add_argument(*argument_sig.args,
+                                        **argument_sig.kwargs)
+                group_signatures = tester.argument_group_signatures
+                for group_sig, argument_sigs in group_signatures:
+                    group = parser.add_argument_group(*group_sig.args,
+                                                      **group_sig.kwargs)
+                    for argument_sig in argument_sigs:
+                        group.add_argument(*argument_sig.args,
+                                           **argument_sig.kwargs)
+                return parser
+
+            def _test(self, tester, parser_text):
+                expected_text = getattr(tester, self.func_suffix)
+                expected_text = textwrap.dedent(expected_text)
+                if expected_text != parser_text:
+                    print(repr(expected_text))
+                    print(repr(parser_text))
+                    for char1, char2 in zip(expected_text, parser_text):
+                        if char1 != char2:
+                            print('first diff: %r %r' % (char1, char2))
+                            break
+                tester.assertEqual(expected_text, parser_text)
+
+            def test_format(self, tester):
+                parser = self._get_parser(tester)
+                format = getattr(parser, 'format_%s' % self.func_suffix)
+                self._test(tester, format())
+
+            def test_print(self, tester):
+                parser = self._get_parser(tester)
+                print_ = getattr(parser, 'print_%s' % self.func_suffix)
+                old_stream = getattr(sys, self.std_name)
+                setattr(sys, self.std_name, StringIO())
+                try:
+                    print_()
+                    parser_text = getattr(sys, self.std_name).getvalue()
+                finally:
+                    setattr(sys, self.std_name, old_stream)
+                self._test(tester, parser_text)
+
+            def test_print_file(self, tester):
+                parser = self._get_parser(tester)
+                print_ = getattr(parser, 'print_%s' % self.func_suffix)
+                sfile = StringIO()
+                print_(sfile)
+                parser_text = sfile.getvalue()
+                self._test(tester, parser_text)
+
+        # add tests for {format,print}_{usage,help,version}
+        for func_suffix, std_name in [('usage', 'stdout'),
+                                      ('help', 'stdout'),
+                                      ('version', 'stderr')]:
+            AddTests(cls, func_suffix, std_name)
+
+bases = TestCase,
+HelpTestCase = TestHelpFormattingMetaclass('HelpTestCase', bases, {})
+
+
+class TestHelpBiggerOptionals(HelpTestCase):
+    """Make sure that argument help aligns when options are longer"""
+
+    parser_signature = Sig(prog='PROG', description='DESCRIPTION',
+                           epilog='EPILOG', version='0.1')
+    argument_signatures = [
+        Sig('-x', action='store_true', help='X HELP'),
+        Sig('--y', help='Y HELP'),
+        Sig('foo', help='FOO HELP'),
+        Sig('bar', help='BAR HELP'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-v] [-x] [--y Y] foo bar
+        '''
+    help = usage + '''\
+
+        DESCRIPTION
+
+        positional arguments:
+          foo            FOO HELP
+          bar            BAR HELP
+
+        optional arguments:
+          -h, --help     show this help message and exit
+          -v, --version  show program's version number and exit
+          -x             X HELP
+          --y Y          Y HELP
+
+        EPILOG
+    '''
+    version = '''\
+        0.1
+        '''
+
+
+class TestHelpBiggerOptionalGroups(HelpTestCase):
+    """Make sure that argument help aligns when options are longer"""
+
+    parser_signature = Sig(prog='PROG', description='DESCRIPTION',
+                           epilog='EPILOG', version='0.1')
+    argument_signatures = [
+        Sig('-x', action='store_true', help='X HELP'),
+        Sig('--y', help='Y HELP'),
+        Sig('foo', help='FOO HELP'),
+        Sig('bar', help='BAR HELP'),
+    ]
+    argument_group_signatures = [
+        (Sig('GROUP TITLE', description='GROUP DESCRIPTION'), [
+            Sig('baz', help='BAZ HELP'),
+            Sig('-z', nargs='+', help='Z HELP')]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [-v] [-x] [--y Y] [-z Z [Z ...]] foo bar baz
+        '''
+    help = usage + '''\
+
+        DESCRIPTION
+
+        positional arguments:
+          foo            FOO HELP
+          bar            BAR HELP
+
+        optional arguments:
+          -h, --help     show this help message and exit
+          -v, --version  show program's version number and exit
+          -x             X HELP
+          --y Y          Y HELP
+
+        GROUP TITLE:
+          GROUP DESCRIPTION
+
+          baz            BAZ HELP
+          -z Z [Z ...]   Z HELP
+
+        EPILOG
+    '''
+    version = '''\
+        0.1
+        '''
+
+
+class TestHelpBiggerPositionals(HelpTestCase):
+    """Make sure that help aligns when arguments are longer"""
+
+    parser_signature = Sig(usage='USAGE', description='DESCRIPTION')
+    argument_signatures = [
+        Sig('-x', action='store_true', help='X HELP'),
+        Sig('--y', help='Y HELP'),
+        Sig('ekiekiekifekang', help='EKI HELP'),
+        Sig('bar', help='BAR HELP'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: USAGE
+        '''
+    help = usage + '''\
+
+        DESCRIPTION
+
+        positional arguments:
+          ekiekiekifekang  EKI HELP
+          bar              BAR HELP
+
+        optional arguments:
+          -h, --help       show this help message and exit
+          -x               X HELP
+          --y Y            Y HELP
+        '''
+
+    version = ''
+
+
+class TestHelpReformatting(HelpTestCase):
+    """Make sure that text after short names starts on the first line"""
+
+    parser_signature = Sig(
+        prog='PROG',
+        description='   oddly    formatted\n'
+                    'description\n'
+                    '\n'
+                    'that is so long that it should go onto multiple '
+                    'lines when wrapped')
+    argument_signatures = [
+        Sig('-x', metavar='XX', help='oddly\n'
+                                     '    formatted -x help'),
+        Sig('y', metavar='yyy', help='normal y help'),
+    ]
+    argument_group_signatures = [
+        (Sig('title', description='\n'
+                                  '    oddly formatted group\n'
+                                  '\n'
+                                  'description'),
+         [Sig('-a', action='store_true',
+              help=' oddly \n'
+                   'formatted    -a  help  \n'
+                   '    again, so long that it should be wrapped over '
+                   'multiple lines')]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [-x XX] [-a] yyy
+        '''
+    help = usage + '''\
+
+        oddly formatted description that is so long that it should go onto \
+multiple
+        lines when wrapped
+
+        positional arguments:
+          yyy         normal y help
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -x XX       oddly formatted -x help
+
+        title:
+          oddly formatted group description
+
+          -a          oddly formatted -a help again, so long that it should \
+be wrapped
+                      over multiple lines
+        '''
+    version = ''
+
+
+class TestHelpWrappingShortNames(HelpTestCase):
+    """Make sure that text after short names starts on the first line"""
+
+    parser_signature = Sig(prog='PROG', description= 'D\nD' * 30)
+    argument_signatures = [
+        Sig('-x', metavar='XX', help='XHH HX' * 20),
+        Sig('y', metavar='yyy', help='YH YH' * 20),
+    ]
+    argument_group_signatures = [
+        (Sig('ALPHAS'), [
+            Sig('-a', action='store_true', help='AHHH HHA' * 10)]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [-x XX] [-a] yyy
+        '''
+    help = usage + '''\
+
+        D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
+DD DD DD
+        DD DD DD DD D
+
+        positional arguments:
+          yyy         YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
+YHYH YHYH
+                      YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -x XX       XHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH \
+HXXHH HXXHH
+                      HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HXXHH HX
+
+        ALPHAS:
+          -a          AHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH HHAAHHH \
+HHAAHHH
+                      HHAAHHH HHAAHHH HHA
+        '''
+    version = ''
+
+
+class TestHelpWrappingLongNames(HelpTestCase):
+    """Make sure that text after long names starts on the next line"""
+
+    parser_signature = Sig(usage='USAGE', description= 'D D' * 30,
+                           version='V V'*30)
+    argument_signatures = [
+        Sig('-x', metavar='X' * 25, help='XH XH' * 20),
+        Sig('y', metavar='y' * 25, help='YH YH' * 20),
+    ]
+    argument_group_signatures = [
+        (Sig('ALPHAS'), [
+            Sig('-a', metavar='A' * 25, help='AH AH' * 20),
+            Sig('z', metavar='z' * 25, help='ZH ZH' * 20)]),
+    ]
+    usage = '''\
+        usage: USAGE
+        '''
+    help = usage + '''\
+
+        D DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD \
+DD DD DD
+        DD DD DD DD D
+
+        positional arguments:
+          yyyyyyyyyyyyyyyyyyyyyyyyy
+                                YH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH \
+YHYH YHYH
+                                YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YHYH YH
+
+        optional arguments:
+          -h, --help            show this help message and exit
+          -v, --version         show program's version number and exit
+          -x XXXXXXXXXXXXXXXXXXXXXXXXX
+                                XH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH \
+XHXH XHXH
+                                XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XHXH XH
+
+        ALPHAS:
+          -a AAAAAAAAAAAAAAAAAAAAAAAAA
+                                AH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH \
+AHAH AHAH
+                                AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AHAH AH
+          zzzzzzzzzzzzzzzzzzzzzzzzz
+                                ZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH \
+ZHZH ZHZH
+                                ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZHZH ZH
+        '''
+    version = '''\
+        V VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV VV \
+VV VV VV
+        VV VV VV VV V
+        '''
+
+
+class TestHelpUsage(HelpTestCase):
+    """Test basic usage messages"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-w', nargs='+', help='w'),
+        Sig('-x', nargs='*', help='x'),
+        Sig('a', help='a'),
+        Sig('b', help='b', nargs=2),
+        Sig('c', help='c', nargs='?'),
+    ]
+    argument_group_signatures = [
+        (Sig('group'), [
+            Sig('-y', nargs='?', help='y'),
+            Sig('-z', nargs=3, help='z'),
+            Sig('d', help='d', nargs='*'),
+            Sig('e', help='e', nargs='+'),
+        ])
+    ]
+    usage = '''\
+        usage: PROG [-h] [-w W [W ...]] [-x [X [X ...]]] [-y [Y]] [-z Z Z Z]
+                    a b b [c] [d [d ...]] e [e ...]
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          a               a
+          b               b
+          c               c
+
+        optional arguments:
+          -h, --help      show this help message and exit
+          -w W [W ...]    w
+          -x [X [X ...]]  x
+
+        group:
+          -y [Y]          y
+          -z Z Z Z        z
+          d               d
+          e               e
+        '''
+    version = ''
+
+
+class TestHelpOnlyUserGroups(HelpTestCase):
+    """Test basic usage messages"""
+
+    parser_signature = Sig(prog='PROG', add_help=False)
+    argument_signatures = []
+    argument_group_signatures = [
+        (Sig('xxxx'), [
+            Sig('-x', help='x'),
+            Sig('a', help='a'),
+        ]),
+        (Sig('yyyy'), [
+            Sig('b', help='b'),
+            Sig('-y', help='y'),
+        ]),
+    ]
+    usage = '''\
+        usage: PROG [-x X] [-y Y] a b
+        '''
+    help = usage + '''\
+
+        xxxx:
+          -x X  x
+          a     a
+
+        yyyy:
+          b     b
+          -y Y  y
+        '''
+    version = ''
+
+
+class TestHelpUsageLongProg(HelpTestCase):
+    """Test usage messages where the prog is long"""
+
+    parser_signature = Sig(prog='P' * 60)
+    argument_signatures = [
+        Sig('-w', metavar='W'),
+        Sig('-x', metavar='X'),
+        Sig('a'),
+        Sig('b'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+               [-h] [-w W] [-x X] a b
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          a
+          b
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          -w W
+          -x X
+        '''
+    version = ''
+
+
+class TestHelpUsageLongProgOptionsWrap(HelpTestCase):
+    """Test usage messages where the prog is long and the optionals wrap"""
+
+    parser_signature = Sig(prog='P' * 60)
+    argument_signatures = [
+        Sig('-w', metavar='W' * 25),
+        Sig('-x', metavar='X' * 25),
+        Sig('-y', metavar='Y' * 25),
+        Sig('-z', metavar='Z' * 25),
+        Sig('a'),
+        Sig('b'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+               [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
+[-x XXXXXXXXXXXXXXXXXXXXXXXXX]
+               [-y YYYYYYYYYYYYYYYYYYYYYYYYY] [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
+               a b
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          a
+          b
+
+        optional arguments:
+          -h, --help            show this help message and exit
+          -w WWWWWWWWWWWWWWWWWWWWWWWWW
+          -x XXXXXXXXXXXXXXXXXXXXXXXXX
+          -y YYYYYYYYYYYYYYYYYYYYYYYYY
+          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
+        '''
+    version = ''
+
+
+class TestHelpUsageLongProgPositionalsWrap(HelpTestCase):
+    """Test usage messages where the prog is long and the positionals wrap"""
+
+    parser_signature = Sig(prog='P' * 60, add_help=False)
+    argument_signatures = [
+        Sig('a' * 25),
+        Sig('b' * 25),
+        Sig('c' * 25),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+               aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
+               ccccccccccccccccccccccccc
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          aaaaaaaaaaaaaaaaaaaaaaaaa
+          bbbbbbbbbbbbbbbbbbbbbbbbb
+          ccccccccccccccccccccccccc
+        '''
+    version = ''
+
+
+class TestHelpUsageOptionalsWrap(HelpTestCase):
+    """Test usage messages where the optionals wrap"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-w', metavar='W' * 25),
+        Sig('-x', metavar='X' * 25),
+        Sig('-y', metavar='Y' * 25),
+        Sig('-z', metavar='Z' * 25),
+        Sig('a'),
+        Sig('b'),
+        Sig('c'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-w WWWWWWWWWWWWWWWWWWWWWWWWW] \
+[-x XXXXXXXXXXXXXXXXXXXXXXXXX]
+                    [-y YYYYYYYYYYYYYYYYYYYYYYYYY] \
+[-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
+                    a b c
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          a
+          b
+          c
+
+        optional arguments:
+          -h, --help            show this help message and exit
+          -w WWWWWWWWWWWWWWWWWWWWWWWWW
+          -x XXXXXXXXXXXXXXXXXXXXXXXXX
+          -y YYYYYYYYYYYYYYYYYYYYYYYYY
+          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
+        '''
+    version = ''
+
+
+class TestHelpUsagePositionalsWrap(HelpTestCase):
+    """Test usage messages where the positionals wrap"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-x'),
+        Sig('-y'),
+        Sig('-z'),
+        Sig('a' * 25),
+        Sig('b' * 25),
+        Sig('c' * 25),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-x X] [-y Y] [-z Z]
+                    aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
+                    ccccccccccccccccccccccccc
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          aaaaaaaaaaaaaaaaaaaaaaaaa
+          bbbbbbbbbbbbbbbbbbbbbbbbb
+          ccccccccccccccccccccccccc
+
+        optional arguments:
+          -h, --help            show this help message and exit
+          -x X
+          -y Y
+          -z Z
+        '''
+    version = ''
+
+
+class TestHelpUsageOptionalsPositionalsWrap(HelpTestCase):
+    """Test usage messages where the optionals and positionals wrap"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-x', metavar='X' * 25),
+        Sig('-y', metavar='Y' * 25),
+        Sig('-z', metavar='Z' * 25),
+        Sig('a' * 25),
+        Sig('b' * 25),
+        Sig('c' * 25),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
+[-y YYYYYYYYYYYYYYYYYYYYYYYYY]
+                    [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
+                    aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
+                    ccccccccccccccccccccccccc
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          aaaaaaaaaaaaaaaaaaaaaaaaa
+          bbbbbbbbbbbbbbbbbbbbbbbbb
+          ccccccccccccccccccccccccc
+
+        optional arguments:
+          -h, --help            show this help message and exit
+          -x XXXXXXXXXXXXXXXXXXXXXXXXX
+          -y YYYYYYYYYYYYYYYYYYYYYYYYY
+          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
+        '''
+    version = ''
+
+
+class TestHelpUsageOptionalsOnlyWrap(HelpTestCase):
+    """Test usage messages where there are only optionals and they wrap"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-x', metavar='X' * 25),
+        Sig('-y', metavar='Y' * 25),
+        Sig('-z', metavar='Z' * 25),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-x XXXXXXXXXXXXXXXXXXXXXXXXX] \
+[-y YYYYYYYYYYYYYYYYYYYYYYYYY]
+                    [-z ZZZZZZZZZZZZZZZZZZZZZZZZZ]
+        '''
+    help = usage + '''\
+
+        optional arguments:
+          -h, --help            show this help message and exit
+          -x XXXXXXXXXXXXXXXXXXXXXXXXX
+          -y YYYYYYYYYYYYYYYYYYYYYYYYY
+          -z ZZZZZZZZZZZZZZZZZZZZZZZZZ
+        '''
+    version = ''
+
+
+class TestHelpUsagePositionalsOnlyWrap(HelpTestCase):
+    """Test usage messages where there are only positionals and they wrap"""
+
+    parser_signature = Sig(prog='PROG', add_help=False)
+    argument_signatures = [
+        Sig('a' * 25),
+        Sig('b' * 25),
+        Sig('c' * 25),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG aaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbb
+                    ccccccccccccccccccccccccc
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          aaaaaaaaaaaaaaaaaaaaaaaaa
+          bbbbbbbbbbbbbbbbbbbbbbbbb
+          ccccccccccccccccccccccccc
+        '''
+    version = ''
+
+
+class TestHelpVariableExpansion(HelpTestCase):
+    """Test that variables are expanded properly in help messages"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-x', type=int,
+            help='x %(prog)s %(default)s %(type)s %%'),
+        Sig('-y', action='store_const', default=42, const='XXX',
+            help='y %(prog)s %(default)s %(const)s'),
+        Sig('--foo', choices='abc',
+            help='foo %(prog)s %(default)s %(choices)s'),
+        Sig('--bar', default='baz', choices=[1, 2], metavar='BBB',
+            help='bar %(prog)s %(default)s %(dest)s'),
+        Sig('spam', help='spam %(prog)s %(default)s'),
+        Sig('badger', default=0.5, help='badger %(prog)s %(default)s'),
+    ]
+    argument_group_signatures = [
+        (Sig('group'), [
+            Sig('-a', help='a %(prog)s %(default)s'),
+            Sig('-b', default=-1, help='b %(prog)s %(default)s'),
+        ])
+    ]
+    usage = ('''\
+        usage: PROG [-h] [-x X] [-y] [--foo {a,b,c}] [--bar BBB] [-a A] [-b B]
+                    spam badger
+        ''')
+    help = usage + '''\
+
+        positional arguments:
+          spam           spam PROG None
+          badger         badger PROG 0.5
+
+        optional arguments:
+          -h, --help     show this help message and exit
+          -x X           x PROG None int %
+          -y             y PROG 42 XXX
+          --foo {a,b,c}  foo PROG None a, b, c
+          --bar BBB      bar PROG baz bar
+
+        group:
+          -a A           a PROG None
+          -b B           b PROG -1
+        '''
+    version = ''
+
+
+class TestHelpVariableExpansionUsageSupplied(HelpTestCase):
+    """Test that variables are expanded properly when usage= is present"""
+
+    parser_signature = Sig(prog='PROG', usage='%(prog)s FOO')
+    argument_signatures = []
+    argument_group_signatures = []
+    usage = ('''\
+        usage: PROG FOO
+        ''')
+    help = usage + '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+        '''
+    version = ''
+
+
+class TestHelpVariableExpansionNoArguments(HelpTestCase):
+    """Test that variables are expanded properly with no arguments"""
+
+    parser_signature = Sig(prog='PROG', add_help=False)
+    argument_signatures = []
+    argument_group_signatures = []
+    usage = ('''\
+        usage: PROG
+        ''')
+    help = usage
+    version = ''
+
+
+class TestHelpSuppressUsage(HelpTestCase):
+    """Test that items can be suppressed in usage messages"""
+
+    parser_signature = Sig(prog='PROG', usage=argparse.SUPPRESS)
+    argument_signatures = [
+        Sig('--foo', help='foo help'),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = []
+    help = '''\
+        positional arguments:
+          spam        spam help
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO   foo help
+        '''
+    usage = ''
+    version = ''
+
+
+class TestHelpSuppressOptional(HelpTestCase):
+    """Test that optional arguments can be suppressed in help messages"""
+
+    parser_signature = Sig(prog='PROG', add_help=False)
+    argument_signatures = [
+        Sig('--foo', help=argparse.SUPPRESS),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG spam
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          spam  spam help
+        '''
+    version = ''
+
+
+class TestHelpSuppressOptionalGroup(HelpTestCase):
+    """Test that optional groups can be suppressed in help messages"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('--foo', help='foo help'),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = [
+        (Sig('group'), [Sig('--bar', help=argparse.SUPPRESS)]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [--foo FOO] spam
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          spam        spam help
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO   foo help
+        '''
+    version = ''
+
+
+class TestHelpSuppressPositional(HelpTestCase):
+    """Test that positional arguments can be suppressed in help messages"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('--foo', help='foo help'),
+        Sig('spam', help=argparse.SUPPRESS),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [--foo FOO]
+        '''
+    help = usage + '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO   foo help
+        '''
+    version = ''
+
+
+class TestHelpRequiredOptional(HelpTestCase):
+    """Test that required options don't look optional"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('--foo', required=True, help='foo help'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] --foo FOO
+        '''
+    help = usage + '''\
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO   foo help
+        '''
+    version = ''
+
+
+class TestHelpAlternatePrefixChars(HelpTestCase):
+    """Test that options display with different prefix characters"""
+
+    parser_signature = Sig(prog='PROG', prefix_chars='^;', add_help=False)
+    argument_signatures = [
+        Sig('^^foo', action='store_true', help='foo help'),
+        Sig(';b', ';;bar', help='bar help'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [^^foo] [;b BAR]
+        '''
+    help = usage + '''\
+
+        optional arguments:
+          ^^foo              foo help
+          ;b BAR, ;;bar BAR  bar help
+        '''
+    version = ''
+
+
+class TestHelpNoHelpOptional(HelpTestCase):
+    """Test that the --help argument can be suppressed help messages"""
+
+    parser_signature = Sig(prog='PROG', add_help=False)
+    argument_signatures = [
+        Sig('--foo', help='foo help'),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [--foo FOO] spam
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          spam       spam help
+
+        optional arguments:
+          --foo FOO  foo help
+        '''
+    version = ''
+
+
+class TestHelpVersionOptional(HelpTestCase):
+    """Test that the --version argument can be suppressed help messages"""
+
+    parser_signature = Sig(prog='PROG', version='1.0')
+    argument_signatures = [
+        Sig('--foo', help='foo help'),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-v] [--foo FOO] spam
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          spam           spam help
+
+        optional arguments:
+          -h, --help     show this help message and exit
+          -v, --version  show program's version number and exit
+          --foo FOO      foo help
+        '''
+    version = '''\
+        1.0
+        '''
+
+
+class TestHelpNone(HelpTestCase):
+    """Test that no errors occur if no help is specified"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('--foo'),
+        Sig('spam'),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [--foo FOO] spam
+        '''
+    help = usage + '''\
+
+        positional arguments:
+          spam
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO
+        '''
+    version = ''
+
+
+class TestHelpTupleMetavar(HelpTestCase):
+    """Test specifying metavar as a tuple"""
+
+    parser_signature = Sig(prog='PROG')
+    argument_signatures = [
+        Sig('-w', help='w', nargs='+', metavar=('W1', 'W2')),
+        Sig('-x', help='x', nargs='*', metavar=('X1', 'X2')),
+        Sig('-y', help='y', nargs=3, metavar=('Y1', 'Y2', 'Y3')),
+        Sig('-z', help='z', nargs='?', metavar=('Z1', )),
+    ]
+    argument_group_signatures = []
+    usage = '''\
+        usage: PROG [-h] [-w W1 [W2 ...]] [-x [X1 [X2 ...]]] [-y Y1 Y2 Y3] \
+[-z [Z1]]
+        '''
+    help = usage + '''\
+
+        optional arguments:
+          -h, --help        show this help message and exit
+          -w W1 [W2 ...]    w
+          -x [X1 [X2 ...]]  x
+          -y Y1 Y2 Y3       y
+          -z [Z1]           z
+        '''
+    version = ''
+
+
+class TestHelpRawText(HelpTestCase):
+    """Test the RawTextHelpFormatter"""
+
+    parser_signature = Sig(
+        prog='PROG', formatter_class=argparse.RawTextHelpFormatter,
+        description='Keep the formatting\n'
+                    '    exactly as it is written\n'
+                    '\n'
+                    'here\n')
+
+    argument_signatures = [
+        Sig('--foo', help='    foo help should also\n'
+                          'appear as given here'),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = [
+        (Sig('title', description='    This text\n'
+                                  '  should be indented\n'
+                                  '    exactly like it is here\n'),
+         [Sig('--bar', help='bar help')]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [--foo FOO] [--bar BAR] spam
+        '''
+    help = usage + '''\
+
+        Keep the formatting
+            exactly as it is written
+
+        here
+
+        positional arguments:
+          spam        spam help
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO       foo help should also
+                      appear as given here
+
+        title:
+              This text
+            should be indented
+              exactly like it is here
+
+          --bar BAR   bar help
+        '''
+    version = ''
+
+
+class TestHelpRawDescription(HelpTestCase):
+    """Test the RawTextHelpFormatter"""
+
+    parser_signature = Sig(
+        prog='PROG', formatter_class=argparse.RawDescriptionHelpFormatter,
+        description='Keep the formatting\n'
+                    '    exactly as it is written\n'
+                    '\n'
+                    'here\n')
+
+    argument_signatures = [
+        Sig('--foo', help='  foo help should not\n'
+                          '    retain this odd formatting'),
+        Sig('spam', help='spam help'),
+    ]
+    argument_group_signatures = [
+        (Sig('title', description='    This text\n'
+                                  '  should be indented\n'
+                                  '    exactly like it is here\n'),
+         [Sig('--bar', help='bar help')]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [--foo FOO] [--bar BAR] spam
+        '''
+    help = usage + '''\
+
+        Keep the formatting
+            exactly as it is written
+
+        here
+
+        positional arguments:
+          spam        spam help
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO   foo help should not retain this odd formatting
+
+        title:
+              This text
+            should be indented
+              exactly like it is here
+
+          --bar BAR   bar help
+        '''
+    version = ''
+
+
+class TestHelpArgumentDefaults(HelpTestCase):
+    """Test the ArgumentDefaultsHelpFormatter"""
+
+    parser_signature = Sig(
+        prog='PROG', formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+        description='description')
+
+    argument_signatures = [
+        Sig('--foo', help='foo help - oh and by the way, %(default)s'),
+        Sig('--bar', action='store_true', help='bar help'),
+        Sig('spam', help='spam help'),
+        Sig('badger', nargs='?', default='wooden', help='badger help'),
+    ]
+    argument_group_signatures = [
+        (Sig('title', description='description'),
+         [Sig('--baz', type=int, default=42, help='baz help')]),
+    ]
+    usage = '''\
+        usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
+        '''
+    help = usage + '''\
+
+        description
+
+        positional arguments:
+          spam        spam help
+          badger      badger help (default: wooden)
+
+        optional arguments:
+          -h, --help  show this help message and exit
+          --foo FOO   foo help - oh and by the way, None
+          --bar       bar help (default: False)
+
+        title:
+          description
+
+          --baz BAZ   baz help (default: 42)
+        '''
+    version = ''
+
+# =====================================
+# Optional/Positional constructor tests
+# =====================================
+
+class TestInvalidArgumentConstructors(TestCase):
+    """Test a bunch of invalid Argument constructors"""
+
+    def assertTypeError(self, *args, **kwargs):
+        parser = argparse.ArgumentParser()
+        self.assertRaises(TypeError, parser.add_argument,
+                          *args, **kwargs)
+
+    def assertValueError(self, *args, **kwargs):
+        parser = argparse.ArgumentParser()
+        self.assertRaises(ValueError, parser.add_argument,
+                          *args, **kwargs)
+
+    def test_invalid_keyword_arguments(self):
+        self.assertTypeError('-x', bar=None)
+        self.assertTypeError('-y', callback='foo')
+        self.assertTypeError('-y', callback_args=())
+        self.assertTypeError('-y', callback_kwargs={})
+
+    def test_missing_destination(self):
+        self.assertTypeError()
+        for action in ['append', 'store']:
+            self.assertTypeError(action=action)
+
+    def test_invalid_option_strings(self):
+        self.assertValueError('--')
+        self.assertValueError('---')
+
+    def test_invalid_type(self):
+        self.assertValueError('--foo', type='int')
+
+    def test_invalid_action(self):
+        self.assertValueError('-x', action='foo')
+        self.assertValueError('foo', action='baz')
+        parser = argparse.ArgumentParser()
+        try:
+            parser.add_argument("--foo", action="store-true")
+        except ValueError:
+            e = sys.exc_info()[1]
+            expected = 'unknown action'
+            msg = 'expected %r, found %r' % (expected, e)
+            self.failUnless(expected in str(e), msg)
+
+    def test_multiple_dest(self):
+        parser = argparse.ArgumentParser()
+        parser.add_argument(dest='foo')
+        try:
+            parser.add_argument('bar', dest='baz')
+        except ValueError:
+            e = sys.exc_info()[1]
+            expected = 'dest supplied twice for positional argument'
+            msg = 'expected %r, found %r' % (expected, e)
+            self.failUnless(expected in str(e), msg)
+
+    def test_no_argument_actions(self):
+        for action in ['store_const', 'store_true', 'store_false',
+                       'append_const', 'count']:
+            for attrs in [dict(type=int), dict(nargs='+'),
+                          dict(choices='ab')]:
+                self.assertTypeError('-x', action=action, **attrs)
+
+    def test_no_argument_no_const_actions(self):
+        # options with zero arguments
+        for action in ['store_true', 'store_false', 'count']:
+
+            # const is always disallowed
+            self.assertTypeError('-x', const='foo', action=action)
+
+            # nargs is always disallowed
+            self.assertTypeError('-x', nargs='*', action=action)
+
+    def test_more_than_one_argument_actions(self):
+        for action in ['store', 'append']:
+
+            # nargs=0 is disallowed
+            self.assertValueError('-x', nargs=0, action=action)
+            self.assertValueError('spam', nargs=0, action=action)
+
+            # const is disallowed with non-optional arguments
+            for nargs in [1, '*', '+']:
+                self.assertValueError('-x', const='foo',
+                                      nargs=nargs, action=action)
+                self.assertValueError('spam', const='foo',
+                                      nargs=nargs, action=action)
+
+    def test_required_const_actions(self):
+        for action in ['store_const', 'append_const']:
+
+            # nargs is always disallowed
+            self.assertTypeError('-x', nargs='+', action=action)
+
+    def test_parsers_action_missing_params(self):
+        self.assertTypeError('command', action='parsers')
+        self.assertTypeError('command', action='parsers', prog='PROG')
+        self.assertTypeError('command', action='parsers',
+                             parser_class=argparse.ArgumentParser)
+
+    def test_required_positional(self):
+        self.assertTypeError('foo', required=True)
+
+    def test_user_defined_action(self):
+
+        class Success(Exception):
+            pass
+
+        class Action(object):
+
+            def __init__(self,
+                         option_strings,
+                         dest,
+                         const,
+                         default,
+                         required=False):
+                if dest == 'spam':
+                    if const is Success:
+                        if default is Success:
+                            raise Success()
+
+            def __call__(self, *args, **kwargs):
+                pass
+
+        parser = argparse.ArgumentParser()
+        self.assertRaises(Success, parser.add_argument, '--spam',
+                          action=Action, default=Success, const=Success)
+        self.assertRaises(Success, parser.add_argument, 'spam',
+                          action=Action, default=Success, const=Success)
+
+# ================================
+# Actions returned by add_argument
+# ================================
+
+class TestActionsReturned(TestCase):
+
+    def test_dest(self):
+        parser = argparse.ArgumentParser()
+        action = parser.add_argument('--foo')
+        self.assertEqual(action.dest, 'foo')
+        action = parser.add_argument('-b', '--bar')
+        self.assertEqual(action.dest, 'bar')
+        action = parser.add_argument('-x', '-y')
+        self.assertEqual(action.dest, 'x')
+
+    def test_misc(self):
+        parser = argparse.ArgumentParser()
+        action = parser.add_argument('--foo', nargs='?', const=42,
+                                     default=84, type=int, choices=[1, 2],
+                                     help='FOO', metavar='BAR', dest='baz')
+        self.assertEqual(action.nargs, '?')
+        self.assertEqual(action.const, 42)
+        self.assertEqual(action.default, 84)
+        self.assertEqual(action.type, int)
+        self.assertEqual(action.choices, [1, 2])
+        self.assertEqual(action.help, 'FOO')
+        self.assertEqual(action.metavar, 'BAR')
+        self.assertEqual(action.dest, 'baz')
+
+
+# ================================
+# Argument conflict handling tests
+# ================================
+
+class TestConflictHandling(TestCase):
+
+    def test_bad_type(self):
+        self.assertRaises(ValueError, argparse.ArgumentParser,
+                          conflict_handler='foo')
+
+    def test_conflict_error(self):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('-x')
+        self.assertRaises(argparse.ArgumentError,
+                          parser.add_argument, '-x')
+        parser.add_argument('--spam')
+        self.assertRaises(argparse.ArgumentError,
+                          parser.add_argument, '--spam')
+
+    def test_resolve_error(self):
+        get_parser = argparse.ArgumentParser
+        parser = get_parser(prog='PROG', conflict_handler='resolve')
+
+        parser.add_argument('-x', help='OLD X')
+        parser.add_argument('-x', help='NEW X')
+        self.assertEqual(parser.format_help(), textwrap.dedent('''\
+            usage: PROG [-h] [-x X]
+
+            optional arguments:
+              -h, --help  show this help message and exit
+              -x X        NEW X
+            '''))
+
+        parser.add_argument('--spam', metavar='OLD_SPAM')
+        parser.add_argument('--spam', metavar='NEW_SPAM')
+        self.assertEqual(parser.format_help(), textwrap.dedent('''\
+            usage: PROG [-h] [-x X] [--spam NEW_SPAM]
+
+            optional arguments:
+              -h, --help       show this help message and exit
+              -x X             NEW X
+              --spam NEW_SPAM
+            '''))
+
+
+# =============================
+# Help and Version option tests
+# =============================
+
+class TestOptionalsHelpVersionActions(TestCase):
+    """Test the help and version actions"""
+
+    def _get_error(self, func, *args, **kwargs):
+        try:
+            func(*args, **kwargs)
+        except ArgumentParserError:
+            return sys.exc_info()[1]
+        else:
+            self.assertRaises(ArgumentParserError, func, *args, **kwargs)
+
+    def assertPrintHelpExit(self, parser, args_str):
+        self.assertEqual(
+            parser.format_help(),
+            self._get_error(parser.parse_args, args_str.split()).stdout)
+
+    def assertPrintVersionExit(self, parser, args_str):
+        self.assertEqual(
+            parser.format_version(),
+            self._get_error(parser.parse_args, args_str.split()).stderr)
+
+    def assertArgumentParserError(self, parser, *args):
+        self.assertRaises(ArgumentParserError, parser.parse_args, args)
+
+    def test_version(self):
+        parser = ErrorRaisingArgumentParser(version='1.0')
+        self.assertPrintHelpExit(parser, '-h')
+        self.assertPrintHelpExit(parser, '--help')
+        self.assertPrintVersionExit(parser, '-v')
+        self.assertPrintVersionExit(parser, '--version')
+
+    def test_version_format(self):
+        parser = ErrorRaisingArgumentParser(prog='PPP', version='%(prog)s 3.5')
+        msg = self._get_error(parser.parse_args, ['-v']).stderr
+        self.assertEqual('PPP 3.5\n', msg)
+
+    def test_version_no_help(self):
+        parser = ErrorRaisingArgumentParser(add_help=False, version='1.0')
+        self.assertArgumentParserError(parser, '-h')
+        self.assertArgumentParserError(parser, '--help')
+        self.assertPrintVersionExit(parser, '-v')
+        self.assertPrintVersionExit(parser, '--version')
+
+    def test_version_action(self):
+        parser = ErrorRaisingArgumentParser(prog='XXX')
+        parser.add_argument('-V', action='version', version='%(prog)s 3.7')
+        msg = self._get_error(parser.parse_args, ['-V']).stderr
+        self.assertEqual('XXX 3.7\n', msg)
+
+    def test_no_help(self):
+        parser = ErrorRaisingArgumentParser(add_help=False)
+        self.assertArgumentParserError(parser, '-h')
+        self.assertArgumentParserError(parser, '--help')
+        self.assertArgumentParserError(parser, '-v')
+        self.assertArgumentParserError(parser, '--version')
+
+    def test_alternate_help_version(self):
+        parser = ErrorRaisingArgumentParser()
+        parser.add_argument('-x', action='help')
+        parser.add_argument('-y', action='version')
+        self.assertPrintHelpExit(parser, '-x')
+        self.assertPrintVersionExit(parser, '-y')
+        self.assertArgumentParserError(parser, '-v')
+        self.assertArgumentParserError(parser, '--version')
+
+    def test_help_version_extra_arguments(self):
+        parser = ErrorRaisingArgumentParser(version='1.0')
+        parser.add_argument('-x', action='store_true')
+        parser.add_argument('y')
+
+        # try all combinations of valid prefixes and suffixes
+        valid_prefixes = ['', '-x', 'foo', '-x bar', 'baz -x']
+        valid_suffixes = valid_prefixes + ['--bad-option', 'foo bar baz']
+        for prefix in valid_prefixes:
+            for suffix in valid_suffixes:
+                format = '%s %%s %s' % (prefix, suffix)
+            self.assertPrintHelpExit(parser, format % '-h')
+            self.assertPrintHelpExit(parser, format % '--help')
+            self.assertPrintVersionExit(parser, format % '-v')
+            self.assertPrintVersionExit(parser, format % '--version')
+
+
+# ======================
+# str() and repr() tests
+# ======================
+
+class TestStrings(TestCase):
+    """Test str()  and repr() on Optionals and Positionals"""
+
+    def assertStringEqual(self, obj, result_string):
+        for func in [str, repr]:
+            self.assertEqual(func(obj), result_string)
+
+    def test_optional(self):
+        option = argparse.Action(
+            option_strings=['--foo', '-a', '-b'],
+            dest='b',
+            type='int',
+            nargs='+',
+            default=42,
+            choices=[1, 2, 3],
+            help='HELP',
+            metavar='METAVAR')
+        string = (
+            "Action(option_strings=['--foo', '-a', '-b'], dest='b', "
+            "nargs='+', const=None, default=42, type='int', "
+            "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
+        self.assertStringEqual(option, string)
+
+    def test_argument(self):
+        argument = argparse.Action(
+            option_strings=[],
+            dest='x',
+            type=float,
+            nargs='?',
+            default=2.5,
+            choices=[0.5, 1.5, 2.5],
+            help='H HH H',
+            metavar='MV MV MV')
+        string = (
+            "Action(option_strings=[], dest='x', nargs='?', "
+            "const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
+            "help='H HH H', metavar='MV MV MV')" % float)
+        self.assertStringEqual(argument, string)
+
+    def test_namespace(self):
+        ns = argparse.Namespace(foo=42, bar='spam')
+        string = "Namespace(bar='spam', foo=42)"
+        self.assertStringEqual(ns, string)
+
+    def test_parser(self):
+        parser = argparse.ArgumentParser(prog='PROG')
+        string = (
+            "ArgumentParser(prog='PROG', usage=None, description=None, "
+            "version=None, formatter_class=%r, conflict_handler='error', "
+            "add_help=True)" % argparse.HelpFormatter)
+        self.assertStringEqual(parser, string)
+
+# ===============
+# Namespace tests
+# ===============
+
+class TestNamespace(TestCase):
+
+    def test_constructor(self):
+        ns = argparse.Namespace()
+        self.assertRaises(AttributeError, getattr, ns, 'x')
+
+        ns = argparse.Namespace(a=42, b='spam')
+        self.assertEqual(ns.a, 42)
+        self.assertEqual(ns.b, 'spam')
+
+    def test_equality(self):
+        ns1 = argparse.Namespace(a=1, b=2)
+        ns2 = argparse.Namespace(b=2, a=1)
+        ns3 = argparse.Namespace(a=1)
+        ns4 = argparse.Namespace(b=2)
+
+        self.assertEqual(ns1, ns2)
+        self.assertNotEqual(ns1, ns3)
+        self.assertNotEqual(ns1, ns4)
+        self.assertNotEqual(ns2, ns3)
+        self.assertNotEqual(ns2, ns4)
+        self.failUnless(ns1 != ns3)
+        self.failUnless(ns1 != ns4)
+        self.failUnless(ns2 != ns3)
+        self.failUnless(ns2 != ns4)
+
+
+# ===================
+# File encoding tests
+# ===================
+
+class TestEncoding(TestCase):
+
+    def _test_module_encoding(self, path):
+        path, _ = os.path.splitext(path)
+        path += ".py"
+        codecs.open(path, 'r', 'utf8').read()
+
+    def test_argparse_module_encoding(self):
+        self._test_module_encoding(argparse.__file__)
+
+    def test_test_argparse_module_encoding(self):
+        self._test_module_encoding(__file__)
+
+# ===================
+# ArgumentError tests
+# ===================
+
+class TestArgumentError(TestCase):
+
+    def test_argument_error(self):
+        msg = "my error here"
+        error = argparse.ArgumentError(None, msg)
+        self.failUnlessEqual(str(error), msg)
+
+# =======================
+# ArgumentTypeError tests
+# =======================
+
+class TestArgumentError(TestCase):
+
+    def test_argument_type_error(self):
+
+        def spam(string):
+            raise argparse.ArgumentTypeError('spam!')
+
+        parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
+        parser.add_argument('x', type=spam)
+        try:
+            parser.parse_args(['XXX'])
+        except ArgumentParserError:
+            expected = 'usage: PROG x\nPROG: error: argument x: spam!\n'
+            msg = sys.exc_info()[1].stderr
+            self.failUnlessEqual(expected, msg)
+        else:
+            self.fail()
+
+# ======================
+# parse_known_args tests
+# ======================
+
+class TestParseKnownArgs(TestCase):
+
+    def test_optionals(self):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('--foo')
+        args, extras = parser.parse_known_args('--foo F --bar --baz'.split())
+        self.failUnlessEqual(NS(foo='F'), args)
+        self.failUnlessEqual(['--bar', '--baz'], extras)
+
+    def test_mixed(self):
+        parser = argparse.ArgumentParser()
+        parser.add_argument('-v', nargs='?', const=1, type=int)
+        parser.add_argument('--spam', action='store_false')
+        parser.add_argument('badger')
+
+        argv = ["B", "C", "--foo", "-v", "3", "4"]
+        args, extras = parser.parse_known_args(argv)
+        self.failUnlessEqual(NS(v=3, spam=True, badger="B"), args)
+        self.failUnlessEqual(["C", "--foo", "4"], extras)
+
+# ============================
+# from argparse import * tests
+# ============================
+
+class TestImportStar(TestCase):
+
+    def test(self):
+        for name in argparse.__all__:
+            self.failUnless(hasattr(argparse, name))
+
+
+if __name__ == '__main__':
+    unittest.main()
