0001 # -*- coding: iso-8859-1 -*- 0002 """Parser for command line options. 0003 0004 This module helps scripts to parse the command line arguments in 0005 sys.argv. It supports the same conventions as the Unix getopt() 0006 function (including the special meanings of arguments of the form `-' 0007 and `--'). Long options similar to those supported by GNU software 0008 may be used as well via an optional third argument. This module 0009 provides two functions and an exception: 0010 0011 getopt() -- Parse command line options 0012 gnu_getopt() -- Like getopt(), but allow option and non-option arguments 0013 to be intermixed. 0014 GetoptError -- exception (class) raised with 'opt' attribute, which is the 0015 option involved with the exception. 0016 """ 0017 0018 # Long option support added by Lars Wirzenius <liw@iki.fi>. 0019 # 0020 # Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions 0021 # to class-based exceptions. 0022 # 0023 # Peter Åstrand <astrand@lysator.liu.se> added gnu_getopt(). 0024 # 0025 # TODO for gnu_getopt(): 0026 # 0027 # - GNU getopt_long_only mechanism 0028 # - allow the caller to specify ordering 0029 # - RETURN_IN_ORDER option 0030 # - GNU extension with '-' as first character of option string 0031 # - optional arguments, specified by double colons 0032 # - a option string with a W followed by semicolon should 0033 # treat "-W foo" as "--foo" 0034 0035 __all__ = ["GetoptError","error","getopt","gnu_getopt"] 0036 0037 import os 0038 0039 class GetoptError(Exception): 0040 opt = '' 0041 msg = '' 0042 def __init__(self, msg, opt=''): 0043 self.msg = msg 0044 self.opt = opt 0045 Exception.__init__(self, msg, opt) 0046 0047 def __str__(self): 0048 return self.msg 0049 0050 error = GetoptError # backward compatibility 0051 0052 def getopt(args, shortopts, longopts = []): 0053 """getopt(args, options[, long_options]) -> opts, args 0054 0055 Parses command line options and parameter list. args is the 0056 argument list to be parsed, without the leading reference to the 0057 running program. Typically, this means "sys.argv[1:]". shortopts 0058 is the string of option letters that the script wants to 0059 recognize, with options that require an argument followed by a 0060 colon (i.e., the same format that Unix getopt() uses). If 0061 specified, longopts is a list of strings with the names of the 0062 long options which should be supported. The leading '--' 0063 characters should not be included in the option name. Options 0064 which require an argument should be followed by an equal sign 0065 ('='). 0066 0067 The return value consists of two elements: the first is a list of 0068 (option, value) pairs; the second is the list of program arguments 0069 left after the option list was stripped (this is a trailing slice 0070 of the first argument). Each option-and-value pair returned has 0071 the option as its first element, prefixed with a hyphen (e.g., 0072 '-x'), and the option argument as its second element, or an empty 0073 string if the option has no argument. The options occur in the 0074 list in the same order in which they were found, thus allowing 0075 multiple occurrences. Long and short options may be mixed. 0076 0077 """ 0078 0079 opts = [] 0080 if type(longopts) == type(""): 0081 longopts = [longopts] 0082 else: 0083 longopts = list(longopts) 0084 while args and args[0].startswith('-') and args[0] != '-': 0085 if args[0] == '--': 0086 args = args[1:] 0087 break 0088 if args[0].startswith('--'): 0089 opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) 0090 else: 0091 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) 0092 0093 return opts, args 0094 0095 def gnu_getopt(args, shortopts, longopts = []): 0096 """getopt(args, options[, long_options]) -> opts, args 0097 0098 This function works like getopt(), except that GNU style scanning 0099 mode is used by default. This means that option and non-option 0100 arguments may be intermixed. The getopt() function stops 0101 processing options as soon as a non-option argument is 0102 encountered. 0103 0104 If the first character of the option string is `+', or if the 0105 environment variable POSIXLY_CORRECT is set, then option 0106 processing stops as soon as a non-option argument is encountered. 0107 0108 """ 0109 0110 opts = [] 0111 prog_args = [] 0112 if isinstance(longopts, str): 0113 longopts = [longopts] 0114 else: 0115 longopts = list(longopts) 0116 0117 # Allow options after non-option arguments? 0118 if shortopts.startswith('+'): 0119 shortopts = shortopts[1:] 0120 all_options_first = True 0121 elif os.environ.get("POSIXLY_CORRECT"): 0122 all_options_first = True 0123 else: 0124 all_options_first = False 0125 0126 while args: 0127 if args[0] == '--': 0128 prog_args += args[1:] 0129 break 0130 0131 if args[0][:2] == '--': 0132 opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) 0133 elif args[0][:1] == '-': 0134 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) 0135 else: 0136 if all_options_first: 0137 prog_args += args 0138 break 0139 else: 0140 prog_args.append(args[0]) 0141 args = args[1:] 0142 0143 return opts, prog_args 0144 0145 def do_longs(opts, opt, longopts, args): 0146 try: 0147 i = opt.index('=') 0148 except ValueError: 0149 optarg = None 0150 else: 0151 opt, optarg = opt[:i], opt[i+1:] 0152 0153 has_arg, opt = long_has_args(opt, longopts) 0154 if has_arg: 0155 if optarg is None: 0156 if not args: 0157 raise GetoptError('option --%s requires argument' % opt, opt) 0158 optarg, args = args[0], args[1:] 0159 elif optarg: 0160 raise GetoptError('option --%s must not have an argument' % opt, opt) 0161 opts.append(('--' + opt, optarg or '')) 0162 return opts, args 0163 0164 # Return: 0165 # has_arg? 0166 # full option name 0167 def long_has_args(opt, longopts): 0168 possibilities = [o for o in longopts if o.startswith(opt)] 0169 if not possibilities: 0170 raise GetoptError('option --%s not recognized' % opt, opt) 0171 # Is there an exact match? 0172 if opt in possibilities: 0173 return False, opt 0174 elif opt + '=' in possibilities: 0175 return True, opt 0176 # No exact match, so better be unique. 0177 if len(possibilities) > 1: 0178 # XXX since possibilities contains all valid continuations, might be 0179 # nice to work them into the error msg 0180 raise GetoptError('option --%s not a unique prefix' % opt, opt) 0181 assert len(possibilities) == 1 0182 unique_match = possibilities[0] 0183 has_arg = unique_match.endswith('=') 0184 if has_arg: 0185 unique_match = unique_match[:-1] 0186 return has_arg, unique_match 0187 0188 def do_shorts(opts, optstring, shortopts, args): 0189 while optstring != '': 0190 opt, optstring = optstring[0], optstring[1:] 0191 if short_has_arg(opt, shortopts): 0192 if optstring == '': 0193 if not args: 0194 raise GetoptError('option -%s requires argument' % opt, 0195 opt) 0196 optstring, args = args[0], args[1:] 0197 optarg, optstring = optstring, '' 0198 else: 0199 optarg = '' 0200 opts.append(('-' + opt, optarg)) 0201 return opts, args 0202 0203 def short_has_arg(opt, shortopts): 0204 for i in range(len(shortopts)): 0205 if opt == shortopts[i] != ':': 0206 return shortopts.startswith(':', i+1) 0207 raise GetoptError('option -%s not recognized' % opt, opt) 0208 0209 if __name__ == '__main__': 0210 import sys 0211 print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]) 0212
Generated by PyXR 0.9.4