Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 446a25f

Browse files
committed
Patch 473512: add GNU style scanning as gnu_getopt.
1 parent cdbc131 commit 446a25f

5 files changed

Lines changed: 103 additions & 2 deletions

File tree

Doc/lib/libgetopt.tex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ \section{\module{getopt} ---
5555
mixed.
5656
\end{funcdesc}
5757

58+
\begin{funcdesc}{gnu_getopt}{args, options\optional{, long_options}}
59+
This function works like \function{getopt()}, except that GNU style
60+
scanning mode is used by default. This means that option and
61+
non-option arguments may be intermixed. The \function{getopt()}
62+
function stops processing options as soon as a non-option argument is
63+
encountered.
64+
65+
If the first character of the option string is `+', or if the
66+
environment variable POSIXLY_CORRECT is set, then option processing
67+
stops as soon as a non-option argument is encountered.
68+
\end{funcdesc}
69+
5870
\begin{excdesc}{GetoptError}
5971
This is raised when an unrecognized option is found in the argument
6072
list or when an option requiring an argument is given none.

Lib/getopt.py

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,36 @@
55
function (including the special meanings of arguments of the form `-'
66
and `--'). Long options similar to those supported by GNU software
77
may be used as well via an optional third argument. This module
8-
provides a single function and an exception:
8+
provides two functions and an exception:
99
1010
getopt() -- Parse command line options
11+
gnu_getopt() -- Like getopt(), but allow option and non-option arguments
12+
to be intermixed.
1113
GetoptError -- exception (class) raised with 'opt' attribute, which is the
1214
option involved with the exception.
1315
"""
1416

1517
# Long option support added by Lars Wirzenius <[email protected]>.
16-
18+
#
1719
# Gerrit Holl <[email protected]> moved the string-based exceptions
1820
# to class-based exceptions.
21+
#
22+
# Peter Åstrand <[email protected]> added gnu_getopt().
23+
#
24+
# TODO for gnu_getopt():
25+
#
26+
# - GNU getopt_long_only mechanism
27+
# - allow the caller to specify ordering
28+
# - RETURN_IN_ORDER option
29+
# - GNU extension with '-' as first character of option string
30+
# - optional arguments, specified by double colons
31+
# - a option string with a W followed by semicolon should
32+
# treat "-W foo" as "--foo"
1933

2034
__all__ = ["GetoptError","error","getopt"]
2135

36+
import os
37+
2238
class GetoptError(Exception):
2339
opt = ''
2440
msg = ''
@@ -75,6 +91,56 @@ def getopt(args, shortopts, longopts = []):
7591

7692
return opts, args
7793

94+
def gnu_getopt(args, shortopts, longopts = []):
95+
"""getopt(args, options[, long_options]) -> opts, args
96+
97+
This function works like getopt(), except that GNU style scanning
98+
mode is used by default. This means that option and non-option
99+
arguments may be intermixed. The getopt() function stops
100+
processing options as soon as a non-option argument is
101+
encountered.
102+
103+
If the first character of the option string is `+', or if the
104+
environment variable POSIXLY_CORRECT is set, then option
105+
processing stops as soon as a non-option argument is encountered.
106+
107+
"""
108+
109+
opts = []
110+
prog_args = []
111+
if type(longopts) == type(""):
112+
longopts = [longopts]
113+
else:
114+
longopts = list(longopts)
115+
116+
# Allow options after non-option arguments?
117+
if shortopts.startswith('+'):
118+
shortopts = shortopts[1:]
119+
all_options_first = 1
120+
elif os.getenv("POSIXLY_CORRECT"):
121+
all_options_first = 1
122+
else:
123+
all_options_first = 0
124+
125+
while args:
126+
if args[0] == '--':
127+
prog_args += args[1:]
128+
break
129+
130+
if args[0][:2] == '--':
131+
opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
132+
elif args[0][:1] == '-':
133+
opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
134+
else:
135+
if all_options_first:
136+
prog_args += args
137+
break
138+
else:
139+
prog_args.append(args[0])
140+
args = args[1:]
141+
142+
return opts, prog_args
143+
78144
def do_longs(opts, opt, longopts, args):
79145
try:
80146
i = opt.index('=')

Lib/test/test_getopt.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import getopt
55
from getopt import GetoptError
66
from test_support import verify, verbose
7+
import os
78

89
def expectException(teststr, expected, failure=AssertionError):
910
"""Executes a statement passed in teststr, and raises an exception
@@ -106,5 +107,24 @@ def expectException(teststr, expected, failure=AssertionError):
106107
"opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])",
107108
GetoptError)
108109

110+
# Test handling of GNU style scanning mode.
111+
if verbose:
112+
print 'Running tests on getopt.gnu_getopt'
113+
cmdline = ['-a', 'arg1', '-b', '1', '--alpha', '--beta=2']
114+
# GNU style
115+
opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
116+
verify(opts == [('-a', ''), ('-b', '1'), ('--alpha', ''), ('--beta', '2')])
117+
verify(args == ['arg1'])
118+
# Posix style via +
119+
opts, args = getopt.gnu_getopt(cmdline, '+ab:', ['alpha', 'beta='])
120+
verify(opts == [('-a', '')])
121+
verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
122+
# Posix style via POSIXLY_CORRECT
123+
os.environ["POSIXLY_CORRECT"] = "1"
124+
opts, args = getopt.gnu_getopt(cmdline, 'ab:', ['alpha', 'beta='])
125+
verify(opts == [('-a', '')])
126+
verify(args == ['arg1', '-b', '1', '--alpha', '--beta=2'])
127+
128+
109129
if verbose:
110130
print "Module getopt: tests completed successfully."

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Oliver Andrich
2020
Ross Andrus
2121
Jason Asbahr
2222
David Ascher
23+
Peter �strand
2324
John Aycock
2425
Donovan Baarda
2526
Alfonso Baciero

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ Extension modules
130130

131131
Library
132132

133+
- getopt.gnu_getopt was added.
134+
133135
- Stop using strings for exceptions. String objects used for
134136
exceptions are now classes deriving from Exception. The objects
135137
changed were: Tkinter.TclError, bdb.BdbQuit, macpath.norm_error,

0 commit comments

Comments
 (0)