blob: c93aad179c5d580c7dd614094b1634883486f9a0 [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
8provides a single function 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
Guido van Rossum80c33e51999-12-21 22:38:40 +000011GetoptError -- exception (class) raised with 'opt' attribute, which is the
12option involved with the exception.
Guido van Rossum6d060941998-11-17 04:16:37 +000013"""
Guido van Rossum1550ff71996-09-11 19:43:52 +000014
Guido van Rossum6d060941998-11-17 04:16:37 +000015# Long option support added by Lars Wirzenius <liw@iki.fi>.
Guido van Rossumc6360141990-10-13 19:23:40 +000016
Fred Drakea395ced2000-02-25 16:14:08 +000017# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions
18# to class-based exceptions.
19
Guido van Rossum80c33e51999-12-21 22:38:40 +000020class GetoptError(Exception):
21 opt = ''
22 msg = ''
23 def __init__(self, *args):
24 self.args = args
25 if len(args) == 1:
26 self.msg = args[0]
27 elif len(args) == 2:
28 self.msg = args[0]
29 self.opt = args[1]
30
31 def __str__(self):
32 return self.msg
33
34error = GetoptError # backward compatibility
Guido van Rossumc6360141990-10-13 19:23:40 +000035
Guido van Rossum2c349bb1996-09-09 15:48:24 +000036def getopt(args, shortopts, longopts = []):
Guido van Rossum6d060941998-11-17 04:16:37 +000037 """getopt(args, options[, long_options]) -> opts, args
38
39 Parses command line options and parameter list. args is the
40 argument list to be parsed, without the leading reference to the
41 running program. Typically, this means "sys.argv[1:]". shortopts
42 is the string of option letters that the script wants to
43 recognize, with options that require an argument followed by a
44 colon (i.e., the same format that Unix getopt() uses). If
45 specified, longopts is a list of strings with the names of the
46 long options which should be supported. The leading '--'
47 characters should not be included in the option name. Options
48 which require an argument should be followed by an equal sign
49 ('=').
50
51 The return value consists of two elements: the first is a list of
52 (option, value) pairs; the second is the list of program arguments
53 left after the option list was stripped (this is a trailing slice
54 of the first argument). Each option-and-value pair returned has
55 the option as its first element, prefixed with a hyphen (e.g.,
56 '-x'), and the option argument as its second element, or an empty
57 string if the option has no argument. The options occur in the
58 list in the same order in which they were found, thus allowing
59 multiple occurrences. Long and short options may be mixed.
60
61 """
62
63 opts = []
64 if type(longopts) == type(""):
65 longopts = [longopts]
66 else:
67 longopts = list(longopts)
Guido van Rossum1550ff71996-09-11 19:43:52 +000068 longopts.sort()
Tim Petersdd699b62000-12-27 08:05:05 +000069 while args and args[0].startswith('-') and args[0] != '-':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000070 if args[0] == '--':
71 args = args[1:]
72 break
73 if args[0][:2] == '--':
Guido van Rossum6d060941998-11-17 04:16:37 +000074 opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000075 else:
Guido van Rossum6d060941998-11-17 04:16:37 +000076 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
Guido van Rossumc6360141990-10-13 19:23:40 +000077
Guido van Rossum6d060941998-11-17 04:16:37 +000078 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +000079
Guido van Rossum6d060941998-11-17 04:16:37 +000080def do_longs(opts, opt, longopts, args):
Guido van Rossum1550ff71996-09-11 19:43:52 +000081 try:
Fred Drakea395ced2000-02-25 16:14:08 +000082 i = opt.index('=')
Guido van Rossum1550ff71996-09-11 19:43:52 +000083 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000084 optarg = None
Tim Petersdd699b62000-12-27 08:05:05 +000085 else:
86 opt, optarg = opt[:i], opt[i+1:]
Guido van Rossum2c349bb1996-09-09 15:48:24 +000087
Guido van Rossum1550ff71996-09-11 19:43:52 +000088 has_arg, opt = long_has_args(opt, longopts)
89 if has_arg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000090 if optarg is None:
91 if not args:
Guido van Rossum80c33e51999-12-21 22:38:40 +000092 raise GetoptError('option --%s requires argument' % opt, opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000093 optarg, args = args[0], args[1:]
Guido van Rossum1550ff71996-09-11 19:43:52 +000094 elif optarg:
Guido van Rossum80c33e51999-12-21 22:38:40 +000095 raise GetoptError('option --%s must not have an argument' % opt, opt)
Guido van Rossum6d060941998-11-17 04:16:37 +000096 opts.append(('--' + opt, optarg or ''))
97 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +000098
99# Return:
100# has_arg?
101# full option name
Tim Petersdd699b62000-12-27 08:05:05 +0000102# Assumes longopts has been sorted (ASCII order).
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000103def long_has_args(opt, longopts):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000104 for i in range(len(longopts)):
Tim Petersdd699b62000-12-27 08:05:05 +0000105 if longopts[i].startswith(opt):
106 break
107 else:
108 raise GetoptError('option --%s not recognized' % opt, opt)
109 # opt is a prefix of longopts[i]; find j s.t. opt is a prefix of
110 # each possibility in longopts[i:j]
111 j = i+1
112 while j < len(longopts) and longopts[j].startswith(opt):
113 j += 1
114 possibilities = longopts[i:j]
115 # Is there an exact match?
116 if opt in possibilities:
117 return 0, opt
118 elif opt + '=' in possibilities:
119 return 1, opt
120 # No exact match, so better be unique.
121 if len(possibilities) > 1:
122 # XXX since possibilities contains all valid continuations, might be
123 # nice to work them into the error msg
124 raise GetoptError('option --%s not a unique prefix' % opt, opt)
125 assert len(possibilities) == 1
126 unique_match = possibilities[0]
127 has_arg = unique_match.endswith('=')
128 if has_arg:
129 unique_match = unique_match[:-1]
130 return has_arg, unique_match
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000131
Guido van Rossum6d060941998-11-17 04:16:37 +0000132def do_shorts(opts, optstring, shortopts, args):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000133 while optstring != '':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000134 opt, optstring = optstring[0], optstring[1:]
135 if short_has_arg(opt, shortopts):
136 if optstring == '':
137 if not args:
Guido van Rossum80c33e51999-12-21 22:38:40 +0000138 raise GetoptError('option -%s requires argument' % opt, opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000139 optstring, args = args[0], args[1:]
140 optarg, optstring = optstring, ''
141 else:
142 optarg = ''
Guido van Rossum6d060941998-11-17 04:16:37 +0000143 opts.append(('-' + opt, optarg))
144 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000145
146def short_has_arg(opt, shortopts):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000147 for i in range(len(shortopts)):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000148 if opt == shortopts[i] != ':':
149 return shortopts[i+1:i+2] == ':'
Guido van Rossum80c33e51999-12-21 22:38:40 +0000150 raise GetoptError('option -%s not recognized' % opt, opt)
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000151
152if __name__ == '__main__':
Guido van Rossum1550ff71996-09-11 19:43:52 +0000153 import sys
154 print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"])