diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2002-06-06 10:58:36 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2002-06-06 10:58:36 (GMT) |
commit | 446a25fa3ca845315259f0f491e8e3a239ff2a65 (patch) | |
tree | 3d8cea0ecdb486c6006d369fc03b587b3a38d0c6 /Lib | |
parent | cdbc131f0370f6e3712d4167ba987d5e6b7f2802 (diff) | |
download | cpython-446a25fa3ca845315259f0f491e8e3a239ff2a65.zip cpython-446a25fa3ca845315259f0f491e8e3a239ff2a65.tar.gz cpython-446a25fa3ca845315259f0f491e8e3a239ff2a65.tar.bz2 |
Patch 473512: add GNU style scanning as gnu_getopt.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/getopt.py | 70 | ||||
-rw-r--r-- | Lib/test/test_getopt.py | 20 |
2 files changed, 88 insertions, 2 deletions
diff --git a/Lib/getopt.py b/Lib/getopt.py index 91584fe..3e8b7c2 100644 --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -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 `-' and `--'). Long options similar to those supported by GNU software 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 +gnu_getopt() -- Like getopt(), but allow option and non-option arguments +to be intermixed. GetoptError -- exception (class) raised with 'opt' attribute, which is the option involved with the exception. """ # Long option support added by Lars Wirzenius <liw@iki.fi>. - +# # Gerrit Holl <gerrit@nl.linux.org> moved the string-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"] +import os + class GetoptError(Exception): opt = '' msg = '' @@ -75,6 +91,56 @@ def getopt(args, shortopts, longopts = []): 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): try: i = opt.index('=') diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index f8989f1..e2ae9fe 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -4,6 +4,7 @@ import getopt from getopt import GetoptError from test_support import verify, verbose +import os def expectException(teststr, expected, failure=AssertionError): """Executes a statement passed in teststr, and raises an exception @@ -106,5 +107,24 @@ expectException( "opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])", 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: print "Module getopt: tests completed successfully." |