Kaydet (Commit) ab05edc0 authored tarafından Greg Ward's avatar Greg Ward

Update optparse to Optik 1.5.1.

üst cdd43280
......@@ -35,9 +35,9 @@ With these few lines of code, users of your script can now do the
\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
......@@ -100,8 +100,8 @@ options; the traditional \UNIX{} syntax is a hyphen (``-'') followed by a
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:
......@@ -170,7 +170,7 @@ For example, consider this hypothetical command-line:
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.
......@@ -287,12 +287,12 @@ but that's rarely necessary: by default it uses \code{sys.argv{[}1:]}.)
\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}
......@@ -309,7 +309,7 @@ command line. There is a fixed set of actions hard-coded into \module{optparse}
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}.
......@@ -333,8 +333,8 @@ args = ["-f", "foo.txt"]
\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}.
......@@ -379,7 +379,7 @@ types is covered in section~\ref{optparse-extending}, Extending \module{optparse
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")
......@@ -421,7 +421,7 @@ want more control. \module{optparse} lets you supply a default value for each
destination, which is assigned before the command line is parsed.
First, consider the verbose/quiet example. If we want \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")
......@@ -441,7 +441,7 @@ parser.add_option("-v", action="store_true", dest="verbose", default=False)
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.
......@@ -566,7 +566,7 @@ argument to OptionParser:
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
......@@ -580,14 +580,14 @@ foo 1.0
\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
......@@ -659,12 +659,66 @@ def main():
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
......@@ -708,38 +762,34 @@ strings, e.g. \programopt{-f} and \longprogramopt{file}. You can
specify any number of short or long option strings, but you must specify
at least one overall option string.
The canonical way to create an 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}]
......@@ -748,6 +798,8 @@ store a true value
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}]
......@@ -762,24 +814,25 @@ action, you may also supply \member{type} and \member{dest} option attributes; s
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:
......@@ -790,8 +843,7 @@ 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}
......@@ -911,6 +963,13 @@ If, a little later on, \code{"-{}-tracks=4"} is seen, it does:
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}]
......@@ -939,14 +998,9 @@ options.verbosity += 1
\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.
......@@ -956,7 +1010,7 @@ 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
......@@ -1007,6 +1061,87 @@ constructor. As with \member{help} options, you will rarely create
\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},
......@@ -1017,22 +1152,74 @@ Arguments to string options are not checked or converted in any way: the
text on the command line is stored in the destination (or passed to the
callback) as-is.
Integer arguments 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}}
......@@ -1050,9 +1237,8 @@ Returns the Option instance with the option string \code{opt{\_}str}, or
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}
......@@ -1074,20 +1260,20 @@ options. If it finds any, it invokes the current conflict-handling
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}
......@@ -1131,7 +1317,78 @@ options:
-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}}
......@@ -1234,7 +1491,7 @@ its instance attributes:
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
......@@ -1260,7 +1517,7 @@ is a dictionary of arbitrary keyword arguments supplied via
\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
......
......@@ -16,7 +16,7 @@ For support, use the optik-users@lists.sourceforge.net mailing list
# 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',
......@@ -35,8 +35,8 @@ __all__ = ['Option',
'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
......@@ -67,21 +67,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
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):
......@@ -120,8 +125,25 @@ class OptionValueError (OptParseError):
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:
......@@ -223,15 +245,30 @@ 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:
......@@ -328,7 +365,7 @@ class IndentedHelpFormatter (HelpFormatter):
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)
......@@ -353,8 +390,27 @@ class TitledHelpFormatter (HelpFormatter):
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")) }
......@@ -422,6 +478,7 @@ class Option:
"store_true",
"store_false",
"append",
"append_const",
"count",
"callback",
"help",
......@@ -435,6 +492,7 @@ class Option:
"store_true",
"store_false",
"append",
"append_const",
"count")
# The set of actions for which it makes sense to supply a value
......@@ -448,6 +506,10 @@ class Option:
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")
......@@ -572,9 +634,17 @@ class Option:
# 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"
......@@ -589,7 +659,7 @@ class Option:
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)
......@@ -613,7 +683,7 @@ class Option:
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)
......@@ -633,12 +703,12 @@ class Option:
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)
......@@ -720,6 +790,8 @@ class Option:
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":
......@@ -748,11 +820,9 @@ try:
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:
......@@ -766,16 +836,13 @@ 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):
"""
......@@ -893,6 +960,13 @@ class OptionContainer:
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):
......@@ -926,7 +1000,7 @@ class OptionContainer:
"""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]
......@@ -1018,6 +1092,11 @@ class OptionGroup (OptionContainer):
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):
......@@ -1044,6 +1123,8 @@ class OptionParser (OptionContainer):
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
......@@ -1102,7 +1183,8 @@ class OptionParser (OptionContainer):
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)
......@@ -1114,6 +1196,7 @@ class OptionParser (OptionContainer):
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'
......@@ -1124,6 +1207,22 @@ class OptionParser (OptionContainer):
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)
......@@ -1167,7 +1266,7 @@ class OptionParser (OptionContainer):
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
......@@ -1201,7 +1300,7 @@ class OptionParser (OptionContainer):
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)
......@@ -1212,7 +1311,7 @@ class OptionParser (OptionContainer):
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]
......@@ -1276,7 +1375,7 @@ class OptionParser (OptionContainer):
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)
......@@ -1401,7 +1500,7 @@ class OptionParser (OptionContainer):
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.
......@@ -1501,7 +1600,7 @@ class OptionParser (OptionContainer):
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))
......@@ -1513,6 +1612,9 @@ class OptionParser (OptionContainer):
# 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
......@@ -1522,6 +1624,7 @@ class OptionParser (OptionContainer):
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):
......@@ -1555,11 +1658,10 @@ def _match_abbrev(s, wordmap):
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
......
......@@ -10,17 +10,22 @@
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:
......@@ -28,6 +33,7 @@ try:
except NameError:
(True, False) = (1, 0)
retype = type(re.compile(''))
class InterceptedError(Exception):
def __init__(self,
......@@ -96,7 +102,8 @@ Args were %(args)s.""" % locals ())
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.
"""
......@@ -109,14 +116,23 @@ Args were %(args)s.""" % locals ())
func(*args, **kwargs)
except expected_exception, err:
actual_message = str(err)
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:
......@@ -157,7 +173,9 @@ and kwargs %(kwargs)r
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:
......@@ -366,6 +384,23 @@ class TestOptionParser(BaseTest):
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
......@@ -391,13 +426,21 @@ class TestTypeAliases(BaseTest):
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.
......@@ -487,13 +530,13 @@ class TestProgName(BaseTest):
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:
......@@ -505,7 +548,7 @@ class TestProgName(BaseTest):
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")
......@@ -515,9 +558,9 @@ class TestExpandDefaults(BaseTest):
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]"
......@@ -699,13 +742,16 @@ class TestStandard(BaseTest):
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"]},
["-"])
......@@ -870,6 +916,8 @@ class TestMultipleArgsAppend(BaseTest):
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"],
......@@ -885,6 +933,11 @@ class TestMultipleArgsAppend(BaseTest):
{'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,
......@@ -960,8 +1013,14 @@ class TestExtendAddTypes(BaseTest):
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):
......@@ -972,25 +1031,23 @@ class TestExtendAddTypes(BaseTest):
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):
......@@ -1003,7 +1060,7 @@ class TestExtendAddActions(BaseTest):
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)
......@@ -1072,7 +1129,7 @@ class TestCallback(BaseTest):
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)
......@@ -1085,7 +1142,7 @@ class TestCallbackExtraArgs(BaseTest):
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)
......@@ -1110,7 +1167,7 @@ class TestCallbackMeddleArgs(BaseTest):
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
......@@ -1139,7 +1196,7 @@ class TestCallbackManyArgs(BaseTest):
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":
......@@ -1162,7 +1219,7 @@ class TestCallbackCheckAbbrev(BaseTest):
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):
......@@ -1177,7 +1234,7 @@ class TestCallbackVarArgs(BaseTest):
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 = []
......@@ -1229,7 +1286,7 @@ class ConflictBase(BaseTest):
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):
......@@ -1280,7 +1337,7 @@ class TestConflictResolve(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
......@@ -1319,7 +1376,7 @@ class TestConflictOverride(BaseTest):
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
""")
......@@ -1332,9 +1389,9 @@ options:
# -- 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)
......@@ -1343,9 +1400,9 @@ options:
"""
_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)
......@@ -1358,7 +1415,7 @@ 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
......@@ -1368,9 +1425,9 @@ options
"""
_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
......@@ -1382,15 +1439,8 @@ options:
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',
......@@ -1419,7 +1469,7 @@ class TestHelp(BaseTest):
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):
......@@ -1449,13 +1499,13 @@ class TestHelp(BaseTest):
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)
......@@ -1467,9 +1517,12 @@ options:
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):
......@@ -1490,6 +1543,43 @@ 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')]
......
......@@ -86,6 +86,11 @@ Extension Modules
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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment