\end{verbatim}
As it parses the command line, \code{optparse} sets attributes of the
-\var{options} object returned by \method{parse{\_}args()} based on user-supplied
+\code{options} object returned by \method{parse{\_}args()} based on user-supplied
command-line values. When \method{parse{\_}args()} returns from parsing this
-command line, \var{options.filename} will be \code{"outfile"} and
+command line, \code{options.filename} will be \code{"outfile"} and
\code{options.verbose} will be \code{False}. \code{optparse} supports both long
and short options, allows short options to be merged together, and
allows options to be associated with their arguments in a variety of
single letter, e.g. \code{"-x"} or \code{"-F"}. Also, traditional \UNIX{}
syntax allows multiple options to be merged into a single argument,
e.g. \code{"-x -F"} is equivalent to \code{"-xF"}. The GNU project
-introduced \code{"{--}"} followed by a series of hyphen-separated words,
-e.g. \code{"{--}file"} or \code{"{--}dry-run"}. These are the only two option
+introduced \code{"-{}-"} followed by a series of hyphen-separated words,
+e.g. \code{"-{}-file"} or \code{"-{}-dry-run"}. These are the only two option
syntaxes provided by \module{optparse}.
Some other option syntaxes that the world has seen include:
prog -v --report /tmp/report.txt foo bar
\end{verbatim}
-\code{"-v"} and \code{"{--}report"} are both options. Assuming that
+\code{"-v"} and \code{"-{}-report"} are both options. Assuming that
\longprogramopt{report} takes one argument, \code{"/tmp/report.txt"} is an option
argument. \code{"foo"} and \code{"bar"} are positional arguments.
\method{parse{\_}args()} returns two values:
\begin{itemize}
\item {}
-\var{options}, an object containing values for all of your options{---}e.g. if \code{"-{}-file"} takes a single string argument, then
-\var{options.file} will be the filename supplied by the user, or
+\code{options}, an object containing values for all of your options{---}e.g. if \code{"-{}-file"} takes a single string argument, then
+\code{options.file} will be the filename supplied by the user, or
\code{None} if the user did not supply that option
\item {}
-\var{args}, the list of positional arguments leftover after parsing
+\code{args}, the list of positional arguments leftover after parsing
options
\end{itemize}
adding new actions is an advanced topic covered in section~\ref{optparse-extending}, Extending \module{optparse}.
Most actions tell \module{optparse} to store a value in some variable{---}for
example, take a string from the command line and store it in an
-attribute of \var{options}.
+attribute of \code{options}.
If you don't specify an option action, \module{optparse} defaults to \code{store}.
\end{verbatim}
When \module{optparse} sees the option string \code{"-f"}, it consumes the next
-argument, \code{"foo.txt"}, and stores it in \var{options.filename}. So,
-after this call to \method{parse{\_}args()}, \var{options.filename} is
+argument, \code{"foo.txt"}, and stores it in \code{options.filename}. So,
+after this call to \method{parse{\_}args()}, \code{options.filename} is
\code{"foo.txt"}.
Some other option types supported by \module{optparse} are \code{int} and \code{float}.
Flag options{---}set a variable to true or false when a particular option
is seen{---}are quite common. \module{optparse} supports them with two separate
actions, \code{store{\_}true} and \code{store{\_}false}. For example, you might have a
-\var{verbose} flag that is turned on with \code{"-v"} and off with \code{"-q"}:
+\code{verbose} flag that is turned on with \code{"-v"} and off with \code{"-q"}:
\begin{verbatim}
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
destination, which is assigned before the command line is parsed.
First, consider the verbose/quiet example. If we want \module{optparse} to set
-\var{verbose} to \code{True} unless \code{"-q"} is seen, then we can do this:
+\code{verbose} to \code{True} unless \code{"-q"} is seen, then we can do this:
\begin{verbatim}
parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)
\end{verbatim}
-Again, the default value for \var{verbose} will be \code{True}: the last
+Again, the default value for \code{verbose} will be \code{True}: the last
default value supplied for any particular destination is the one that
counts.
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
\end{verbatim}
-Note that \code{"{\%}prog"} is expanded just like it is in \var{usage}. Apart
+Note that \code{"{\%}prog"} is expanded just like it is in \code{usage}. Apart
from that, \code{version} can contain anything you like. When you supply
it, \module{optparse} automatically adds a \code{"-{}-version"} option to your parser.
If it encounters this option on the command line, it expands your
\end{verbatim}
-\subsubsection{How \module{optparse} handles errors\label{optparse-how-optik-handles-errors}}
+\subsubsection{How \module{optparse} handles errors\label{optparse-how-optparse-handles-errors}}
There are two broad classes of errors that \module{optparse} has to worry about:
programmer errors and user errors. Programmer errors are usually
-erroneous calls to \code{parse.add{\_}option()}, e.g. invalid option strings,
+erroneous calls to \code{parser.add{\_}option()}, e.g. invalid option strings,
unknown option attributes, missing option attributes, etc. These are
dealt with in the usual way: raise an exception (either
-\exception{optparse.OptionError} or \exception{TypeError}) and let the program crash.
+\code{optparse.OptionError} or \code{TypeError}) and let the program crash.
Handling user errors is much more important, since they are guaranteed
to happen no matter how stable your code is. \module{optparse} can automatically
if __name__ == "__main__":
main()
\end{verbatim}
-% $Id: tutorial.txt 415 2004-09-30 02:26:17Z greg $
+% $Id: tutorial.txt 505 2005-07-22 01:52:40Z gward $
\subsection{Reference Guide\label{optparse-reference-guide}}
+\subsubsection{Creating the parser\label{optparse-creating-parser}}
+
+The first step in using \module{optparse} is to create an OptionParser instance:
+\begin{verbatim}
+parser = OptionParser(...)
+\end{verbatim}
+
+The OptionParser constructor has no required arguments, but a number of
+optional keyword arguments. You should always pass them as keyword
+arguments, i.e. do not rely on the order in which the arguments are
+declared.
+\begin{quote}
+\begin{description}
+\item[\code{usage} (default: \code{"{\%}prog {[}options]"})]
+The usage summary to print when your program is run incorrectly or
+with a help option. When \module{optparse} prints the usage string, it expands
+\code{{\%}prog} to \code{os.path.basename(sys.argv{[}0])} (or to \code{prog} if
+you passed that keyword argument). To suppress a usage message,
+pass the special value \code{optparse.SUPPRESS{\_}USAGE}.
+\item[\code{option{\_}list} (default: \code{{[}]})]
+A list of Option objects to populate the parser with. The options
+in \code{option{\_}list} are added after any options in
+\code{standard{\_}option{\_}list} (a class attribute that may be set by
+OptionParser subclasses), but before any version or help options.
+Deprecated; use \method{add{\_}option()} after creating the parser instead.
+\item[\code{option{\_}class} (default: optparse.Option)]
+Class to use when adding options to the parser in \method{add{\_}option()}.
+\item[\code{version} (default: \code{None})]
+A version string to print when the user supplies a version option.
+If you supply a true value for \code{version}, \module{optparse} automatically adds
+a version option with the single option string \code{"-{}-version"}. The
+substring \code{"{\%}prog"} is expanded the same as for \code{usage}.
+\item[\code{conflict{\_}handler} (default: \code{"error"})]
+Specifies what to do when options with conflicting option strings
+are added to the parser; see section~\ref{optparse-conflicts-between-options}, Conflicts between options.
+\item[\code{description} (default: \code{None})]
+A paragraph of text giving a brief overview of your program. \module{optparse}
+reformats this paragraph to fit the current terminal width and
+prints it when the user requests help (after \code{usage}, but before
+the list of options).
+\item[\code{formatter} (default: a new IndentedHelpFormatter)]
+An instance of optparse.HelpFormatter that will be used for
+printing help text. \module{optparse} provides two concrete classes for this
+purpose: IndentedHelpFormatter and TitledHelpFormatter.
+\item[\code{add{\_}help{\_}option} (default: \code{True})]
+If true, \module{optparse} will add a help option (with option strings \code{"-h"}
+and \code{"-{}-help"}) to the parser.
+\item[\code{prog}]
+The string to use when expanding \code{"{\%}prog"} in \code{usage} and
+\code{version} instead of \code{os.path.basename(sys.argv{[}0])}.
+\end{description}
+\end{quote}
+
+
\subsubsection{Populating the parser\label{optparse-populating-parser}}
There are several ways to populate the parser with options. The
specify any number of short or long option strings, but you must specify
at least one overall option string.
-The canonical way to create an Option instance is by calling
-\function{make{\_}option()}, so that is what will be shown here. However, the
-most common and convenient way is to use \code{parser.add{\_}option()}. Note
-that \function{make{\_}option()} and \code{parser.add{\_}option()} have identical call
-signatures:
+The canonical way to create an Option instance is with the
+\method{add{\_}option()} method of \class{OptionParser}:
\begin{verbatim}
-make_option(opt_str, ..., attr=value, ...)
-parser.add_option(opt_str, ..., attr=value, ...)
+parser.add_option(opt_str[, ...], attr=value, ...)
\end{verbatim}
To define an option with only a short option string:
\begin{verbatim}
-make_option("-f", attr=value, ...)
+parser.add_option("-f", attr=value, ...)
\end{verbatim}
And to define an option with only a long option string:
\begin{verbatim}
-make_option("--foo", attr=value, ...)
+parser.add_option("--foo", attr=value, ...)
\end{verbatim}
-The \code{attr=value} keyword arguments define option attributes,
-i.e. attributes of the Option object. The most important option
-attribute is \member{action}, and it largely determines what other attributes
-are relevant or required. If you pass irrelevant option attributes, or
-fail to pass required ones, \module{optparse} raises an OptionError exception
-explaining your mistake.
+The keyword arguments define attributes of the new Option object. The
+most important option attribute is \member{action}, and it largely determines
+which other attributes are relevant or required. If you pass irrelevant
+option attributes, or fail to pass required ones, \module{optparse} raises an
+OptionError exception explaining your mistake.
-An options's \emph{action} determines what \module{optparse} does when it encounters
-this option on the command-line. The actions hard-coded into \module{optparse} are:
+An options's \emph{action} determines what \module{optparse} does when it encounters this
+option on the command-line. The standard option actions hard-coded into
+\module{optparse} are:
\begin{description}
\item[\code{store}]
-store this option's argument {[}default]
+store this option's argument (default)
\item[\code{store{\_}const}]
store a constant value
\item[\code{store{\_}true}]
store a false value
\item[\code{append}]
append this option's argument to a list
+\item[\code{append{\_}const}]
+append a constant value to a list
\item[\code{count}]
increment a counter by one
\item[\code{callback}]
below.)
As you can see, most actions involve storing or updating a value
-somewhere. \module{optparse} always creates an instance of \code{optparse.Values}
-specifically for this purpose; we refer to this instance as \var{options}.
-Option arguments (and various other values) are stored as attributes of
-this object, according to the \member{dest} (destination) option attribute.
+somewhere. \module{optparse} always creates a special object for this,
+conventionally called \code{options} (it happens to be an instance of
+\code{optparse.Values}). Option arguments (and various other values) are
+stored as attributes of this object, according to the \member{dest}
+(destination) option attribute.
For example, when you call
\begin{verbatim}
parser.parse_args()
\end{verbatim}
-one of the first things \module{optparse} does is create the \var{options} object:
+one of the first things \module{optparse} does is create the \code{options} object:
\begin{verbatim}
options = Values()
\end{verbatim}
If one of the options in this parser is defined with
\begin{verbatim}
-make_option("-f", "--file", action="store", type="string", dest="filename")
+parser.add_option("-f", "--file", action="store", type="string", dest="filename")
\end{verbatim}
and the command-line being parsed includes any of the following:
--file foo
\end{verbatim}
-then \module{optparse}, on seeing the \programopt{-f} or \longprogramopt{file} option, will do the
-equivalent of
+then \module{optparse}, on seeing this option, will do the equivalent of
\begin{verbatim}
options.filename = "foo"
\end{verbatim}
options.tracks.append(int("4"))
\end{verbatim}
+\item {}
+\code{append{\_}const} {[}required: \code{const}; relevant: \member{dest}]
+
+Like \code{store{\_}const}, but the value \code{const} is appended to \member{dest};
+as with \code{append}, \member{dest} defaults to \code{None}, and an an empty list is
+automatically created the first time the option is encountered.
+
\item {}
\code{count} {[}relevant: \member{dest}]
\code{callback} {[}required: \code{callback};
relevant: \member{type}, \code{nargs}, \code{callback{\_}args}, \code{callback{\_}kwargs}]
-Call the function specified by \code{callback}. The signature of
-this function should be
+Call the function specified by \code{callback}, which is called as
\begin{verbatim}
-func(option : Option,
- opt : string,
- value : any,
- parser : OptionParser,
- *args, **kwargs)
+func(option, opt_str, value, parser, *args, **kwargs)
\end{verbatim}
See section~\ref{optparse-option-callbacks}, Option Callbacks for more detail.
Prints a complete help message for all the options in the
current option parser. The help message is constructed from
-the \var{usage} string passed to OptionParser's constructor and
+the \code{usage} string passed to OptionParser's constructor and
the \member{help} string passed to every option.
If no \member{help} string is supplied for an option, it will still be
\end{itemize}
+\subsubsection{Option attributes\label{optparse-option-attributes}}
+
+The following option attributes may be passed as keyword arguments
+to \code{parser.add{\_}option()}. If you pass an option attribute
+that is not relevant to a particular option, or fail to pass a required
+option attribute, \module{optparse} raises OptionError.
+\begin{itemize}
+\item {}
+\member{action} (default: \code{"store"})
+
+Determines \module{optparse}'s behaviour when this option is seen on the command
+line; the available options are documented above.
+
+\item {}
+\member{type} (default: \code{"string"})
+
+The argument type expected by this option (e.g., \code{"string"} or
+\code{"int"}); the available option types are documented below.
+
+\item {}
+\member{dest} (default: derived from option strings)
+
+If the option's action implies writing or modifying a value somewhere,
+this tells \module{optparse} where to write it: \member{dest} names an attribute of the
+\code{options} object that \module{optparse} builds as it parses the command line.
+
+\item {}
+\code{default} (deprecated)
+
+The value to use for this option's destination if the option is not
+seen on the command line. Deprecated; use \code{parser.set{\_}defaults()}
+instead.
+
+\item {}
+\code{nargs} (default: 1)
+
+How many arguments of type \member{type} should be consumed when this
+option is seen. If {\textgreater} 1, \module{optparse} will store a tuple of values to
+\member{dest}.
+
+\item {}
+\code{const}
+
+For actions that store a constant value, the constant value to store.
+
+\item {}
+\code{choices}
+
+For options of type \code{"choice"}, the list of strings the user
+may choose from.
+
+\item {}
+\code{callback}
+
+For options with action \code{"callback"}, the callable to call when this
+option is seen. See section~\ref{optparse-option-callbacks}, Option Callbacks for detail on the arguments
+passed to \code{callable}.
+
+\item {}
+\code{callback{\_}args}, \code{callback{\_}kwargs}
+
+Additional positional and keyword arguments to pass to \code{callback}
+after the four standard callback arguments.
+
+\item {}
+\member{help}
+
+Help text to print for this option when listing all available options
+after the user supplies a \member{help} option (such as \code{"-{}-help"}).
+If no help text is supplied, the option will be listed without help
+text. To hide this option, use the special value \code{SUPPRESS{\_}HELP}.
+
+\item {}
+\code{metavar} (default: derived from option strings)
+
+Stand-in for the option argument(s) to use when printing help text.
+See section~\ref{optparse-tutorial}, the tutorial for an example.
+
+\end{itemize}
+
+
\subsubsection{Standard option types\label{optparse-standard-option-types}}
\module{optparse} has six built-in option types: \code{string}, \code{int}, \code{long},
text on the command line is stored in the destination (or passed to the
callback) as-is.
-Integer arguments are passed to \code{int()} to convert them to Python
-integers. If \code{int()} fails, so will \module{optparse}, although with a more
-useful error message. (Internally, \module{optparse} raises
-\exception{OptionValueError}; OptionParser catches this exception higher
-up and terminates your program with a useful error message.)
+Integer arguments (type \code{int} or \code{long}) are parsed as follows:
+\begin{quote}
+\begin{itemize}
+\item {}
+if the number starts with \code{0x}, it is parsed as a hexadecimal number
+
+\item {}
+if the number starts with \code{0}, it is parsed as an octal number
+
+\item {}
+if the number starts with \code{0b}, is is parsed as a binary number
+
+\item {}
+otherwise, the number is parsed as a decimal number
+
+\end{itemize}
+\end{quote}
+
+The conversion is done by calling either \code{int()} or \code{long()} with
+the appropriate base (2, 8, 10, or 16). If this fails, so will \module{optparse},
+although with a more useful error message.
-Likewise, \code{float} arguments are passed to \code{float()} for conversion,
-\code{long} arguments to \code{long()}, and \code{complex} arguments to
-\code{complex()}. Apart from that, they are handled identically to integer
-arguments.
+\code{float} and \code{complex} option arguments are converted directly with
+\code{float()} and \code{complex()}, with similar error-handling.
\code{choice} options are a subtype of \code{string} options. The \code{choices}
option attribute (a sequence of strings) defines the set of allowed
-option arguments. \code{optparse.option.check{\_}choice()} compares
+option arguments. \code{optparse.check{\_}choice()} compares
user-supplied option arguments against this master list and raises
-\exception{OptionValueError} if an invalid string is given.
+OptionValueError if an invalid string is given.
+
+
+\subsubsection{Parsing arguments\label{optparse-parsing-arguments}}
+
+The whole point of creating and populating an OptionParser is to call
+its \method{parse{\_}args()} method:
+\begin{verbatim}
+(options, args) = parser.parse_args(args=None, options=None)
+\end{verbatim}
+
+where the input parameters are
+\begin{description}
+\item[\code{args}]
+the list of arguments to process (\code{sys.argv{[}1:]} by default)
+\item[\code{options}]
+object to store option arguments in (a new instance of
+optparse.Values by default)
+\end{description}
+
+and the return values are
+\begin{description}
+\item[\code{options}]
+the same object as was passed in as \code{options}, or the new
+optparse.Values instance created by \module{optparse}
+\item[\code{args}]
+the leftover positional arguments after all options have been
+processed
+\end{description}
+
+The most common usage is to supply neither keyword argument. If you
+supply a \code{values} object, it will be repeatedly modified with a
+\code{setattr()} call for every option argument written to an option
+destination, and finally returned by \method{parse{\_}args()}.
+
+If \method{parse{\_}args()} encounters any errors in the argument list, it calls
+the OptionParser's \method{error()} method with an appropriate end-user error
+message. This ultimately terminates your process with an exit status of
+2 (the traditional \UNIX{} exit status for command-line errors).
\subsubsection{Querying and manipulating your option parser\label{optparse-querying-manipulating-option-parser}}
If the OptionParser has an option corresponding to \code{opt{\_}str},
that option is removed. If that option provided any other
option strings, all of those option strings become invalid.
-
If \code{opt{\_}str} does not occur in any option belonging to this
-OptionParser, raises \exception{ValueError}.
+OptionParser, raises ValueError.
\end{description}
mechanism. You can set the conflict-handling mechanism either in the
constructor:
\begin{verbatim}
-parser = OptionParser(..., conflict_handler="...")
+parser = OptionParser(..., conflict_handler=handler)
\end{verbatim}
or with a separate call:
\begin{verbatim}
-parser.set_conflict_handler("...")
+parser.set_conflict_handler(handler)
\end{verbatim}
-The available conflict-handling mechanisms are:
+The available conflict handlers are:
\begin{quote}
\begin{description}
\item[\code{error} (default)]
assume option conflicts are a programming error and raise
-\exception{OptionConflictError}
+OptionConflictError
\item[\code{resolve}]
resolve option conflicts intelligently (see below)
\end{description}
-n, --noisy be noisy
--dry-run new dry-run option
\end{verbatim}
-% $Id: reference.txt 415 2004-09-30 02:26:17Z greg $
+
+
+\subsubsection{Cleanup\label{optparse-cleanup}}
+
+OptionParser instances have several cyclic references. This should not
+be a problem for Python's garbage collector, but you may wish to break
+the cyclic references explicitly by calling \code{destroy()} on your
+OptionParser once you are done with it. This is particularly useful in
+long-running applications where large object graphs are reachable from
+your OptionParser.
+
+
+\subsubsection{Other methods\label{optparse-other-methods}}
+
+OptionParser supports several other public methods:
+\begin{itemize}
+\item {}
+\code{set{\_}usage(usage)}
+
+Set the usage string according to the rules described above for the
+\code{usage} constructor keyword argument. Passing \code{None} sets the
+default usage string; use \code{SUPPRESS{\_}USAGE} to suppress a usage
+message.
+
+\item {}
+\code{enable{\_}interspersed{\_}args()}, \code{disable{\_}interspersed{\_}args()}
+
+Enable/disable positional arguments interspersed with options, similar
+to GNU getopt (enabled by default). For example, if \code{"-a"} and
+\code{"-b"} are both simple options that take no arguments, \module{optparse}
+normally accepts this syntax:
+\begin{verbatim}
+prog -a arg1 -b arg2
+\end{verbatim}
+
+and treats it as equivalent to
+\begin{verbatim}
+prog -a -b arg1 arg2
+\end{verbatim}
+
+To disable this feature, call \code{disable{\_}interspersed{\_}args()}. This
+restores traditional \UNIX{} syntax, where option parsing stops with the
+first non-option argument.
+
+\item {}
+\code{set{\_}defaults(dest=value, ...)}
+
+Set default values for several option destinations at once. Using
+\method{set{\_}defaults()} is the preferred way to set default values for
+options, since multiple options can share the same destination. For
+example, if several ``mode'' options all set the same destination, any
+one of them can set the default, and the last one wins:
+\begin{verbatim}
+parser.add_option("--advanced", action="store_const",
+ dest="mode", const="advanced",
+ default="novice") # overridden below
+parser.add_option("--novice", action="store_const",
+ dest="mode", const="novice",
+ default="advanced") # overrides above setting
+\end{verbatim}
+
+To avoid this confusion, use \method{set{\_}defaults()}:
+\begin{verbatim}
+parser.set_defaults(mode="advanced")
+parser.add_option("--advanced", action="store_const",
+ dest="mode", const="advanced")
+parser.add_option("--novice", action="store_const",
+ dest="mode", const="novice")
+\end{verbatim}
+
+\end{itemize}
+% $Id: reference.txt 505 2005-07-22 01:52:40Z gward $
\subsection{Option Callbacks\label{optparse-option-callbacks}}
the current list of leftover arguments, ie. arguments that have
been consumed but are neither options nor option arguments.
Feel free to modify \code{parser.largs}, e.g. by adding more
-arguments to it. (This list will become \var{args}, the second
+arguments to it. (This list will become \code{args}, the second
return value of \method{parse{\_}args()}.)
\item[\code{parser.rargs}]
the current list of remaining arguments, ie. with \code{opt{\_}str} and
\subsubsection{Raising errors in a callback\label{optparse-raising-errors-in-callback}}
-The callback function should raise \exception{OptionValueError} if there are any
+The callback function should raise OptionValueError if there are any
problems with the option or its argument(s). \module{optparse} catches this and
terminates the program, printing the error message you supply to
stderr. Your message should be clear, concise, accurate, and mention
# Python developers: please do not make changes to this file, since
# it is automatically generated from the Optik source code.
-__version__ = "1.5a2"
+__version__ = "1.5.1"
__all__ = ['Option',
'SUPPRESS_HELP',
'BadOptionError']
__copyright__ = """
-Copyright (c) 2001-2004 Gregory P. Ward. All rights reserved.
-Copyright (c) 2002-2004 Python Software Foundation. All rights reserved.
+Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved.
+Copyright (c) 2002-2006 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
"""
import sys, os
+import types
import textwrap
-try:
- from gettext import gettext as _
-except ImportError:
- _ = lambda arg: arg
def _repr(self):
return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
# This file was generated from:
-# Id: option_parser.py 421 2004-10-26 00:45:16Z greg
-# Id: option.py 422 2004-10-26 00:53:47Z greg
-# Id: help.py 367 2004-07-24 23:21:21Z gward
-# Id: errors.py 367 2004-07-24 23:21:21Z gward
+# Id: option_parser.py 509 2006-04-20 00:58:24Z gward
+# Id: option.py 509 2006-04-20 00:58:24Z gward
+# Id: help.py 509 2006-04-20 00:58:24Z gward
+# Id: errors.py 509 2006-04-20 00:58:24Z gward
+
+try:
+ from gettext import gettext
+except ImportError:
+ def gettext(message):
+ return message
+_ = gettext
+
class OptParseError (Exception):
def __init__(self, msg):
class BadOptionError (OptParseError):
"""
- Raised if an invalid or ambiguous option is seen on the command-line.
+ Raised if an invalid option is seen on the command line.
+ """
+ def __init__(self, opt_str):
+ self.opt_str = opt_str
+
+ def __str__(self):
+ return _("no such option: %s") % self.opt_str
+
+class AmbiguousOptionError (BadOptionError):
+ """
+ Raised if an ambiguous option is seen on the command line.
"""
+ def __init__(self, opt_str, possibilities):
+ BadOptionError.__init__(self, opt_str)
+ self.possibilities = possibilities
+
+ def __str__(self):
+ return (_("ambiguous option: %s (%s?)")
+ % (self.opt_str, ", ".join(self.possibilities)))
class HelpFormatter:
def format_heading(self, heading):
raise NotImplementedError, "subclasses must implement"
- def format_description(self, description):
- if not description:
- return ""
- desc_width = self.width - self.current_indent
+ def _format_text(self, text):
+ """
+ Format a paragraph of free-form text for inclusion in the
+ help output at the current indentation level.
+ """
+ text_width = self.width - self.current_indent
indent = " "*self.current_indent
- return textwrap.fill(description,
- desc_width,
+ return textwrap.fill(text,
+ text_width,
initial_indent=indent,
- subsequent_indent=indent) + "\n"
+ subsequent_indent=indent)
+
+ def format_description(self, description):
+ if description:
+ return self._format_text(description) + "\n"
+ else:
+ return ""
+
+ def format_epilog(self, epilog):
+ if epilog:
+ return "\n" + self._format_text(epilog) + "\n"
+ else:
+ return ""
+
def expand_default(self, option):
if self.parser is None or not self.default_tag:
self, indent_increment, max_help_position, width, short_first)
def format_usage(self, usage):
- return _("usage: %s\n") % usage
+ return _("Usage: %s\n") % usage
def format_heading(self, heading):
return "%*s%s:\n" % (self.current_indent, "", heading)
return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
-_builtin_cvt = { "int" : (int, _("integer")),
- "long" : (long, _("long integer")),
+def _parse_num(val, type):
+ if val[:2].lower() == "0x": # hexadecimal
+ radix = 16
+ elif val[:2].lower() == "0b": # binary
+ radix = 2
+ val = val[2:] or "0" # have to remove "0b" prefix
+ elif val[:1] == "0": # octal
+ radix = 8
+ else: # decimal
+ radix = 10
+
+ return type(val, radix)
+
+def _parse_int(val):
+ return _parse_num(val, int)
+
+def _parse_long(val):
+ return _parse_num(val, long)
+
+_builtin_cvt = { "int" : (_parse_int, _("integer")),
+ "long" : (_parse_long, _("long integer")),
"float" : (float, _("floating-point")),
"complex" : (complex, _("complex")) }
"store_true",
"store_false",
"append",
+ "append_const",
"count",
"callback",
"help",
"store_true",
"store_false",
"append",
+ "append_const",
"count")
# The set of actions for which it makes sense to supply a value
ALWAYS_TYPED_ACTIONS = ("store",
"append")
+ # The set of actions which take a 'const' attribute.
+ CONST_ACTIONS = ("store_const",
+ "append_const")
+
# The set of known types for option parsers. Again, listed here for
# constructor argument validation.
TYPES = ("string", "int", "long", "float", "complex", "choice")
# 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:
+ # Allow type objects or builtin type conversion functions
+ # (int, str, etc.) as an alternative to their names. (The
+ # complicated check of __builtin__ is only necessary for
+ # Python 2.1 and earlier, and is short-circuited by the
+ # first check on modern Pythons.)
+ import __builtin__
+ if ( type(self.type) is types.TypeType or
+ (hasattr(self.type, "__name__") and
+ getattr(__builtin__, self.type.__name__, None) is self.type) ):
self.type = self.type.__name__
+
if self.type == "str":
self.type = "string"
if self.choices is None:
raise OptionError(
"must supply a list of choices for type 'choice'", self)
- elif type(self.choices) not in (tuple, list):
+ elif type(self.choices) not in (types.TupleType, types.ListType):
raise OptionError(
"choices must be a list of strings ('%s' supplied)"
% str(type(self.choices)).split("'")[1], self)
self.dest = self._short_opts[0][1]
def _check_const(self):
- if self.action != "store_const" and self.const is not None:
+ if self.action not in self.CONST_ACTIONS and self.const is not None:
raise OptionError(
"'const' must not be supplied for action %r" % self.action,
self)
raise OptionError(
"callback not callable: %r" % self.callback, self)
if (self.callback_args is not None and
- type(self.callback_args) is not tuple):
+ type(self.callback_args) is not types.TupleType):
raise OptionError(
"callback_args, if supplied, must be a tuple: not %r"
% self.callback_args, self)
if (self.callback_kwargs is not None and
- type(self.callback_kwargs) is not dict):
+ type(self.callback_kwargs) is not types.DictType):
raise OptionError(
"callback_kwargs, if supplied, must be a dict: not %r"
% self.callback_kwargs, self)
setattr(values, dest, False)
elif action == "append":
values.ensure_value(dest, []).append(value)
+ elif action == "append_const":
+ values.ensure_value(dest, []).append(self.const)
elif action == "count":
setattr(values, dest, values.ensure_value(dest, 0) + 1)
elif action == "callback":
True, False
except NameError:
(True, False) = (1, 0)
-try:
- basestring
-except NameError:
- basestring = (str, unicode)
+def isbasestring(x):
+ return isinstance(x, types.StringType) or isinstance(x, types.UnicodeType)
class Values:
__repr__ = _repr
- def __eq__(self, other):
+ def __cmp__(self, other):
if isinstance(other, Values):
- return self.__dict__ == other.__dict__
- elif isinstance(other, dict):
- return self.__dict__ == other
+ return cmp(self.__dict__, other.__dict__)
+ elif isinstance(other, types.DictType):
+ return cmp(self.__dict__, other)
else:
- return False
-
- def __ne__(self, other):
- return not (self == other)
+ return -1
def _update_careful(self, dict):
"""
return self.description
+ def destroy(self):
+ """see OptionParser.destroy()."""
+ del self._short_opt
+ del self._long_opt
+ del self.defaults
+
+
# -- Option-adding methods -----------------------------------------
def _check_conflict(self, option):
"""add_option(Option)
add_option(opt_str, ..., kwarg=val, ...)
"""
- if type(args[0]) is str:
+ if type(args[0]) is types.StringType:
option = self.option_class(*args, **kwargs)
elif len(args) == 1 and not kwargs:
option = args[0]
def set_title(self, title):
self.title = title
+ def destroy(self):
+ """see OptionParser.destroy()."""
+ OptionContainer.destroy(self)
+ del self.option_list
+
# -- Help-formatting methods ---------------------------------------
def format_help(self, formatter):
prog : string
the name of the current program (to override
os.path.basename(sys.argv[0])).
+ epilog : string
+ paragraph of help text to print after option help
option_groups : [OptionGroup]
list of option groups in this parser (option groups are
description=None,
formatter=None,
add_help_option=True,
- prog=None):
+ prog=None,
+ epilog=None):
OptionContainer.__init__(
self, option_class, conflict_handler, description)
self.set_usage(usage)
formatter = IndentedHelpFormatter()
self.formatter = formatter
self.formatter.set_parser(self)
+ self.epilog = epilog
# Populate the option list; initial sources are the
# standard_option_list class attribute, the 'option_list'
self._init_parsing_state()
+
+ def destroy(self):
+ """
+ Declare that you are done with this OptionParser. This cleans up
+ reference cycles so the OptionParser (and all objects referenced by
+ it) can be garbage-collected promptly. After calling destroy(), the
+ OptionParser is unusable.
+ """
+ OptionContainer.destroy(self)
+ for group in self.option_groups:
+ group.destroy()
+ del self.option_list
+ del self.option_groups
+ del self.formatter
+
+
# -- Private methods -----------------------------------------------
# (used by our or OptionContainer's constructor)
elif usage is SUPPRESS_USAGE:
self.usage = None
# For backwards compatibility with Optik 1.3 and earlier.
- elif usage.startswith("usage:" + " "):
+ elif usage.lower().startswith("usage: "):
self.usage = usage[7:]
else:
self.usage = usage
defaults = self.defaults.copy()
for option in self._get_all_options():
default = defaults.get(option.dest)
- if isinstance(default, basestring):
+ if isbasestring(default):
opt_str = option.get_opt_string()
defaults[option.dest] = option.check_value(opt_str, default)
def add_option_group(self, *args, **kwargs):
# XXX lots of overlap with OptionContainer.add_option()
- if type(args[0]) is str:
+ if type(args[0]) is types.StringType:
group = OptionGroup(self, *args, **kwargs)
elif len(args) == 1 and not kwargs:
group = args[0]
try:
stop = self._process_args(largs, rargs, values)
except (BadOptionError, OptionValueError), err:
- self.error(err.msg)
+ self.error(str(err))
args = largs + rargs
return self.check_values(values, args)
i += 1 # we have consumed a character
if not option:
- self.error(_("no such option: %s") % opt)
+ raise BadOptionError(opt)
if option.takes_value():
# Any characters left in arg? Pretend they're the
# next arg, and stop consuming characters of arg.
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))
# Drop the last "\n", or the header if no options or option groups:
return "".join(result[:-1])
+ def format_epilog(self, formatter):
+ return formatter.format_epilog(self.epilog)
+
def format_help(self, formatter=None):
if formatter is None:
formatter = self.formatter
if self.description:
result.append(self.format_description(formatter) + "\n")
result.append(self.format_option_help(formatter))
+ result.append(self.format_epilog(formatter))
return "".join(result)
def print_help(self, file=None):
if len(possibilities) == 1:
return possibilities[0]
elif not possibilities:
- raise BadOptionError(_("no such option: %s") % s)
+ raise BadOptionError(s)
else:
# More than one possible completion: ambiguous prefix.
- raise BadOptionError(_("ambiguous option: %s (%s?)")
- % (s, ", ".join(possibilities)))
+ raise AmbiguousOptionError(s, possibilities)
# Some day, there might be many Option classes. As of Optik 1.3, the
import sys
import os
+import re
import copy
+import types
import unittest
from cStringIO import StringIO
from pprint import pprint
from test import test_support
+
from optparse import make_option, Option, IndentedHelpFormatter, \
TitledHelpFormatter, OptionParser, OptionContainer, OptionGroup, \
SUPPRESS_HELP, SUPPRESS_USAGE, OptionError, OptionConflictError, \
- BadOptionError, OptionValueError, Values, _match_abbrev
+ BadOptionError, OptionValueError, Values
+from optparse import _match_abbrev
+from optparse import _parse_num
# Do the right thing with boolean values for all known Python versions.
try:
except NameError:
(True, False) = (1, 0)
+retype = type(re.compile(''))
class InterceptedError(Exception):
def __init__(self,
args -- positional arguments to `func`
kwargs -- keyword arguments to `func`
expected_exception -- exception that should be raised
- expected_output -- output we expect to see
+ expected_message -- expected exception message (or pattern
+ if a compiled regex object)
Returns the exception raised for further testing.
"""
func(*args, **kwargs)
except expected_exception, err:
actual_message = str(err)
- self.assertEqual(actual_message,
- expected_message,
+ if isinstance(expected_message, retype):
+ self.assert_(expected_message.search(actual_message),
"""\
+expected exception message pattern:
+/%s/
+actual exception message:
+'''%s'''
+""" % (expected_message.pattern, actual_message))
+ else:
+ self.assertEqual(actual_message,
+ expected_message,
+ """\
expected exception message:
-'''%(expected_message)s'''
+'''%s'''
actual exception message:
-'''%(actual_message)s'''
-""" % locals())
+'''%s'''
+""" % (expected_message, actual_message))
return err
else:
sys.stdout = save_stdout
except InterceptedError, err:
- self.assertEqual(output, expected_output)
+ if output != expected_output:
+ self.fail("expected: \n'''\n" + expected_output +
+ "'''\nbut got \n'''\n" + output + "'''")
self.assertEqual(err.exit_status, expected_status)
self.assertEqual(err.exit_message, expected_error)
else:
self.assertRaises(self.parser.remove_option, ('foo',), None,
ValueError, "no such option 'foo'")
+ def test_refleak(self):
+ # If an OptionParser is carrying around a reference to a large
+ # object, various cycles can prevent it from being GC'd in
+ # a timely fashion. destroy() breaks the cycles to ensure stuff
+ # can be cleaned up.
+ big_thing = [42]
+ refcount = sys.getrefcount(big_thing)
+ parser = OptionParser()
+ parser.add_option("-a", "--aaarggh")
+ parser.big_thing = big_thing
+
+ parser.destroy()
+ #self.assertEqual(refcount, sys.getrefcount(big_thing))
+ del parser
+ self.assertEqual(refcount, sys.getrefcount(big_thing))
+
+
class TestOptionValues(BaseTest):
def setUp(self):
pass
def setUp(self):
self.parser = OptionParser()
- def test_type_aliases(self):
- self.parser.add_option("-x", type=int)
+ def test_str_aliases_string(self):
+ self.parser.add_option("-s", type="str")
+ self.assertEquals(self.parser.get_option("-s").type, "string")
+
+ def test_new_type_object(self):
self.parser.add_option("-s", type=str)
- self.parser.add_option("-t", type="str")
+ self.assertEquals(self.parser.get_option("-s").type, "string")
+ self.parser.add_option("-x", type=int)
self.assertEquals(self.parser.get_option("-x").type, "int")
+
+ def test_old_type_object(self):
+ self.parser.add_option("-s", type=types.StringType)
self.assertEquals(self.parser.get_option("-s").type, "string")
- self.assertEquals(self.parser.get_option("-t").type, "string")
+ self.parser.add_option("-x", type=types.IntType)
+ self.assertEquals(self.parser.get_option("-x").type, "int")
# Custom type for testing processing of default values.
save_argv = sys.argv[:]
try:
sys.argv[0] = os.path.join("foo", "bar", "baz.py")
- parser = OptionParser("usage: %prog ...", version="%prog 1.2")
- expected_usage = "usage: baz.py ...\n"
+ parser = OptionParser("%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"
+ "Options:\n"
" --version show program's version number and exit\n"
" -h, --help show this help message and exit\n")
finally:
usage="%prog arg arg")
parser.remove_option("-h")
parser.remove_option("--version")
- expected_usage = "usage: thingy arg arg\n"
+ expected_usage = "Usage: thingy arg arg\n"
self.assertUsage(parser, expected_usage)
self.assertVersion(parser, "thingy 0.1")
self.assertHelp(parser, expected_usage + "\n")
def setUp(self):
self.parser = OptionParser(prog="test")
self.help_prefix = """\
-usage: test [options]
+Usage: test [options]
-options:
+Options:
-h, --help show this help message and exit
"""
self.file_help = "read from FILE [default: %default]"
self.assertParseOK(["-a", "--", "foo", "bar"],
{'a': "--", 'boo': None, 'foo': None},
["foo", "bar"]),
+ self.assertParseOK(["-a", "--", "--foo", "bar"],
+ {'a': "--", 'boo': None, 'foo': ["bar"]},
+ []),
def test_short_option_joined_and_separator(self):
self.assertParseOK(["-ab", "--", "--foo", "bar"],
{'a': "b", 'boo': None, 'foo': None},
["--foo", "bar"]),
- def test_invalid_option_becomes_positional_arg(self):
+ def test_hyphen_becomes_positional_arg(self):
self.assertParseOK(["-ab", "-", "--foo", "bar"],
{'a': "b", 'boo': None, 'foo': ["bar"]},
["-"])
type="float", dest="point")
self.parser.add_option("-f", "--foo", action="append", nargs=2,
type="int", dest="foo")
+ self.parser.add_option("-z", "--zero", action="append_const",
+ dest="foo", const=(0, 0))
def test_nargs_append(self):
self.assertParseOK(["-f", "4", "-3", "blah", "--foo", "1", "666"],
{'point': None, 'foo':[(3, 4)]},
[])
+ def test_nargs_append_const(self):
+ self.assertParseOK(["--zero", "--foo", "3", "4", "-z"],
+ {'point': None, 'foo':[(0, 0), (3, 4), (0, 0)]},
+ [])
+
class TestVersion(BaseTest):
def test_version(self):
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
self.parser.add_option("-a", None, type="string", dest="a")
self.parser.add_option("-f", "--file", type="file", dest="file")
+ def tearDown(self):
+ if os.path.isdir(test_support.TESTFN):
+ os.rmdir(test_support.TESTFN)
+ elif os.path.isfile(test_support.TESTFN):
+ os.unlink(test_support.TESTFN)
+
class MyOption (Option):
- def check_file (option, opt, value):
+ def check_file(option, opt, value):
if not os.path.exists(value):
raise OptionValueError("%s: file does not exist" % value)
elif not os.path.isfile(value):
TYPE_CHECKER = copy.copy(Option.TYPE_CHECKER)
TYPE_CHECKER["file"] = check_file
- def test_extend_file(self):
+ def test_filetype_ok(self):
open(test_support.TESTFN, "w").close()
self.assertParseOK(["--file", test_support.TESTFN, "-afoo"],
{'file': test_support.TESTFN, 'a': 'foo'},
[])
- os.unlink(test_support.TESTFN)
-
- def test_extend_file_nonexistent(self):
+ def test_filetype_noexist(self):
self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
"%s: file does not exist" %
test_support.TESTFN)
- def test_file_irregular(self):
+ def test_filetype_notfile(self):
os.mkdir(test_support.TESTFN)
self.assertParseFail(["--file", test_support.TESTFN, "-afoo"],
"%s: not a regular file" %
test_support.TESTFN)
- os.rmdir(test_support.TESTFN)
+
class TestExtendAddActions(BaseTest):
def setUp(self):
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
- def take_action (self, action, dest, opt, value, values, parser):
+ def take_action(self, action, dest, opt, value, values, parser):
if action == "extend":
lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue)
callback=lambda: None, type="string",
help="foo")
- expected_help = ("options:\n"
+ expected_help = ("Options:\n"
" -t TEST, --test=TEST foo\n")
self.assertHelp(parser, expected_help)
dest="points", default=[])]
self.parser = OptionParser(option_list=options)
- def process_tuple (self, option, opt, value, parser_, len, type):
+ def process_tuple(self, option, opt, value, parser_, len, type):
self.assertEqual(len, 3)
self.assert_(type is int)
self.parser = OptionParser(option_list=options)
# Callback that meddles in rargs, largs
- def process_n (self, option, opt, value, parser_):
+ def process_n(self, option, opt, value, parser_):
# option is -3, -5, etc.
nargs = int(opt[1:])
rargs = parser_.rargs
callback=self.process_many, type="int")]
self.parser = OptionParser(option_list=options)
- def process_many (self, option, opt, value, parser_):
+ def process_many(self, option, opt, value, parser_):
if opt == "-a":
self.assertEqual(value, ("foo", "bar"))
elif opt == "--apple":
self.parser.add_option("--foo-bar", action="callback",
callback=self.check_abbrev)
- def check_abbrev (self, option, opt, value, parser):
+ def check_abbrev(self, option, opt, value, parser):
self.assertEqual(opt, "--foo-bar")
def test_abbrev_callback_expansion(self):
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
option_list=options)
- def variable_args (self, option, opt, value, parser):
+ def variable_args(self, option, opt, value, parser):
self.assert_(value is None)
done = 0
value = []
self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE,
option_list=options)
- def show_version (self, option, opt, value, parser):
+ def show_version(self, option, opt, value, parser):
parser.values.show_version = 1
class TestConflict(ConflictBase):
def test_conflict_resolve_help(self):
self.assertOutput(["-h"], """\
-options:
+Options:
--verbose increment verbosity
-h, --help show this help message and exit
-v, --version show version
def test_conflict_override_help(self):
self.assertOutput(["-h"], """\
-options:
+Options:
-h, --help show this help message and exit
-n, --dry-run dry run mode
""")
# -- Other testing. ----------------------------------------------------
_expected_help_basic = """\
-usage: bar.py [options]
+Usage: bar.py [options]
-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)
"""
_expected_help_long_opts_first = """\
-usage: bar.py [options]
+Usage: bar.py [options]
-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)
=====
bar.py [options]
-options
+Options
=======
-a APPLE throw APPLEs at basket
--boo=NUM, -b NUM shout "boo!" NUM times (in order to frighten away all the
"""
_expected_help_short_lines = """\
-usage: bar.py [options]
+Usage: bar.py [options]
-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
class TestHelp(BaseTest):
def setUp(self):
- self.orig_columns = os.environ.get('COLUMNS')
self.parser = self.make_parser(80)
- def tearDown(self):
- if self.orig_columns is None:
- del os.environ['COLUMNS']
- else:
- os.environ['COLUMNS'] = self.orig_columns
-
def make_parser(self, columns):
options = [
make_option("-a", type="string", dest='a',
self.assertHelpEquals(_expected_help_basic)
def test_help_old_usage(self):
- self.parser.set_usage("usage: %prog [options]")
+ self.parser.set_usage("Usage: %prog [options]")
self.assertHelpEquals(_expected_help_basic)
def test_help_long_opts_first(self):
group.add_option("-g", action="store_true", help="Group option.")
self.parser.add_option_group(group)
- self.assertHelpEquals("""\
-usage: bar.py [options]
+ expect = """\
+Usage: bar.py [options]
This is the program description for bar.py. bar.py has an option group as
well as single options.
-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)
that some of them bite.
-g Group option.
-""")
+"""
+ self.assertHelpEquals(expect)
+ self.parser.epilog = "Please report bugs to /dev/null."
+ self.assertHelpEquals(expect + "\nPlease report bugs to /dev/null.\n")
class TestMatchAbbrev(BaseTest):
BadOptionError, "ambiguous option: --f (%s?)" % possibilities)
+class TestParseNumber(BaseTest):
+ def setUp(self):
+ self.parser = InterceptingOptionParser()
+ self.parser.add_option("-n", type=int)
+ self.parser.add_option("-l", type=long)
+
+ def test_parse_num_fail(self):
+ self.assertRaises(
+ _parse_num, ("", int), {},
+ ValueError,
+ re.compile(r"invalid literal for int().*: '?'?"))
+ self.assertRaises(
+ _parse_num, ("0xOoops", long), {},
+ ValueError,
+ re.compile(r"invalid literal for long().*: '?0xOoops'?"))
+
+ def test_parse_num_ok(self):
+ self.assertEqual(_parse_num("0", int), 0)
+ self.assertEqual(_parse_num("0x10", int), 16)
+ self.assertEqual(_parse_num("0XA", long), 10L)
+ self.assertEqual(_parse_num("010", long), 8L)
+ self.assertEqual(_parse_num("0b11", int), 3)
+ self.assertEqual(_parse_num("0b", long), 0L)
+
+ def test_numeric_options(self):
+ self.assertParseOK(["-n", "42", "-l", "0x20"],
+ { "n": 42, "l": 0x20 }, [])
+ self.assertParseOK(["-n", "0b0101", "-l010"],
+ { "n": 5, "l": 8 }, [])
+ self.assertParseFail(["-n008"],
+ "option -n: invalid integer value: '008'")
+ self.assertParseFail(["-l0b0123"],
+ "option -l: invalid long integer value: '0b0123'")
+ self.assertParseFail(["-l", "0x12x"],
+ "option -l: invalid long integer value: '0x12x'")
+
+
def _testclasses():
mod = sys.modules[__name__]
return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
Library
-------
+- Updated optparse module to Optik 1.5.1 (allow numeric constants in
+ hex, octal, or binary; add ``append_const`` action; keep going if
+ gettext cannot be imported; added ``OptionParser.destroy()`` method;
+ added ``epilog`` for better help generation).
+
- Bug #1473760: ``tempfile.TemporaryFile()`` could hang on Windows, when
called from a thread spawned as a side effect of importing a module.