blob: a8ad645bee6480a371883beba1d424bf83a93013 [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)
Tim Petersdd699b62000-12-27 08:05:05 +000068 while args and args[0].startswith('-') and args[0] != '-':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000069 if args[0] == '--':
70 args = args[1:]
71 break
72 if args[0][:2] == '--':
Guido van Rossum6d060941998-11-17 04:16:37 +000073 opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000074 else:
Guido van Rossum6d060941998-11-17 04:16:37 +000075 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
Guido van Rossumc6360141990-10-13 19:23:40 +000076
Guido van Rossum6d060941998-11-17 04:16:37 +000077 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +000078
Guido van Rossum6d060941998-11-17 04:16:37 +000079def do_longs(opts, opt, longopts, args):
Guido van Rossum1550ff71996-09-11 19:43:52 +000080 try:
Fred Drakea395ced2000-02-25 16:14:08 +000081 i = opt.index('=')
Guido van Rossum1550ff71996-09-11 19:43:52 +000082 except ValueError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000083 optarg = None
Tim Petersdd699b62000-12-27 08:05:05 +000084 else:
85 opt, optarg = opt[:i], opt[i+1:]
Guido van Rossum2c349bb1996-09-09 15:48:24 +000086
Guido van Rossum1550ff71996-09-11 19:43:52 +000087 has_arg, opt = long_has_args(opt, longopts)
88 if has_arg:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000089 if optarg is None:
90 if not args:
Guido van Rossum80c33e51999-12-21 22:38:40 +000091 raise GetoptError('option --%s requires argument' % opt, opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000092 optarg, args = args[0], args[1:]
Guido van Rossum1550ff71996-09-11 19:43:52 +000093 elif optarg:
Guido van Rossum80c33e51999-12-21 22:38:40 +000094 raise GetoptError('option --%s must not have an argument' % opt, opt)
Guido van Rossum6d060941998-11-17 04:16:37 +000095 opts.append(('--' + opt, optarg or ''))
96 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +000097
98# Return:
99# has_arg?
100# full option name
101def long_has_args(opt, longopts):
Tim Petersd31b6322000-12-29 02:17:56 +0000102 possibilities = [o for o in longopts if o.startswith(opt)]
103 if not possibilities:
Tim Petersdd699b62000-12-27 08:05:05 +0000104 raise GetoptError('option --%s not recognized' % opt, opt)
Tim Petersdd699b62000-12-27 08:05:05 +0000105 # Is there an exact match?
106 if opt in possibilities:
107 return 0, opt
108 elif opt + '=' in possibilities:
109 return 1, opt
110 # No exact match, so better be unique.
111 if len(possibilities) > 1:
112 # XXX since possibilities contains all valid continuations, might be
113 # nice to work them into the error msg
114 raise GetoptError('option --%s not a unique prefix' % opt, opt)
115 assert len(possibilities) == 1
116 unique_match = possibilities[0]
117 has_arg = unique_match.endswith('=')
118 if has_arg:
119 unique_match = unique_match[:-1]
120 return has_arg, unique_match
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000121
Guido van Rossum6d060941998-11-17 04:16:37 +0000122def do_shorts(opts, optstring, shortopts, args):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000123 while optstring != '':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000124 opt, optstring = optstring[0], optstring[1:]
125 if short_has_arg(opt, shortopts):
126 if optstring == '':
127 if not args:
Guido van Rossum80c33e51999-12-21 22:38:40 +0000128 raise GetoptError('option -%s requires argument' % opt, opt)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000129 optstring, args = args[0], args[1:]
130 optarg, optstring = optstring, ''
131 else:
132 optarg = ''
Guido van Rossum6d060941998-11-17 04:16:37 +0000133 opts.append(('-' + opt, optarg))
134 return opts, args
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000135
136def short_has_arg(opt, shortopts):
Guido van Rossum1550ff71996-09-11 19:43:52 +0000137 for i in range(len(shortopts)):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000138 if opt == shortopts[i] != ':':
139 return shortopts[i+1:i+2] == ':'
Guido van Rossum80c33e51999-12-21 22:38:40 +0000140 raise GetoptError('option -%s not recognized' % opt, opt)
Guido van Rossum2c349bb1996-09-09 15:48:24 +0000141
142if __name__ == '__main__':
Guido van Rossum1550ff71996-09-11 19:43:52 +0000143 import sys
144 print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"])