blob: 980861d2517253da92c414e669ba03a1a67eb542 [file] [log] [blame]
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +00001"""Parser for command line options.
Guido van Rossumc6360141990-10-13 19:23:40 +00002
Guido van Rossum6d060941998-11-17 04:16:37 +00003This module helps scripts to parse the command line arguments in
4sys.argv. It supports the same conventions as the Unix getopt()
5function (including the special meanings of arguments of the form `-'
6and `--'). Long options similar to those supported by GNU software
7may be used as well via an optional third argument. This module
Martin v. Löwis446a25f2002-06-06 10:58:36 +00008provides two functions and an exception:
Guido van Rossumc6360141990-10-13 19:23:40 +00009
Guido van Rossum6d060941998-11-17 04:16:37 +000010getopt() -- Parse command line options
Martin v. Löwis446a25f2002-06-06 10:58:36 +000011gnu_getopt() -- Like getopt(), but allow option and non-option arguments
Tim Petersc411dba2002-07-16 21:35:23 +000012to be intermixed.
Guido van Rossum80c33e51999-12-21 22:38:40 +000013GetoptError -- exception (class) raised with 'opt' attribute, which is the
14option involved with the exception.
Guido van Rossum6d060941998-11-17 04:16:37 +000015"""
Guido van Rossum1550ff71996-09-11 19:43:52 +000016
Guido van Rossum6d060941998-11-17 04:16:37 +000017# Long option support added by Lars Wirzenius <liw@iki.fi>.
Martin v. Löwis446a25f2002-06-06 10:58:36 +000018#
Fred Drakea395ced2000-02-25 16:14:08 +000019# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions
20# to class-based exceptions.
Martin v. Löwis446a25f2002-06-06 10:58:36 +000021#
Guido van Rossumd77d6992007-07-16 23:10:57 +000022# Peter Åstrand <astrand@lysator.liu.se> added gnu_getopt().
Martin v. Löwis446a25f2002-06-06 10:58:36 +000023#
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"
Fred Drakea395ced2000-02-25 16:14:08 +000033
Skip Montanaro96803b22002-06-07 03:26:43 +000034__all__ = ["GetoptError","error","getopt","gnu_getopt"]
Skip Montanaroeccd02a2001-01-20 23:34:12 +000035
Martin v. Löwis446a25f2002-06-06 10:58:36 +000036import os
37
Guido van Rossum80c33e51999-12-21 22:38:40 +000038class GetoptError(Exception):
39 opt = ''
40 msg = ''
Andrew M. Kuchling01892662003-02-06 19:52:56 +000041 def __init__(self, msg, opt=''):
Fred Drakee1fd5262001-01-08 15:39:32 +000042 self.msg = msg
43 self.opt = opt
44 Exception.__init__(self, msg, opt)
Guido van Rossum80c33e51999-12-21 22:38:40 +000045
46 def __str__(self):
47 return self.msg
48
49error = GetoptError # backward compatibility
Guido van Rossumc6360141990-10-13 19:23:40 +000050
Guido van Rossum2c349bb1996-09-09 15:48:24 +000051def getopt(args, shortopts, longopts = []):
Guido van Rossum6d060941998-11-17 04:16:37 +000052 """getopt(args, options[, long_options]) -> opts, args
53
54 Parses command line options and parameter list. args is the
55 argument list to be parsed, without the leading reference to the
56 running program. Typically, this means "sys.argv[1:]". shortopts
57 is the string of option letters that the script wants to
58 recognize, with options that require an argument followed by a
59 colon (i.e., the same format that Unix getopt() uses). If
60 specified, longopts is a list of strings with the names of the
61 long options which should be supported. The leading '--'
62 characters should not be included in the option name. Options
63 which require an argument should be followed by an equal sign
64 ('=').
65
66 The return value consists of two elements: the first is a list of
67 (option, value) pairs; the second is the list of program arguments
68 left after the option list was stripped (this is a trailing slice
69 of the first argument). Each option-and-value pair returned has
70 the option as its first element, prefixed with a hyphen (e.g.,
71 '-x'), and the option argument as its second element, or an empty
72 string if the option has no argument. The options occur in the
73 list in the same order in which they were found, thus allowing
74 multiple occurrences. Long and short options may be mixed.
75
76 """
77
78 opts = []
79 if type(longopts) == type(""):
80 longopts = [longopts]
81 else:
82 longopts = list(longopts)
Tim Petersdd699b62000-12-27 08:05:05 +000083 while args and args[0].startswith('-') and args[0] != '-':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000084 if args[0] == '--':
85 args = args[1:]
86 break
Fred Drake1e7dfd32001-12-12 06:20:34 +000087 if args[0].startswith('--'):
Guido van Rossum6d060941998-11-17 04:16:37 +000088 opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000089 else:
Guido van Rossum6d060941998-11-17 04:16:37 +000090 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
Guido van Rossumc6360141990-10-13 19:23:40 +000091
Guido van Rossum6d060941998-11-17 04:16:37 +000092 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +000093
Martin v. Löwis446a25f2002-06-06 10:58:36 +000094def 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.
Tim Petersc411dba2002-07-16 21:35:23 +0000106
Martin v. Löwis446a25f2002-06-06 10:58:36 +0000107 """
108
109 opts = []
110 prog_args = []
Martin v. Löwis33b77de2002-06-06 18:14:50 +0000111 if isinstance(longopts, str):
Martin v. Löwis446a25f2002-06-06 10:58:36 +0000112 longopts = [longopts]
113 else:
114 longopts = list(longopts)
115
116 # Allow options after non-option arguments?
117 if shortopts.startswith('+'):
118 shortopts = shortopts[1:]
Martin v. Löwis33b77de2002-06-06 18:14:50 +0000119 all_options_first = True
Jack Jansenf03c6922002-07-26 11:34:49 +0000120 elif os.environ.get("POSIXLY_CORRECT"):
Martin v. Löwis33b77de2002-06-06 18:14:50 +0000121 all_options_first = True
Martin v. Löwis446a25f2002-06-06 10:58:36 +0000122 else:
Martin v. Löwis33b77de2002-06-06 18:14:50 +0000123 all_options_first = False
Martin v. Löwis446a25f2002-06-06 10:58:36 +0000124
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:])
Georg Brandleee31162008-12-07 15:15:22 +0000132 elif args[0][:1] == '-' and args[0] != '-':
Martin v. Löwis446a25f2002-06-06 10:58:36 +0000133 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
Guido van Rossum6d060941998-11-17 04:16:37 +0000144def do_longs(opts, opt, longopts, args):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000145 try:
Fred Drakea395ced2000-02-25 16:14:08 +0000146 i = opt.index('=')
Guido van Rossum1550ff71996-09-11 19:43:52 +0000147 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000148 optarg = None
Tim Petersdd699b62000-12-27 08:05:05 +0000149 else:
150 opt, optarg = opt[:i], opt[i+1:]
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000151
Guido van Rossum1550ff71996-09-11 19:43:52 +0000152 has_arg, opt = long_has_args(opt, longopts)
153 if has_arg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000154 if optarg is None:
155 if not args:
Guido van Rossum80c33e51999-12-21 22:38:40 +0000156 raise GetoptError('option --%s requires argument' % opt, opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000157 optarg, args = args[0], args[1:]
Victor Stinnereccc5fa2010-07-24 00:49:20 +0000158 elif optarg is not None:
Guido van Rossum80c33e51999-12-21 22:38:40 +0000159 raise GetoptError('option --%s must not have an argument' % opt, opt)
Guido van Rossum6d060941998-11-17 04:16:37 +0000160 opts.append(('--' + opt, optarg or ''))
161 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000162
163# Return:
164# has_arg?
165# full option name
166def long_has_args(opt, longopts):
Tim Petersd31b6322000-12-29 02:17:56 +0000167 possibilities = [o for o in longopts if o.startswith(opt)]
168 if not possibilities:
Tim Petersdd699b62000-12-27 08:05:05 +0000169 raise GetoptError('option --%s not recognized' % opt, opt)
Tim Petersdd699b62000-12-27 08:05:05 +0000170 # Is there an exact match?
171 if opt in possibilities:
Tim Petersbc0e9102002-04-04 22:55:58 +0000172 return False, opt
Tim Petersdd699b62000-12-27 08:05:05 +0000173 elif opt + '=' in possibilities:
Tim Petersbc0e9102002-04-04 22:55:58 +0000174 return True, opt
Tim Petersdd699b62000-12-27 08:05:05 +0000175 # No exact match, so better be unique.
176 if len(possibilities) > 1:
177 # XXX since possibilities contains all valid continuations, might be
178 # nice to work them into the error msg
179 raise GetoptError('option --%s not a unique prefix' % opt, opt)
180 assert len(possibilities) == 1
181 unique_match = possibilities[0]
182 has_arg = unique_match.endswith('=')
183 if has_arg:
184 unique_match = unique_match[:-1]
185 return has_arg, unique_match
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000186
Guido van Rossum6d060941998-11-17 04:16:37 +0000187def do_shorts(opts, optstring, shortopts, args):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000188 while optstring != '':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000189 opt, optstring = optstring[0], optstring[1:]
190 if short_has_arg(opt, shortopts):
191 if optstring == '':
192 if not args:
Fred Drake1e7dfd32001-12-12 06:20:34 +0000193 raise GetoptError('option -%s requires argument' % opt,
194 opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000195 optstring, args = args[0], args[1:]
196 optarg, optstring = optstring, ''
197 else:
198 optarg = ''
Guido van Rossum6d060941998-11-17 04:16:37 +0000199 opts.append(('-' + opt, optarg))
200 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000201
202def short_has_arg(opt, shortopts):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000203 for i in range(len(shortopts)):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000204 if opt == shortopts[i] != ':':
Fred Drake1e7dfd32001-12-12 06:20:34 +0000205 return shortopts.startswith(':', i+1)
Guido van Rossum80c33e51999-12-21 22:38:40 +0000206 raise GetoptError('option -%s not recognized' % opt, opt)
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000207
208if __name__ == '__main__':
Guido van Rossum1550ff71996-09-11 19:43:52 +0000209 import sys
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000210 print(getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]))