Patch 473512: add GNU style scanning as gnu_getopt.

This commit is contained in:
Martin v. Löwis 2002-06-06 10:58:36 +00:00
parent cdbc131f03
commit 446a25fa3c
5 changed files with 103 additions and 2 deletions

View File

@ -55,6 +55,18 @@ thus allowing multiple occurrences. Long and short options may be
mixed. mixed.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{gnu_getopt}{args, options\optional{, long_options}}
This function works like \function{getopt()}, except that GNU style
scanning mode is used by default. This means that option and
non-option arguments may be intermixed. The \function{getopt()}
function stops processing options as soon as a non-option argument is
encountered.
If the first character of the option string is `+', or if the
environment variable POSIXLY_CORRECT is set, then option processing
stops as soon as a non-option argument is encountered.
\end{funcdesc}
\begin{excdesc}{GetoptError} \begin{excdesc}{GetoptError}
This is raised when an unrecognized option is found in the argument This is raised when an unrecognized option is found in the argument
list or when an option requiring an argument is given none. list or when an option requiring an argument is given none.

View File

@ -5,20 +5,36 @@ sys.argv. It supports the same conventions as the Unix getopt()
function (including the special meanings of arguments of the form `-' function (including the special meanings of arguments of the form `-'
and `--'). Long options similar to those supported by GNU software and `--'). Long options similar to those supported by GNU software
may be used as well via an optional third argument. This module may be used as well via an optional third argument. This module
provides a single function and an exception: provides two functions and an exception:
getopt() -- Parse command line options getopt() -- Parse command line options
gnu_getopt() -- Like getopt(), but allow option and non-option arguments
to be intermixed.
GetoptError -- exception (class) raised with 'opt' attribute, which is the GetoptError -- exception (class) raised with 'opt' attribute, which is the
option involved with the exception. option involved with the exception.
""" """
# Long option support added by Lars Wirzenius <liw@iki.fi>. # Long option support added by Lars Wirzenius <liw@iki.fi>.
#
# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions # Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions
# to class-based exceptions. # to class-based exceptions.
#
# Peter Åstrand <astrand@lysator.liu.se> added gnu_getopt().
#
# TODO for gnu_getopt():
#
# - GNU getopt_long_only mechanism
# - allow the caller to specify ordering
# - RETURN_IN_ORDER option
# - GNU extension with '-' as first character of option string
# - optional arguments, specified by double colons
# - a option string with a W followed by semicolon should
# treat "-W foo" as "--foo"
__all__ = ["GetoptError","error","getopt"] __all__ = ["GetoptError","error","getopt"]
import os
class GetoptError(Exception): class GetoptError(Exception):
opt = '' opt = ''
msg = '' msg = ''
@ -75,6 +91,56 @@ def getopt(args, shortopts, longopts = []):
return opts, args return opts, args
def gnu_getopt(args, shortopts, longopts = []):
"""getopt(args, options[, long_options]) -> opts, args
This function works like getopt(), except that GNU style scanning
mode is used by default. This means that option and non-option
arguments may be intermixed. The getopt() function stops
processing options as soon as a non-option argument is
encountered.
If the first character of the option string is `+', or if the
environment variable POSIXLY_CORRECT is set, then option
processing stops as soon as a non-option argument is encountered.
"""
opts = []
prog_args = []
if type(longopts) == type(""):
longopts = [longopts]
else:
longopts = list(longopts)
# Allow options after non-option arguments?
if shortopts.startswith('+'):
shortopts = shortopts[1:]
all_options_first = 1
elif os.getenv("POSIXLY_CORRECT"):
all_options_first = 1
else:
all_options_first = 0
while args:
if args[0] == '--':
prog_args += args[1:]
break
if args[0][:2] == '--':
opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
elif args[0][:1] == '-':
opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
else:
if all_options_first:
prog_args += args
break
else:
prog_args.append(args[0])
args = args[1:]
return opts, prog_args
def do_longs(opts, opt, longopts, args): def do_longs(opts, opt, longopts, args):
try: try:
i = opt.index('=') i = opt.index('=')

View File

@ -4,6 +4,7 @@
import getopt import getopt
from getopt import GetoptError from getopt import GetoptError
from test_support import verify, verbose from test_support import verify, verbose
import os
def expectException(teststr, expected, failure=AssertionError): def expectException(teststr, expected, failure=AssertionError):
"""Executes a statement passed in teststr, and raises an exception """Executes a statement passed in teststr, and raises an exception
@ -106,5 +107,24 @@ expectException(
"opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])", "opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])",
GetoptError) GetoptError)
# Test handling of GNU style scanning mode.
if verbose:
print 'Running tests on getopt.gnu_getopt'
cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2']
# GNU style
opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
verify(opts == [('-a', ''), ('-b', '1'), ('--alpha', ''), ('--beta', '2')])
verify(args == ['arg1'])
# Posix style via +
opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
verify(opts == [('-a', '')])
verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
# Posix style via POSIXLY_CORRECT
os.environ["POSIXLY_CORRECT"] = "1"
opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
verify(opts == [('-a', '')])
verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
if verbose: if verbose:
print "Module getopt: tests completed successfully." print "Module getopt: tests completed successfully."

View File

@ -20,6 +20,7 @@ Oliver Andrich
Ross Andrus Ross Andrus
Jason Asbahr Jason Asbahr
David Ascher David Ascher
Peter Åstrand
John Aycock John Aycock
Donovan Baarda Donovan Baarda
Alfonso Baciero Alfonso Baciero

View File

@ -130,6 +130,8 @@ Extension modules
Library Library
- getopt.gnu_getopt was added.
- Stop using strings for exceptions. String objects used for - Stop using strings for exceptions. String objects used for
exceptions are now classes deriving from Exception. The objects exceptions are now classes deriving from Exception. The objects
changed were: Tkinter.TclError, bdb.BdbQuit, macpath.norm_error, changed were: Tkinter.TclError, bdb.BdbQuit, macpath.norm_error,