Upgrade optparse module and tests to Optik 1.5a1:
  * add expansion of default values in help text: the string
    "%default" in an option's help string is expanded to str() of
    that option's default value, or "none" if no default value.
  * bug #955889: option default values that happen to be strings are
    now processed in the same way as values from the command line; this
    allows generation of nicer help when using custom types.  Can
    be disabled with parser.set_process_default_values(False).
  * bug #960515: don't crash when generating help for callback
    options that specify 'type', but not 'dest' or 'metavar'.
  * feature #815264: change the default help format for short options
    that take an argument from e.g. "-oARG" to "-o ARG"; add
    set_short_opt_delimiter() and set_long_opt_delimiter() methods to
    HelpFormatter to allow (slight) customization of the formatting.
  * patch #736940: internationalize Optik: all built-in user-
    targeted literal strings are passed through gettext.gettext().  (If
    you want translations (.po files), they're not included with Python
    -- you'll find them in the Optik source distribution from
    http://optik.sourceforge.net/ .)
  * bug #878453: respect $COLUMNS environment variable for
    wrapping help output.
  * feature #988122: expand "%prog" in the 'description' passed
    to OptionParser, just like in the 'usage' and 'version' strings.
    (This is *not* done in the 'description' passed to OptionGroup.)
diff --git a/Lib/optparse.py b/Lib/optparse.py
index d3593d3..f30fc45 100644
--- a/Lib/optparse.py
+++ b/Lib/optparse.py
@@ -16,13 +16,11 @@
 # Python developers: please do not make changes to this file, since
 # it is automatically generated from the Optik source code.
 
-__version__ = "1.4.1+"
+__version__ = "1.5a1"
 
 __all__ = ['Option',
            'SUPPRESS_HELP',
            'SUPPRESS_USAGE',
-           'STD_HELP_OPTION',
-           'STD_VERSION_OPTION',
            'Values',
            'OptionContainer',
            'OptionGroup',
@@ -37,7 +35,8 @@
            'BadOptionError']
 
 __copyright__ = """
-Copyright (c) 2001-2003 Gregory P. Ward.  All rights reserved.
+Copyright (c) 2001-2004 Gregory P. Ward.  All rights reserved.
+Copyright (c) 2002-2004 Python Software Foundation.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -70,12 +69,23 @@
 import sys, os
 import types
 import textwrap
+from gettext import gettext as _
+
+def _repr(self):
+    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
+
+
+# This file was generated from:
+#   Id: option_parser.py,v 1.67 2004/07/24 23:21:21 gward Exp
+#   Id: option.py,v 1.33 2004/07/24 23:21:21 gward Exp
+#   Id: help.py,v 1.15 2004/07/24 23:21:21 gward Exp
+#   Id: errors.py,v 1.9 2004/07/24 23:21:21 gward Exp
 
 class OptParseError (Exception):
-    def __init__ (self, msg):
+    def __init__(self, msg):
         self.msg = msg
 
-    def __str__ (self):
+    def __str__(self):
         return self.msg
 
 
@@ -85,11 +95,11 @@
     inconsistent arguments.
     """
 
-    def __init__ (self, msg, option):
+    def __init__(self, msg, option):
         self.msg = msg
         self.option_id = str(option)
 
-    def __str__ (self):
+    def __str__(self):
         if self.option_id:
             return "option %s: %s" % (self.option_id, self.msg)
         else:
@@ -120,6 +130,8 @@
     formatting help; by default IndentedHelpFormatter is used.
 
     Instance attributes:
+      parser : OptionParser
+        the controlling OptionParser instance
       indent_increment : int
         the number of columns to indent per nesting level
       max_help_position : int
@@ -128,51 +140,108 @@
         the calculated starting column for option help text;
         initially the same as the maximum
       width : int
-        total number of columns for output
+        total number of columns for output (pass None to constructor for
+        this value to be taken from the $COLUMNS environment variable)
       level : int
         current indentation level
       current_indent : int
         current indentation level (in columns)
       help_width : int
         number of columns available for option help text (calculated)
+      default_tag : str
+        text to replace with each option's default value, "%default"
+        by default.  Set to false value to disable default value expansion.
+      option_strings : { Option : str }
+        maps Option instances to the snippet of help text explaining
+        the syntax of that option, e.g. "-h, --help" or
+        "-fFILE, --file=FILE"
+      _short_opt_fmt : str
+        format string controlling how short options with values are
+        printed in help text.  Must be either "%s%s" ("-fFILE") or
+        "%s %s" ("-f FILE"), because those are the two syntaxes that
+        Optik supports.
+      _long_opt_fmt : str
+        similar but for long options; must be either "%s %s" ("--file FILE")
+        or "%s=%s" ("--file=FILE").
     """
 
-    def __init__ (self,
-                  indent_increment,
-                  max_help_position,
-                  width,
-                  short_first):
+    NO_DEFAULT_VALUE = "none"
+
+    def __init__(self,
+                 indent_increment,
+                 max_help_position,
+                 width,
+                 short_first):
+        self.parser = None
         self.indent_increment = indent_increment
         self.help_position = self.max_help_position = max_help_position
+        if width is None:
+            try:
+                width = int(os.environ['COLUMNS'])
+            except (KeyError, ValueError):
+                width = 80
+            width -= 2
         self.width = width
         self.current_indent = 0
         self.level = 0
-        self.help_width = width - max_help_position
+        self.help_width = None          # computed later
         self.short_first = short_first
+        self.default_tag = "%default"
+        self.option_strings = {}
+        self._short_opt_fmt = "%s %s"
+        self._long_opt_fmt = "%s=%s"
 
-    def indent (self):
+    def set_parser(self, parser):
+        self.parser = parser
+
+    def set_short_opt_delimiter(self, delim):
+        if delim not in ("", " "):
+            raise ValueError(
+                "invalid metavar delimiter for short options: %r" % delim)
+        self._short_opt_fmt = "%s" + delim + "%s"
+
+    def set_long_opt_delimiter(self, delim):
+        if delim not in ("=", " "):
+            raise ValueError(
+                "invalid metavar delimiter for long options: %r" % delim)
+        self._long_opt_fmt = "%s" + delim + "%s"
+
+    def indent(self):
         self.current_indent += self.indent_increment
         self.level += 1
 
-    def dedent (self):
+    def dedent(self):
         self.current_indent -= self.indent_increment
         assert self.current_indent >= 0, "Indent decreased below 0."
         self.level -= 1
 
-    def format_usage (self, usage):
+    def format_usage(self, usage):
         raise NotImplementedError, "subclasses must implement"
 
-    def format_heading (self, heading):
+    def format_heading(self, heading):
         raise NotImplementedError, "subclasses must implement"
 
-    def format_description (self, description):
+    def format_description(self, description):
+        if not description:
+            return ""
         desc_width = self.width - self.current_indent
         indent = " "*self.current_indent
-        return textwrap.fill(description, desc_width,
+        return textwrap.fill(description,
+                             desc_width,
                              initial_indent=indent,
-                             subsequent_indent=indent)
+                             subsequent_indent=indent) + "\n"
 
-    def format_option (self, option):
+    def expand_default(self, option):
+        if self.parser is None or not self.default_tag:
+            return option.help
+
+        default_value = self.parser.defaults.get(option.dest)
+        if default_value is NO_DEFAULT or default_value is None:
+            default_value = self.NO_DEFAULT_VALUE
+
+        return option.help.replace(self.default_tag, str(default_value))
+
+    def format_option(self, option):
         # The help for each option consists of two parts:
         #   * the opt strings and metavars
         #     eg. ("-x", or "-fFILENAME, --file=FILENAME")
@@ -188,7 +257,7 @@
         #   -fFILENAME, --file=FILENAME
         #           read data from FILENAME
         result = []
-        opts = option.option_strings
+        opts = self.option_strings[option]
         opt_width = self.help_position - self.current_indent - 2
         if len(opts) > opt_width:
             opts = "%*s%s\n" % (self.current_indent, "", opts)
@@ -198,7 +267,8 @@
             indent_first = 0
         result.append(opts)
         if option.help:
-            help_lines = textwrap.wrap(option.help, self.help_width)
+            help_text = self.expand_default(option)
+            help_lines = textwrap.wrap(help_text, self.help_width)
             result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
             result.extend(["%*s%s\n" % (self.help_position, "", line)
                            for line in help_lines[1:]])
@@ -206,29 +276,32 @@
             result.append("\n")
         return "".join(result)
 
-    def store_option_strings (self, parser):
+    def store_option_strings(self, parser):
         self.indent()
         max_len = 0
         for opt in parser.option_list:
             strings = self.format_option_strings(opt)
-            opt.option_strings = strings
+            self.option_strings[opt] = strings
             max_len = max(max_len, len(strings) + self.current_indent)
         self.indent()
         for group in parser.option_groups:
             for opt in group.option_list:
                 strings = self.format_option_strings(opt)
-                opt.option_strings = strings
+                self.option_strings[opt] = strings
                 max_len = max(max_len, len(strings) + self.current_indent)
         self.dedent()
         self.dedent()
         self.help_position = min(max_len + 2, self.max_help_position)
+        self.help_width = self.width - self.help_position
 
-    def format_option_strings (self, option):
+    def format_option_strings(self, option):
         """Return a comma-separated list of option strings & metavariables."""
         if option.takes_value():
             metavar = option.metavar or option.dest.upper()
-            short_opts = [sopt + metavar for sopt in option._short_opts]
-            long_opts = [lopt + "=" + metavar for lopt in option._long_opts]
+            short_opts = [self._short_opt_fmt % (sopt, metavar)
+                          for sopt in option._short_opts]
+            long_opts = [self._long_opt_fmt % (lopt, metavar)
+                         for lopt in option._long_opts]
         else:
             short_opts = option._short_opts
             long_opts = option._long_opts
@@ -244,18 +317,18 @@
     """Format help with indented section bodies.
     """
 
-    def __init__ (self,
-                  indent_increment=2,
-                  max_help_position=24,
-                  width=79,
-                  short_first=1):
+    def __init__(self,
+                 indent_increment=2,
+                 max_help_position=24,
+                 width=None,
+                 short_first=1):
         HelpFormatter.__init__(
             self, indent_increment, max_help_position, width, short_first)
 
-    def format_usage (self, usage):
-        return "usage: %s\n" % usage
+    def format_usage(self, usage):
+        return _("usage: %s\n") % usage
 
-    def format_heading (self, heading):
+    def format_heading(self, heading):
         return "%*s%s:\n" % (self.current_indent, "", heading)
 
 
@@ -263,34 +336,33 @@
     """Format help with underlined section headers.
     """
 
-    def __init__ (self,
-                  indent_increment=0,
-                  max_help_position=24,
-                  width=79,
-                  short_first=0):
+    def __init__(self,
+                 indent_increment=0,
+                 max_help_position=24,
+                 width=None,
+                 short_first=0):
         HelpFormatter.__init__ (
             self, indent_increment, max_help_position, width, short_first)
 
-    def format_usage (self, usage):
-        return "%s  %s\n" % (self.format_heading("Usage"), usage)
+    def format_usage(self, usage):
+        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)
 
-    def format_heading (self, heading):
+    def format_heading(self, heading):
         return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
 
 
-_builtin_cvt = { "int" : (int, "integer"),
-                 "long" : (long, "long integer"),
-                 "float" : (float, "floating-point"),
-                 "complex" : (complex, "complex") }
+_builtin_cvt = { "int" : (int, _("integer")),
+                 "long" : (long, _("long integer")),
+                 "float" : (float, _("floating-point")),
+                 "complex" : (complex, _("complex")) }
 
-def check_builtin (option, opt, value):
+def check_builtin(option, opt, value):
     (cvt, what) = _builtin_cvt[option.type]
     try:
         return cvt(value)
     except ValueError:
         raise OptionValueError(
-            #"%s: invalid %s argument %r" % (opt, what, value))
-            "option %s: invalid %s value: %r" % (opt, what, value))
+            _("option %s: invalid %s value: %r") % (opt, what, value))
 
 def check_choice(option, opt, value):
     if value in option.choices:
@@ -298,12 +370,12 @@
     else:
         choices = ", ".join(map(repr, option.choices))
         raise OptionValueError(
-            "option %s: invalid choice: %r (choose from %s)"
+            _("option %s: invalid choice: %r (choose from %s)")
             % (opt, value, choices))
 
 # Not supplying a default is different from a default of None,
 # so we need an explicit "not supplied" value.
-NO_DEFAULT = "NO"+"DEFAULT"
+NO_DEFAULT = ("NO", "DEFAULT")
 
 
 class Option:
@@ -392,7 +464,7 @@
     TYPE_CHECKER = { "int"    : check_builtin,
                      "long"   : check_builtin,
                      "float"  : check_builtin,
-                     "complex"  : check_builtin,
+                     "complex": check_builtin,
                      "choice" : check_choice,
                    }
 
@@ -410,7 +482,7 @@
 
     # -- Constructor/initialization methods ----------------------------
 
-    def __init__ (self, *opts, **attrs):
+    def __init__(self, *opts, **attrs):
         # Set _short_opts, _long_opts attrs from 'opts' tuple.
         # Have to be set now, in case no option strings are supplied.
         self._short_opts = []
@@ -429,7 +501,7 @@
         for checker in self.CHECK_METHODS:
             checker(self)
 
-    def _check_opt_strings (self, opts):
+    def _check_opt_strings(self, opts):
         # Filter out None because early versions of Optik had exactly
         # one short option and one long option, either of which
         # could be None.
@@ -438,7 +510,7 @@
             raise TypeError("at least one option string must be supplied")
         return opts
 
-    def _set_opt_strings (self, opts):
+    def _set_opt_strings(self, opts):
         for opt in opts:
             if len(opt) < 2:
                 raise OptionError(
@@ -459,7 +531,7 @@
                         self)
                 self._long_opts.append(opt)
 
-    def _set_attrs (self, attrs):
+    def _set_attrs(self, attrs):
         for attr in self.ATTRS:
             if attrs.has_key(attr):
                 setattr(self, attr, attrs[attr])
@@ -477,13 +549,13 @@
 
     # -- Constructor validation methods --------------------------------
 
-    def _check_action (self):
+    def _check_action(self):
         if self.action is None:
             self.action = "store"
         elif self.action not in self.ACTIONS:
             raise OptionError("invalid action: %r" % self.action, self)
 
-    def _check_type (self):
+    def _check_type(self):
         if self.type is None:
             # XXX should factor out another class attr here: list of
             # actions that *require* a type
@@ -495,6 +567,12 @@
                     # No type given?  "string" is the most sensible default.
                     self.type = "string"
         else:
+            # Allow type objects as an alternative to their names.
+            if type(self.type) is type:
+                self.type = self.type.__name__
+            if self.type == "str":
+                self.type = "string"
+
             if self.type not in self.TYPES:
                 raise OptionError("invalid option type: %r" % self.type, self)
             if self.action not in self.TYPED_ACTIONS:
@@ -514,9 +592,13 @@
             raise OptionError(
                 "must not supply choices for type %r" % self.type, self)
 
-    def _check_dest (self):
-        if self.action in self.STORE_ACTIONS and self.dest is None:
-            # No destination given, and we need one for this action.
+    def _check_dest(self):
+        # No destination given, and we need one for this action.  The
+        # self.type check is for callbacks that take a value.
+        takes_value = (self.action in self.STORE_ACTIONS or
+                       self.type is not None)
+        if self.dest is None and takes_value:
+
             # Glean a destination from the first long option string,
             # or from the first short option string if no long options.
             if self._long_opts:
@@ -525,13 +607,13 @@
             else:
                 self.dest = self._short_opts[0][1]
 
-    def _check_const (self):
+    def _check_const(self):
         if self.action != "store_const" and self.const is not None:
             raise OptionError(
                 "'const' must not be supplied for action %r" % self.action,
                 self)
 
-    def _check_nargs (self):
+    def _check_nargs(self):
         if self.action in self.TYPED_ACTIONS:
             if self.nargs is None:
                 self.nargs = 1
@@ -540,7 +622,7 @@
                 "'nargs' must not be supplied for action %r" % self.action,
                 self)
 
-    def _check_callback (self):
+    def _check_callback(self):
         if self.action == "callback":
             if not callable(self.callback):
                 raise OptionError(
@@ -579,31 +661,42 @@
 
     # -- Miscellaneous methods -----------------------------------------
 
-    def __str__ (self):
+    def __str__(self):
         return "/".join(self._short_opts + self._long_opts)
 
-    def takes_value (self):
+    __repr__ = _repr
+
+    def takes_value(self):
         return self.type is not None
 
+    def get_opt_string(self):
+        if self._long_opts:
+            return self._long_opts[0]
+        else:
+            return self._short_opts[0]
+
 
     # -- Processing methods --------------------------------------------
 
-    def check_value (self, opt, value):
+    def check_value(self, opt, value):
         checker = self.TYPE_CHECKER.get(self.type)
         if checker is None:
             return value
         else:
             return checker(self, opt, value)
 
-    def process (self, opt, value, values, parser):
+    def convert_value(self, opt, value):
+        if value is not None:
+            if self.nargs == 1:
+                return self.check_value(opt, value)
+            else:
+                return tuple([self.check_value(opt, v) for v in value])
+
+    def process(self, opt, value, values, parser):
 
         # First, convert the value(s) to the right type.  Howl if any
         # value(s) are bogus.
-        if value is not None:
-            if self.nargs == 1:
-                value = self.check_value(opt, value)
-            else:
-                value = tuple([self.check_value(opt, v) for v in value])
+        value = self.convert_value(opt, value)
 
         # And then take whatever action is expected of us.
         # This is a separate method to make life easier for
@@ -611,7 +704,7 @@
         return self.take_action(
             self.action, self.dest, opt, value, values, parser)
 
-    def take_action (self, action, dest, opt, value, values, parser):
+    def take_action(self, action, dest, opt, value, values, parser):
         if action == "store":
             setattr(values, dest, value)
         elif action == "store_const":
@@ -642,33 +735,44 @@
 # class Option
 
 
-def get_prog_name ():
-    return os.path.basename(sys.argv[0])
-
-
 SUPPRESS_HELP = "SUPPRESS"+"HELP"
 SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
 
-STD_HELP_OPTION = Option("-h", "--help",
-                         action="help",
-                         help="show this help message and exit")
-STD_VERSION_OPTION = Option("--version",
-                            action="version",
-                            help="show program's version number and exit")
+# For compatibility with Python 2.2
+try:
+    True, False
+except NameError:
+    (True, False) = (1, 0)
+try:
+    basestring
+except NameError:
+    basestring = (str, unicode)
 
 
 class Values:
 
-    def __init__ (self, defaults=None):
+    def __init__(self, defaults=None):
         if defaults:
             for (attr, val) in defaults.items():
                 setattr(self, attr, val)
 
-    def __repr__ (self):
-        return ("<%s at 0x%x: %r>"
-                % (self.__class__.__name__, id(self), self.__dict__))
+    def __str__(self):
+        return str(self.__dict__)
 
-    def _update_careful (self, dict):
+    __repr__ = _repr
+
+    def __eq__(self, other):
+        if isinstance(other, Values):
+            return self.__dict__ == other.__dict__
+        elif isinstance(other, dict):
+            return self.__dict__ == other
+        else:
+            return false
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def _update_careful(self, dict):
         """
         Update the option values from an arbitrary dictionary, but only
         use keys from dict that already have a corresponding attribute
@@ -681,7 +785,7 @@
                 if dval is not None:
                     setattr(self, attr, dval)
 
-    def _update_loose (self, dict):
+    def _update_loose(self, dict):
         """
         Update the option values from an arbitrary dictionary,
         using all keys from the dictionary regardless of whether
@@ -689,7 +793,7 @@
         """
         self.__dict__.update(dict)
 
-    def _update (self, dict, mode):
+    def _update(self, dict, mode):
         if mode == "careful":
             self._update_careful(dict)
         elif mode == "loose":
@@ -697,17 +801,17 @@
         else:
             raise ValueError, "invalid update mode: %r" % mode
 
-    def read_module (self, modname, mode="careful"):
+    def read_module(self, modname, mode="careful"):
         __import__(modname)
         mod = sys.modules[modname]
         self._update(vars(mod), mode)
 
-    def read_file (self, filename, mode="careful"):
+    def read_file(self, filename, mode="careful"):
         vars = {}
         execfile(filename, vars)
         self._update(vars, mode)
 
-    def ensure_value (self, attr, value):
+    def ensure_value(self, attr, value):
         if not hasattr(self, attr) or getattr(self, attr) is None:
             setattr(self, attr, value)
         return getattr(self, attr)
@@ -745,7 +849,7 @@
 
     """
 
-    def __init__ (self, option_class, conflict_handler, description):
+    def __init__(self, option_class, conflict_handler, description):
         # Initialize the option list and related data structures.
         # This method must be provided by subclasses, and it must
         # initialize at least the following instance attributes:
@@ -756,7 +860,7 @@
         self.set_conflict_handler(conflict_handler)
         self.set_description(description)
 
-    def _create_option_mappings (self):
+    def _create_option_mappings(self):
         # For use by OptionParser constructor -- create the master
         # option mappings used by this OptionParser and all
         # OptionGroups that it owns.
@@ -765,25 +869,28 @@
         self.defaults = {}              # maps option dest -> default value
 
 
-    def _share_option_mappings (self, parser):
+    def _share_option_mappings(self, parser):
         # For use by OptionGroup constructor -- use shared option
         # mappings from the OptionParser that owns this OptionGroup.
         self._short_opt = parser._short_opt
         self._long_opt = parser._long_opt
         self.defaults = parser.defaults
 
-    def set_conflict_handler (self, handler):
+    def set_conflict_handler(self, handler):
         if handler not in ("ignore", "error", "resolve"):
             raise ValueError, "invalid conflict_resolution value %r" % handler
         self.conflict_handler = handler
 
-    def set_description (self, description):
+    def set_description(self, description):
         self.description = description
 
+    def get_description(self):
+        return self.description
+
 
     # -- Option-adding methods -----------------------------------------
 
-    def _check_conflict (self, option):
+    def _check_conflict(self, option):
         conflict_opts = []
         for opt in option._short_opts:
             if self._short_opt.has_key(opt):
@@ -812,7 +919,7 @@
                     if not (c_option._short_opts or c_option._long_opts):
                         c_option.container.option_list.remove(c_option)
 
-    def add_option (self, *args, **kwargs):
+    def add_option(self, *args, **kwargs):
         """add_option(Option)
            add_option(opt_str, ..., kwarg=val, ...)
         """
@@ -842,21 +949,21 @@
 
         return option
 
-    def add_options (self, option_list):
+    def add_options(self, option_list):
         for option in option_list:
             self.add_option(option)
 
     # -- Option query/removal methods ----------------------------------
 
-    def get_option (self, opt_str):
+    def get_option(self, opt_str):
         return (self._short_opt.get(opt_str) or
                 self._long_opt.get(opt_str))
 
-    def has_option (self, opt_str):
+    def has_option(self, opt_str):
         return (self._short_opt.has_key(opt_str) or
                 self._long_opt.has_key(opt_str))
 
-    def remove_option (self, opt_str):
+    def remove_option(self, opt_str):
         option = self._short_opt.get(opt_str)
         if option is None:
             option = self._long_opt.get(opt_str)
@@ -872,7 +979,7 @@
 
     # -- Help-formatting methods ---------------------------------------
 
-    def format_option_help (self, formatter):
+    def format_option_help(self, formatter):
         if not self.option_list:
             return ""
         result = []
@@ -881,38 +988,36 @@
                 result.append(formatter.format_option(option))
         return "".join(result)
 
-    def format_description (self, formatter):
-        if self.description:
-            return formatter.format_description(self.description)
-        else:
-            return ""
+    def format_description(self, formatter):
+        return formatter.format_description(self.get_description())
 
-    def format_help (self, formatter):
+    def format_help(self, formatter):
+        result = []
         if self.description:
-            desc = self.format_description(formatter) + "\n"
-        else:
-            desc = ""
-        return desc + self.format_option_help(formatter)
+            result.append(self.format_description(formatter))
+        if self.option_list:
+            result.append(self.format_option_help(formatter))
+        return "\n".join(result)
 
 
 class OptionGroup (OptionContainer):
 
-    def __init__ (self, parser, title, description=None):
+    def __init__(self, parser, title, description=None):
         self.parser = parser
         OptionContainer.__init__(
             self, parser.option_class, parser.conflict_handler, description)
         self.title = title
 
-    def _create_option_list (self):
+    def _create_option_list(self):
         self.option_list = []
         self._share_option_mappings(self.parser)
 
-    def set_title (self, title):
+    def set_title(self, title):
         self.title = title
 
     # -- Help-formatting methods ---------------------------------------
 
-    def format_help (self, formatter):
+    def format_help(self, formatter):
         result = formatter.format_heading(self.title)
         formatter.indent()
         result += OptionContainer.format_help(self, formatter)
@@ -937,7 +1042,12 @@
         the name of the current program (to override
         os.path.basename(sys.argv[0])).
 
-      allow_interspersed_args : boolean = true
+      option_groups : [OptionGroup]
+        list of option groups in this parser (option groups are
+        irrelevant for parsing the command-line, but very useful
+        for generating help)
+
+      allow_interspersed_args : bool = true
         if true, positional arguments may be interspersed with options.
         Assuming -a and -b each take a single argument, the command-line
           -ablah foo bar -bboo baz
@@ -950,6 +1060,14 @@
         Python's getopt module, Perl's Getopt::Std, and other argument-
         parsing libraries, but it is generally annoying to users.)
 
+      process_default_values : bool = true
+        if true, option default values are processed similarly to option
+        values from the command line: that is, they are passed to the
+        type-checking function for the option's type (as long as the
+        default value is a string).  (This really only matters if you
+        have defined custom types; see SF bug #955889.)  Set it to false
+        to restore the behaviour of Optik 1.4.1 and earlier.
+
       rargs : [string]
         the argument list currently being parsed.  Only set when
         parse_args() is active, and continually trimmed down as
@@ -972,30 +1090,32 @@
 
     standard_option_list = []
 
-    def __init__ (self,
-                  usage=None,
-                  option_list=None,
-                  option_class=Option,
-                  version=None,
-                  conflict_handler="error",
-                  description=None,
-                  formatter=None,
-                  add_help_option=1,
-                  prog=None):
+    def __init__(self,
+                 usage=None,
+                 option_list=None,
+                 option_class=Option,
+                 version=None,
+                 conflict_handler="error",
+                 description=None,
+                 formatter=None,
+                 add_help_option=True,
+                 prog=None):
         OptionContainer.__init__(
             self, option_class, conflict_handler, description)
         self.set_usage(usage)
         self.prog = prog
         self.version = version
-        self.allow_interspersed_args = 1
+        self.allow_interspersed_args = True
+        self.process_default_values = True
         if formatter is None:
             formatter = IndentedHelpFormatter()
         self.formatter = formatter
+        self.formatter.set_parser(self)
 
         # Populate the option list; initial sources are the
         # standard_option_list class attribute, the 'option_list'
-        # argument, and the STD_VERSION_OPTION (if 'version' supplied)
-        # and STD_HELP_OPTION globals.
+        # argument, and (if applicable) the _add_version_option() and
+        # _add_help_option() methods.
         self._populate_option_list(option_list,
                                    add_help=add_help_option)
 
@@ -1004,65 +1124,90 @@
     # -- Private methods -----------------------------------------------
     # (used by our or OptionContainer's constructor)
 
-    def _create_option_list (self):
+    def _create_option_list(self):
         self.option_list = []
         self.option_groups = []
         self._create_option_mappings()
 
-    def _populate_option_list (self, option_list, add_help=1):
+    def _add_help_option(self):
+        self.add_option("-h", "--help",
+                        action="help",
+                        help=_("show this help message and exit"))
+
+    def _add_version_option(self):
+        self.add_option("--version",
+                        action="version",
+                        help=_("show program's version number and exit"))
+
+    def _populate_option_list(self, option_list, add_help=True):
         if self.standard_option_list:
             self.add_options(self.standard_option_list)
         if option_list:
             self.add_options(option_list)
         if self.version:
-            self.add_option(STD_VERSION_OPTION)
+            self._add_version_option()
         if add_help:
-            self.add_option(STD_HELP_OPTION)
+            self._add_help_option()
 
-    def _init_parsing_state (self):
+    def _init_parsing_state(self):
         # These are set in parse_args() for the convenience of callbacks.
         self.rargs = None
         self.largs = None
         self.values = None
 
-    def _get_prog_name(self):
-        if self.prog:
-            return self.prog
-        else:
-            return get_prog_name()
 
     # -- Simple modifier methods ---------------------------------------
 
-    def set_usage (self, usage):
+    def set_usage(self, usage):
         if usage is None:
-            self.usage = "%prog [options]"
+            self.usage = _("%prog [options]")
         elif usage is SUPPRESS_USAGE:
             self.usage = None
-        elif usage.lower().startswith("usage: "):
-            # for backwards compatibility with Optik 1.3 and earlier
+        # For backwards compatibility with Optik 1.3 and earlier.
+        elif usage.startswith("usage:" + " "):
             self.usage = usage[7:]
         else:
             self.usage = usage
 
-    def enable_interspersed_args (self):
-        self.allow_interspersed_args = 1
+    def enable_interspersed_args(self):
+        self.allow_interspersed_args = True
 
-    def disable_interspersed_args (self):
-        self.allow_interspersed_args = 0
+    def disable_interspersed_args(self):
+        self.allow_interspersed_args = False
 
-    def set_default (self, dest, value):
+    def set_process_default_values(self, process):
+        self.process_default_values = process
+
+    def set_default(self, dest, value):
         self.defaults[dest] = value
 
-    def set_defaults (self, **kwargs):
+    def set_defaults(self, **kwargs):
         self.defaults.update(kwargs)
 
-    def get_default_values (self):
-        return Values(self.defaults)
+    def _get_all_options(self):
+        options = self.option_list[:]
+        for group in self.option_groups:
+            options.extend(group.option_list)
+        return options
+
+    def get_default_values(self):
+        if not self.process_default_values:
+            # Old, pre-Optik 1.5 behaviour.
+            return Values(self.defaults)
+
+        defaults = self.defaults.copy()
+        for option in self._get_all_options():
+            default = defaults.get(option.dest)
+            if isinstance(default, basestring):
+                opt_str = option.get_opt_string()
+                defaults[option.dest] = option.check_value(opt_str, default)
+
+        return Values(defaults)
 
 
     # -- OptionGroup methods -------------------------------------------
 
-    def add_option_group (self, *args, **kwargs):
+    def add_option_group(self, *args, **kwargs):
         # XXX lots of overlap with OptionContainer.add_option()
         if type(args[0]) is types.StringType:
             group = OptionGroup(self, *args, **kwargs)
@@ -1078,7 +1223,7 @@
         self.option_groups.append(group)
         return group
 
-    def get_option_group (self, opt_str):
+    def get_option_group(self, opt_str):
         option = (self._short_opt.get(opt_str) or
                   self._long_opt.get(opt_str))
         if option and option.container is not self:
@@ -1088,13 +1233,13 @@
 
     # -- Option-parsing methods ----------------------------------------
 
-    def _get_args (self, args):
+    def _get_args(self, args):
         if args is None:
             return sys.argv[1:]
         else:
             return args[:]              # don't modify caller's list
 
-    def parse_args (self, args=None, values=None):
+    def parse_args(self, args=None, values=None):
         """
         parse_args(args : [string] = sys.argv[1:],
                    values : Values = None)
@@ -1133,7 +1278,7 @@
         args = largs + rargs
         return self.check_values(values, args)
 
-    def check_values (self, values, args):
+    def check_values(self, values, args):
         """
         check_values(values : Values, args : [string])
         -> (values : Values, args : [string])
@@ -1146,7 +1291,7 @@
         """
         return (values, args)
 
-    def _process_args (self, largs, rargs, values):
+    def _process_args(self, largs, rargs, values):
         """_process_args(largs : [string],
                          rargs : [string],
                          values : Values)
@@ -1197,7 +1342,7 @@
         # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
         # not a very interesting subset!
 
-    def _match_long_opt (self, opt):
+    def _match_long_opt(self, opt):
         """_match_long_opt(opt : string) -> string
 
         Determine which long option string 'opt' matches, ie. which one
@@ -1206,7 +1351,7 @@
         """
         return _match_abbrev(opt, self._long_opt)
 
-    def _process_long_opt (self, rargs, values):
+    def _process_long_opt(self, rargs, values):
         arg = rargs.pop(0)
 
         # Value explicitly attached to arg?  Pretend it's the next
@@ -1214,10 +1359,10 @@
         if "=" in arg:
             (opt, next_arg) = arg.split("=", 1)
             rargs.insert(0, next_arg)
-            had_explicit_value = 1
+            had_explicit_value = True
         else:
             opt = arg
-            had_explicit_value = 0
+            had_explicit_value = False
 
         opt = self._match_long_opt(opt)
         option = self._long_opt[opt]
@@ -1225,9 +1370,9 @@
             nargs = option.nargs
             if len(rargs) < nargs:
                 if nargs == 1:
-                    self.error("%s option requires a value" % opt)
+                    self.error(_("%s option requires an argument") % opt)
                 else:
-                    self.error("%s option requires %d values"
+                    self.error(_("%s option requires %d arguments")
                                % (opt, nargs))
             elif nargs == 1:
                 value = rargs.pop(0)
@@ -1236,16 +1381,16 @@
                 del rargs[0:nargs]
 
         elif had_explicit_value:
-            self.error("%s option does not take a value" % opt)
+            self.error(_("%s option does not take a value") % opt)
 
         else:
             value = None
 
         option.process(opt, value, values, self)
 
-    def _process_short_opts (self, rargs, values):
+    def _process_short_opts(self, rargs, values):
         arg = rargs.pop(0)
-        stop = 0
+        stop = False
         i = 1
         for ch in arg[1:]:
             opt = "-" + ch
@@ -1253,20 +1398,20 @@
             i += 1                      # we have consumed a character
 
             if not option:
-                self.error("no such option: %s" % opt)
+                self.error(_("no such option: %s") % opt)
             if option.takes_value():
                 # Any characters left in arg?  Pretend they're the
                 # next arg, and stop consuming characters of arg.
                 if i < len(arg):
                     rargs.insert(0, arg[i:])
-                    stop = 1
+                    stop = True
 
                 nargs = option.nargs
                 if len(rargs) < nargs:
                     if nargs == 1:
-                        self.error("%s option requires a value" % opt)
+                        self.error(_("%s option requires an argument") % opt)
                     else:
-                        self.error("%s option requires %s values"
+                        self.error(_("%s option requires %d arguments")
                                    % (opt, nargs))
                 elif nargs == 1:
                     value = rargs.pop(0)
@@ -1285,7 +1430,19 @@
 
     # -- Feedback methods ----------------------------------------------
 
-    def error (self, msg):
+    def get_prog_name(self):
+        if self.prog is None:
+            return os.path.basename(sys.argv[0])
+        else:
+            return self.prog
+
+    def expand_prog_name(self, s):
+        return s.replace("%prog", self.get_prog_name())
+
+    def get_description(self):
+        return self.expand_prog_name(self.description)
+
+    def error(self, msg):
         """error(msg : string)
 
         Print a usage message incorporating 'msg' to stderr and exit.
@@ -1293,16 +1450,17 @@
         should either exit or raise an exception.
         """
         self.print_usage(sys.stderr)
-        sys.exit("%s: error: %s" % (self._get_prog_name(), msg))
+        sys.stderr.write("%s: error: %s\n" % (self.get_prog_name(), msg))
+        sys.exit(2)                     # command-line usage error
 
-    def get_usage (self):
+    def get_usage(self):
         if self.usage:
             return self.formatter.format_usage(
-                self.usage.replace("%prog", self._get_prog_name()))
+                self.expand_prog_name(self.usage))
         else:
             return ""
 
-    def print_usage (self, file=None):
+    def print_usage(self, file=None):
         """print_usage(file : file = stdout)
 
         Print the usage message for the current program (self.usage) to
@@ -1314,13 +1472,13 @@
         if self.usage:
             print >>file, self.get_usage()
 
-    def get_version (self):
+    def get_version(self):
         if self.version:
-            return self.version.replace("%prog", self._get_prog_name())
+            return self.expand_prog_name(self.version)
         else:
             return ""
 
-    def print_version (self, file=None):
+    def print_version(self, file=None):
         """print_version(file : file = stdout)
 
         Print the version message for this program (self.version) to
@@ -1331,12 +1489,12 @@
         if self.version:
             print >>file, self.get_version()
 
-    def format_option_help (self, formatter=None):
+    def format_option_help(self, formatter=None):
         if formatter is None:
             formatter = self.formatter
         formatter.store_option_strings(self)
         result = []
-        result.append(formatter.format_heading("options"))
+        result.append(formatter.format_heading(_("options")))
         formatter.indent()
         if self.option_list:
             result.append(OptionContainer.format_option_help(self, formatter))
@@ -1348,7 +1506,7 @@
         # Drop the last "\n", or the header if no options or option groups:
         return "".join(result[:-1])
 
-    def format_help (self, formatter=None):
+    def format_help(self, formatter=None):
         if formatter is None:
             formatter = self.formatter
         result = []
@@ -1359,7 +1517,7 @@
         result.append(self.format_option_help(formatter))
         return "".join(result)
 
-    def print_help (self, file=None):
+    def print_help(self, file=None):
         """print_help(file : file = stdout)
 
         Print an extended help message, listing all options and any
@@ -1372,7 +1530,7 @@
 # class OptionParser
 
 
-def _match_abbrev (s, wordmap):
+def _match_abbrev(s, wordmap):
     """_match_abbrev(s : string, wordmap : {string : Option}) -> string
 
     Return the string key in 'wordmap' for which 's' is an unambiguous
@@ -1390,10 +1548,10 @@
         if len(possibilities) == 1:
             return possibilities[0]
         elif not possibilities:
-            raise BadOptionError("no such option: %s" % s)
+            raise BadOptionError(_("no such option: %s") % s)
         else:
             # More than one possible completion: ambiguous prefix.
-            raise BadOptionError("ambiguous option: %s (%s?)"
+            raise BadOptionError(_("ambiguous option: %s (%s?)")
                                  % (s, ", ".join(possibilities)))
 
 
diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py
index 37e229c..b850cec 100644
--- a/Lib/test/test_optparse.py
+++ b/Lib/test/test_optparse.py
@@ -20,14 +20,7 @@
 from optparse import make_option, Option, IndentedHelpFormatter, \
      TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, \
      SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, \
-     BadOptionError, OptionValueError
-from optparse import _match_abbrev
-
-# Do the right thing with boolean values for all known Python versions.
-try:
-    True, False
-except NameError:
-    (True, False) = (1, 0)
+     BadOptionError, OptionValueError, _match_abbrev
 
 class BaseTest(unittest.TestCase):
     def assertParseOK(self, args, expected_opts, expected_positional_args):
@@ -60,50 +53,62 @@
 
         return (options, positional_args)
 
-    def assertRaises(self, func, expected_exception, expected_output,
-                     get_output=None,
-                     funcargs=[], funckwargs={}):
+    def assertRaises(self,
+                     func,
+                     args,
+                     kwargs,
+                     expected_exception,
+                     expected_output,
+                     get_output=None, 
+                     exact_match=False):
         """Assert the expected exception is raised when calling a function.
 
         Also check whether the right error message is given for a given error.
 
-        Keyword arguments:
-        func -- The function to be called.
-        expected_exception -- The exception that should be raised.
-        expected_output -- The output we expect to see.
-        get_output -- The function to call to get the output.
-        funcargs -- The arguments `func` should be called with.
-        funckwargs -- The keyword arguments `func` should be called with.
+        Arguments:
+          func -- the function to call
+          args -- positional arguments to `func`
+          kwargs -- keyword arguments to `func`
+          expected_exception -- exception that should be raised
+          expected_output -- output we expect to see
+          get_output -- function to call to get the output
+          exact_match -- whether output must exactly match expected output,
+            or merely contain it
 
         Returns the exception raised for further testing.
         """
+        if args is None:
+            args = ()
+        if kwargs is None:
+            kwargs = {}
         if get_output is None:
             get_output = self.exception
 
         try:
-            out = func(*funcargs, **funckwargs)
+            out = func(*args, **kwargs)
         except expected_exception, err:
-            output = get_output(err)
+            actual_output = get_output(err)
 
-            self.failUnless(output.find(expected_output) != -1,
-                            """
-Message was:
-%(output)s
-Should contain:
-%(expected_output)s
-Function called:
-%(func)s
-With args/kwargs:
-%(funcargs)s/%(funckwargs)s""" % locals())
+            if exact_match:
+                match = actual_output == expected_exception
+            else:
+                match = actual_output.find(expected_output) != -1
+
+            self.assert_(match,
+                         """mismatched output
+expected output:
+'''%(expected_output)s'''
+actual output:
+'''%(actual_output)s'''
+""" % locals())
 
             return err
         else:
-            self.fail("""
-No %(expected_exception)s raised.
-Function called:
-%(func)s
-With args/kwargs:
-%(funcargs)s/%(funckwargs)s""" % locals ())
+            self.fail("""expected exception %(expected_exception)s not raised
+called %(func)r
+with args %(args)r
+and kwargs %(kwargs)r
+""" % locals ())
 
     # -- Functions to be used as the get_output argument to assertRaises ------
 
@@ -113,23 +118,38 @@
     def redirected_stdout(self, err):
         return sys.stdout.getvalue()
 
+    def redirected_stderr(self, err):
+        return sys.stderr.getvalue()
+
     # -- Assertions used in more than one class --------------------
 
     def assertParseFail(self, cmdline_args, expected_output):
         """Assert the parser fails with the expected message."""
-        self.assertRaises(self.parser.parse_args, SystemExit, expected_output,
-                          funcargs=[cmdline_args])
+        sys.stderr = StringIO()
+        self.assertRaises(self.parser.parse_args, (cmdline_args,), None,
+                          SystemExit, expected_output,
+                          self.redirected_stderr)
+        sys.stderr = sys.__stderr__
 
     def assertStdoutEquals(self, cmdline_args, expected_output):
         """Assert the parser prints the expected output on stdout."""
         sys.stdout = StringIO()
-        self.assertRaises(self.parser.parse_args, SystemExit, expected_output,
-                          self.redirected_stdout, [cmdline_args])
+        self.assertRaises(self.parser.parse_args, (cmdline_args,), None,
+                          SystemExit, expected_output,
+                          self.redirected_stdout)
         sys.stdout = sys.__stdout__
 
     def assertTypeError(self, func, expected_output, *args):
         """Assert a TypeError is raised when executing func."""
-        self.assertRaises(func, TypeError, expected_output, funcargs=args)
+        self.assertRaises(func, args, None, TypeError, expected_output)
+
+    def assertHelp(self, parser, expected_help):
+        actual_help = parser.format_help()
+        if actual_help != expected_help:
+            raise self.failureException(
+                'help text failure; expected:\n"' +
+                expected_help + '"; got:\n"' +
+                actual_help + '"\n')
 
 # -- Test make_option() aka Option -------------------------------------
 
@@ -142,8 +162,8 @@
         self.parser = OptionParser(usage=SUPPRESS_USAGE)
 
     def assertOptionError(self, expected_output, args=[], kwargs={}):
-        self.assertRaises(make_option, OptionError, expected_output,
-                          funcargs=args, funckwargs=kwargs)
+        self.assertRaises(make_option, args, kwargs,
+                          OptionError, expected_output)
 
     def test_opt_string_empty(self):
         self.assertTypeError(make_option,
@@ -175,6 +195,8 @@
     def test_type_invalid(self):
         self.assertOptionError("invalid option type: 'foo'",
                                ["-b"], {'type': 'foo'})
+        self.assertOptionError("invalid option type: 'tuple'",
+                               ["-b"], {'type': tuple})
 
     def test_no_type_for_action(self):
         self.assertOptionError("must not supply a type for action 'count'",
@@ -304,8 +326,204 @@
         self.assert_removed()
 
     def test_remove_nonexistent(self):
-        self.assertRaises(self.parser.remove_option, ValueError,
-                          "no such option 'foo'", funcargs=['foo'])
+        self.assertRaises(self.parser.remove_option, ('foo',), None,
+                          ValueError, "no such option 'foo'")
+
+class TestTypeAliases(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser()
+
+    def test_type_aliases(self):
+        self.parser.add_option("-x", type=int)
+        self.parser.add_option("-s", type=str)
+        self.parser.add_option("-t", type="str")
+        self.assertEquals(self.parser.get_option("-x").type, "int")
+        self.assertEquals(self.parser.get_option("-s").type, "string")
+        self.assertEquals(self.parser.get_option("-t").type, "string")
+        
+
+# Custom type for testing processing of default values.
+_time_units = { 's' : 1, 'm' : 60, 'h' : 60*60, 'd' : 60*60*24 }
+
+def _check_duration(option, opt, value):
+    try:
+        if value[-1].isdigit():
+            return int(value)
+        else:
+            return int(value[:-1]) * _time_units[value[-1]]
+    except ValueError, IndexError:
+        raise OptionValueError(
+            'option %s: invalid duration: %r' % (opt, value))
+
+class DurationOption(Option):
+    TYPES = Option.TYPES + ('duration',)
+    TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
+    TYPE_CHECKER['duration'] = _check_duration
+
+class TestDefaultValues(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser()
+        self.parser.add_option("-v", "--verbose", default=True)
+        self.parser.add_option("-q", "--quiet", dest='verbose')
+        self.parser.add_option("-n", type="int", default=37)
+        self.parser.add_option("-m", type="int")
+        self.parser.add_option("-s", default="foo")
+        self.parser.add_option("-t")
+        self.parser.add_option("-u", default=None)
+        self.expected = { 'verbose': True,
+                          'n': 37,
+                          'm': None,
+                          's': "foo",
+                          't': None,
+                          'u': None }
+
+    def test_basic_defaults(self):
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+    def test_mixed_defaults_post(self):
+        self.parser.set_defaults(n=42, m=-100)
+        self.expected.update({'n': 42, 'm': -100})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+    def test_mixed_defaults_pre(self):
+        self.parser.set_defaults(x="barf", y="blah")
+        self.parser.add_option("-x", default="frob")
+        self.parser.add_option("-y")
+
+        self.expected.update({'x': "frob", 'y': "blah"})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+        self.parser.remove_option("-y")
+        self.parser.add_option("-y", default=None)
+        self.expected.update({'y': None})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+    def test_process_default(self):
+        self.parser.option_class = DurationOption
+        self.parser.add_option("-d", type="duration", default=300)
+        self.parser.add_option("-e", type="duration", default="6m")
+        self.parser.set_defaults(n="42")
+        self.expected.update({'d': 300, 'e': 360, 'n': 42})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+        self.parser.set_process_default_values(False)
+        self.expected.update({'d': 300, 'e': "6m", 'n': "42"})
+        self.assertEqual(self.parser.get_default_values(), self.expected)
+
+
+class TestProgName(BaseTest):
+    """
+    Test that %prog expands to the right thing in usage, version,
+    and help strings.
+    """
+
+    def assertUsage(self, parser, expected_usage):
+        self.assertEqual(parser.get_usage(), expected_usage)
+
+    def assertVersion(self, parser, expected_version):
+        self.assertEqual(parser.get_version(), expected_version)
+
+
+    def test_default_progname(self):
+        # Make sure that program name taken from sys.argv[0] by default.
+        sys.argv[0] = "/foo/bar/baz.py"
+        parser = OptionParser("usage: %prog ...", version="%prog 1.2")
+        expected_usage = "usage: baz.py ...\n"
+        self.assertUsage(parser, expected_usage)
+        self.assertVersion(parser, "baz.py 1.2")
+        self.assertHelp(parser,
+            expected_usage + "\n" +
+            "options:\n"
+            "  --version   show program's version number and exit\n"
+            "  -h, --help  show this help message and exit\n")
+
+    def test_custom_progname(self):
+        parser = OptionParser(prog="thingy",
+                              version="%prog 0.1",
+                              usage="%prog arg arg")
+        parser.remove_option("-h")
+        parser.remove_option("--version")
+        expected_usage = "usage: thingy arg arg\n"
+        self.assertUsage(parser, expected_usage)
+        self.assertVersion(parser, "thingy 0.1")
+        self.assertHelp(parser, expected_usage + "\n")
+
+
+class TestExpandDefaults(BaseTest):
+    def setUp(self):
+        self.parser = OptionParser(prog="test")
+        self.help_prefix = """\
+usage: test [options]
+
+options:
+  -h, --help            show this help message and exit
+"""
+        self.file_help = "read from FILE [default: %default]"
+        self.expected_help_file = self.help_prefix + \
+            "  -f FILE, --file=FILE  read from FILE [default: foo.txt]\n"
+        self.expected_help_none = self.help_prefix + \
+            "  -f FILE, --file=FILE  read from FILE [default: none]\n"
+
+    def test_option_default(self):
+        self.parser.add_option("-f", "--file",
+                               default="foo.txt",
+                               help=self.file_help)
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_parser_default_1(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.parser.set_default('file', "foo.txt")
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_parser_default_2(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.parser.set_defaults(file="foo.txt")
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_no_default(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.assertHelp(self.parser, self.expected_help_none)
+
+    def test_default_none_1(self):
+        self.parser.add_option("-f", "--file",
+                               default=None,
+                               help=self.file_help)
+        self.assertHelp(self.parser, self.expected_help_none)
+        
+    def test_default_none_2(self):
+        self.parser.add_option("-f", "--file",
+                               help=self.file_help)
+        self.parser.set_defaults(file=None)
+        self.assertHelp(self.parser, self.expected_help_none)
+
+    def test_float_default(self):
+        self.parser.add_option(
+            "-p", "--prob",
+            help="blow up with probability PROB [default: %default]")
+        self.parser.set_defaults(prob=0.43)
+        expected_help = self.help_prefix + \
+            "  -p PROB, --prob=PROB  blow up with probability PROB [default: 0.43]\n"
+        self.assertHelp(self.parser, expected_help)
+
+    def test_alt_expand(self):
+        self.parser.add_option("-f", "--file",
+                               default="foo.txt",
+                               help="read from FILE [default: *DEFAULT*]")
+        self.parser.formatter.default_tag = "*DEFAULT*"
+        self.assertHelp(self.parser, self.expected_help_file)
+
+    def test_no_expand(self):
+        self.parser.add_option("-f", "--file",
+                               default="foo.txt",
+                               help="read from %default file")
+        self.parser.formatter.default_tag = None
+        expected_help = self.help_prefix + \
+            "  -f FILE, --file=FILE  read from %default file\n"
+        self.assertHelp(self.parser, expected_help)
+
 
 # -- Test parser.parse_args() ------------------------------------------
 
@@ -318,7 +536,7 @@
         self.parser = OptionParser(usage=SUPPRESS_USAGE, option_list=options)
 
     def test_required_value(self):
-        self.assertParseFail(["-a"], "-a option requires a value")
+        self.assertParseFail(["-a"], "-a option requires an argument")
 
     def test_invalid_integer(self):
         self.assertParseFail(["-b", "5x"],
@@ -580,7 +798,7 @@
 
     def test_nargs_required_values(self):
         self.assertParseFail(["--point", "1.0", "3.5"],
-                             "--point option requires 3 values")
+                             "--point option requires 3 arguments")
 
 class TestNArgsAppend(BaseTest):
     def setUp(self):
@@ -597,7 +815,7 @@
 
     def test_nargs_append_required_values(self):
         self.assertParseFail(["-f4,3"],
-                             "-f option requires 2 values")
+                             "-f option requires 2 arguments")
 
     def test_nargs_append_simple(self):
         self.assertParseOK(["--foo=3", "4"],
@@ -612,22 +830,6 @@
         self.assertStdoutEquals(["--version"], "bar 0.1\n")
         sys.argv[0] = oldargv
 
-    def test_version_with_prog_keyword(self):
-        oldargv = sys.argv[0]
-        sys.argv[0] = "./foo/bar"
-        self.parser = OptionParser(usage=SUPPRESS_USAGE, version="%prog 0.1",
-                                   prog="splat")
-        self.assertStdoutEquals(["--version"], "splat 0.1\n")
-        sys.argv[0] = oldargv
-
-    def test_version_with_prog_attribute(self):
-        oldargv = sys.argv[0]
-        sys.argv[0] = "./foo/bar"
-        self.parser = OptionParser(usage=SUPPRESS_USAGE, version="%prog 0.1")
-        self.parser.prog = "splat"
-        self.assertStdoutEquals(["--version"], "splat 0.1\n")
-        sys.argv[0] = oldargv
-
     def test_no_version(self):
         self.parser = OptionParser(usage=SUPPRESS_USAGE)
         self.assertParseFail(["--version"],
@@ -673,8 +875,8 @@
     def test_add_group_wrong_parser(self):
         group = OptionGroup(self.parser, "Spam")
         group.parser = OptionParser()
-        self.assertRaises(self.parser.add_option_group, ValueError,
-                          "invalid OptionGroup (wrong parser)", funcargs=[group])
+        self.assertRaises(self.parser.add_option_group, (group,), None,
+                          ValueError, "invalid OptionGroup (wrong parser)")
 
     def test_group_manipulate(self):
         group = self.parser.add_option_group("Group 2",
@@ -794,7 +996,22 @@
                            {'filename': "foo", 'x': 42},
                            [])
 
-class TestCallBackExtraArgs(BaseTest):
+    def test_callback_help(self):
+        # This test was prompted by SF bug #960515 -- the point is
+        # not to inspect the help text, just to make sure that
+        # format_help() doesn't crash.
+        parser = OptionParser(usage=SUPPRESS_USAGE)
+        parser.remove_option("-h")
+        parser.add_option("-t", "--test", action="callback",
+                          callback=lambda: None, type="string",
+                          help="foo")
+
+        expected_help = ("options:\n"
+                         "  -t TEST, --test=TEST  foo\n")
+        self.assertHelp(parser, expected_help)
+
+
+class TestCallbackExtraArgs(BaseTest):
     def setUp(self):
         options = [make_option("-p", "--point", action="callback",
                                callback=self.process_tuple,
@@ -819,7 +1036,7 @@
                            {'points': [(1,2,3), (4,5,6)]},
                            [])
 
-class TestCallBackMeddleArgs(BaseTest):
+class TestCallbackMeddleArgs(BaseTest):
     def setUp(self):
         options = [make_option(str(x), action="callback",
                                callback=self.process_n, dest='things')
@@ -848,7 +1065,7 @@
                            {'things': [('foo', '--')]},
                            [2])
 
-class TestCallBackManyArgs(BaseTest):
+class TestCallbackManyArgs(BaseTest):
     def setUp(self):
         options = [make_option("-a", "--apple", action="callback", nargs=2,
                                callback=self.process_many, type="string"),
@@ -870,10 +1087,10 @@
         self.assertParseOK(["-a", "foo", "bar", "--apple", "ding", "dong",
                             "-b", "1", "2", "3", "--bob", "-666", "42",
                             "0"],
-                           {},
+                           {"apple": None, "bob": None},
                            [])
 
-class TestCallBackCheckAbbrev(BaseTest):
+class TestCallbackCheckAbbrev(BaseTest):
     def setUp(self):
         self.parser = OptionParser()
         self.parser.add_option("--foo-bar", action="callback",
@@ -885,7 +1102,7 @@
     def test_abbrev_callback_expansion(self):
         self.assertParseOK(["--foo"], {}, [])
 
-class TestCallBackVarArgs(BaseTest):
+class TestCallbackVarArgs(BaseTest):
     def setUp(self):
         options = [make_option("-a", type="int", nargs=2, dest="a"),
                    make_option("-b", action="store_true", dest="b"),
@@ -950,13 +1167,12 @@
 class TestConflict(ConflictBase):
     """Use the default conflict resolution for Optik 1.2: error."""
     def assert_conflict_error(self, func):
-        err = self.assertRaises(func, OptionConflictError,
-                                "option -v/--version: conflicting option "
-                                "string(s): -v",
-                                funcargs=["-v", "--version"],
-                                funckwargs={'action':"callback",
-                                            'callback':self.show_version,
-                                            'help':"show version"})
+        err = self.assertRaises(
+            func, ("-v", "--version"), {'action' : "callback",
+                                        'callback' : self.show_version,
+                                        'help' : "show version"},
+            OptionConflictError,
+            "option -v/--version: conflicting option string(s): -v")
 
         self.assertEqual(err.msg, "conflicting option string(s): -v")
         self.assertEqual(err.option_id, "-v/--version")
@@ -969,9 +1185,9 @@
         self.assert_conflict_error(group.add_option)
 
     def test_no_such_conflict_handler(self):
-        self.assertRaises(self.parser.set_conflict_handler, ValueError,
-                          "invalid conflict_resolution value 'foo'",
-                          funcargs=['foo'])
+        self.assertRaises(
+            self.parser.set_conflict_handler, ('foo',), None,
+            ValueError, "invalid conflict_resolution value 'foo'")
 
 
 class TestConflictIgnore(ConflictBase):
@@ -1082,8 +1298,60 @@
 
 # -- Other testing. ----------------------------------------------------
 
+_expected_help_basic = """\
+usage: bar.py [options]
+
+options:
+  -a APPLE           throw APPLEs at basket
+  -b NUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all the
+                     evil spirits that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later fooing
+  -h, --help         show this help message and exit
+"""
+
+_expected_help_long_opts_first = """\
+usage: bar.py [options]
+
+options:
+  -a APPLE           throw APPLEs at basket
+  --boo=NUM, -b NUM  shout "boo!" NUM times (in order to frighten away all the
+                     evil spirits that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later fooing
+  --help, -h         show this help message and exit
+"""
+
+_expected_help_title_formatter = """\
+Usage
+=====
+  bar.py [options]
+
+options
+=======
+-a APPLE           throw APPLEs at basket
+--boo=NUM, -b NUM  shout "boo!" NUM times (in order to frighten away all the
+                   evil spirits that cause trouble and mayhem)
+--foo=FOO          store FOO in the foo list for later fooing
+--help, -h         show this help message and exit
+"""
+
+_expected_help_short_lines = """\
+usage: bar.py [options]
+
+options:
+  -a APPLE           throw APPLEs at basket
+  -b NUM, --boo=NUM  shout "boo!" NUM times (in order to
+                     frighten away all the evil spirits
+                     that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later
+                     fooing
+  -h, --help         show this help message and exit
+"""
+
 class TestHelp(BaseTest):
     def setUp(self):
+        self.parser = self.make_parser(80)
+
+    def make_parser(self, columns):
         options = [
             make_option("-a", type="string", dest='a',
                         metavar="APPLE", help="throw APPLEs at basket"),
@@ -1095,9 +1363,8 @@
             make_option("--foo", action="append", type="string", dest='foo',
                         help="store FOO in the foo list for later fooing"),
             ]
-
-        usage = "%prog [options]"
-        self.parser = OptionParser(usage=usage, option_list=options)
+        os.environ['COLUMNS'] = str(columns)
+        return OptionParser(option_list=options)        
 
     def assertHelpEquals(self, expected_output):
         # This trick is used to make optparse believe bar.py is being executed.
@@ -1109,62 +1376,30 @@
         sys.argv[0] = oldargv
 
     def test_help(self):
-        self.assertHelpEquals("""\
-usage: bar.py [options]
-
-options:
-  -aAPPLE           throw APPLEs at basket
-  -bNUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all
-                    the evil spirits that cause trouble and mayhem)
-  --foo=FOO         store FOO in the foo list for later fooing
-  -h, --help        show this help message and exit
-""")
+        self.assertHelpEquals(_expected_help_basic)
 
     def test_help_old_usage(self):
         self.parser.set_usage("usage: %prog [options]")
-        self.assertHelpEquals("""\
-usage: bar.py [options]
-
-options:
-  -aAPPLE           throw APPLEs at basket
-  -bNUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all
-                    the evil spirits that cause trouble and mayhem)
-  --foo=FOO         store FOO in the foo list for later fooing
-  -h, --help        show this help message and exit
-""")
+        self.assertHelpEquals(_expected_help_basic)
 
     def test_help_long_opts_first(self):
         self.parser.formatter.short_first = 0
-        self.assertHelpEquals("""\
-usage: bar.py [options]
-
-options:
-  -aAPPLE           throw APPLEs at basket
-  --boo=NUM, -bNUM  shout "boo!" NUM times (in order to frighten away all
-                    the evil spirits that cause trouble and mayhem)
-  --foo=FOO         store FOO in the foo list for later fooing
-  --help, -h        show this help message and exit
-""")
+        self.assertHelpEquals(_expected_help_long_opts_first)
 
     def test_help_title_formatter(self):
         self.parser.formatter = TitledHelpFormatter()
-        self.assertHelpEquals("""\
-Usage
-=====
-  bar.py [options]
+        self.assertHelpEquals(_expected_help_title_formatter)
 
-options
-=======
--aAPPLE           throw APPLEs at basket
---boo=NUM, -bNUM  shout "boo!" NUM times (in order to frighten away all
-                  the evil spirits that cause trouble and mayhem)
---foo=FOO         store FOO in the foo list for later fooing
---help, -h        show this help message and exit
-""")
+    def test_wrap_columns(self):
+        # Ensure that wrapping respects $COLUMNS environment variable.
+        # Need to reconstruct the parser, since that's the only time
+        # we look at $COLUMNS.
+        self.parser = self.make_parser(60)
+        self.assertHelpEquals(_expected_help_short_lines)
 
     def test_help_description_groups(self):
         self.parser.set_description(
-            "This is the program description.  This program has "
+            "This is the program description for %prog.  %prog has "
             "an option group as well as single options.")
 
         group = OptionGroup(
@@ -1177,21 +1412,26 @@
         self.assertHelpEquals("""\
 usage: bar.py [options]
 
-This is the program description.  This program has an option group as well as
-single options.
+This is the program description for bar.py.  bar.py has an option group as
+well as single options.
+
 options:
-  -aAPPLE           throw APPLEs at basket
-  -bNUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all
-                    the evil spirits that cause trouble and mayhem)
-  --foo=FOO         store FOO in the foo list for later fooing
-  -h, --help        show this help message and exit
+  -a APPLE           throw APPLEs at basket
+  -b NUM, --boo=NUM  shout "boo!" NUM times (in order to frighten away all the
+                     evil spirits that cause trouble and mayhem)
+  --foo=FOO          store FOO in the foo list for later fooing
+  -h, --help         show this help message and exit
 
   Dangerous Options:
-    Caution: use of these options is at your own risk.  It is believed that
-    some of them bite.
-    -g              Group option.
+    Caution: use of these options is at your own risk.  It is believed
+    that some of them bite.
+
+    -g               Group option.
 """)
 
+
+        
+
 class TestMatchAbbrev(BaseTest):
     def test_match_abbrev(self):
         self.assertEqual(_match_abbrev("--f",
@@ -1205,15 +1445,23 @@
         s = "--f"
         wordmap = {"--foz": None, "--foo": None, "--fie": None}
         possibilities = ", ".join(wordmap.keys())
-        self.assertRaises(_match_abbrev, BadOptionError,
-                          "ambiguous option: --f (%s?)" % possibilities,
-                          funcargs=[s, wordmap])
+        self.assertRaises(
+            _match_abbrev, (s, wordmap), None,
+            BadOptionError, "ambiguous option: --f (%s?)" % possibilities)
+
+
+def _testclasses():
+    mod = sys.modules[__name__]
+    return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
+
+def suite():
+    suite = unittest.TestSuite()
+    for testclass in _testclasses():
+        suite.addTest(unittest.makeSuite(testclass))
+    return suite
 
 def test_main():
-    mod = sys.modules[__name__]
-    test_support.run_unittest(
-        *[getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
-    )
+    test_support.run_suite(suite())
 
 if __name__ == '__main__':
     unittest.main()