Coverage for /pythoncovmergedfiles/medio/medio/usr/lib/python3.9/getopt.py: 16%

107 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:05 +0000

1"""Parser for command line options. 

2 

3This 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 two functions and an exception: 

9 

10getopt() -- Parse command line options 

11gnu_getopt() -- Like getopt(), but allow option and non-option arguments 

12to be intermixed. 

13GetoptError -- exception (class) raised with 'opt' attribute, which is the 

14option involved with the exception. 

15""" 

16 

17# Long option support added by Lars Wirzenius <liw@iki.fi>. 

18# 

19# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions 

20# to class-based exceptions. 

21# 

22# Peter Åstrand <astrand@lysator.liu.se> 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# - an option string with a W followed by semicolon should 

32# treat "-W foo" as "--foo" 

33 

34__all__ = ["GetoptError","error","getopt","gnu_getopt"] 

35 

36import os 

37try: 

38 from gettext import gettext as _ 

39except ImportError: 

40 # Bootstrapping Python: gettext's dependencies not built yet 

41 def _(s): return s 

42 

43class GetoptError(Exception): 

44 opt = '' 

45 msg = '' 

46 def __init__(self, msg, opt=''): 

47 self.msg = msg 

48 self.opt = opt 

49 Exception.__init__(self, msg, opt) 

50 

51 def __str__(self): 

52 return self.msg 

53 

54error = GetoptError # backward compatibility 

55 

56def getopt(args, shortopts, longopts = []): 

57 """getopt(args, options[, long_options]) -> opts, args 

58 

59 Parses command line options and parameter list. args is the 

60 argument list to be parsed, without the leading reference to the 

61 running program. Typically, this means "sys.argv[1:]". shortopts 

62 is the string of option letters that the script wants to 

63 recognize, with options that require an argument followed by a 

64 colon (i.e., the same format that Unix getopt() uses). If 

65 specified, longopts is a list of strings with the names of the 

66 long options which should be supported. The leading '--' 

67 characters should not be included in the option name. Options 

68 which require an argument should be followed by an equal sign 

69 ('='). 

70 

71 The return value consists of two elements: the first is a list of 

72 (option, value) pairs; the second is the list of program arguments 

73 left after the option list was stripped (this is a trailing slice 

74 of the first argument). Each option-and-value pair returned has 

75 the option as its first element, prefixed with a hyphen (e.g., 

76 '-x'), and the option argument as its second element, or an empty 

77 string if the option has no argument. The options occur in the 

78 list in the same order in which they were found, thus allowing 

79 multiple occurrences. Long and short options may be mixed. 

80 

81 """ 

82 

83 opts = [] 

84 if type(longopts) == type(""): 

85 longopts = [longopts] 

86 else: 

87 longopts = list(longopts) 

88 while args and args[0].startswith('-') and args[0] != '-': 

89 if args[0] == '--': 

90 args = args[1:] 

91 break 

92 if args[0].startswith('--'): 

93 opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) 

94 else: 

95 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) 

96 

97 return opts, args 

98 

99def gnu_getopt(args, shortopts, longopts = []): 

100 """getopt(args, options[, long_options]) -> opts, args 

101 

102 This function works like getopt(), except that GNU style scanning 

103 mode is used by default. This means that option and non-option 

104 arguments may be intermixed. The getopt() function stops 

105 processing options as soon as a non-option argument is 

106 encountered. 

107 

108 If the first character of the option string is `+', or if the 

109 environment variable POSIXLY_CORRECT is set, then option 

110 processing stops as soon as a non-option argument is encountered. 

111 

112 """ 

113 

114 opts = [] 

115 prog_args = [] 

116 if isinstance(longopts, str): 

117 longopts = [longopts] 

118 else: 

119 longopts = list(longopts) 

120 

121 # Allow options after non-option arguments? 

122 if shortopts.startswith('+'): 

123 shortopts = shortopts[1:] 

124 all_options_first = True 

125 elif os.environ.get("POSIXLY_CORRECT"): 

126 all_options_first = True 

127 else: 

128 all_options_first = False 

129 

130 while args: 

131 if args[0] == '--': 

132 prog_args += args[1:] 

133 break 

134 

135 if args[0][:2] == '--': 

136 opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) 

137 elif args[0][:1] == '-' and args[0] != '-': 

138 opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) 

139 else: 

140 if all_options_first: 

141 prog_args += args 

142 break 

143 else: 

144 prog_args.append(args[0]) 

145 args = args[1:] 

146 

147 return opts, prog_args 

148 

149def do_longs(opts, opt, longopts, args): 

150 try: 

151 i = opt.index('=') 

152 except ValueError: 

153 optarg = None 

154 else: 

155 opt, optarg = opt[:i], opt[i+1:] 

156 

157 has_arg, opt = long_has_args(opt, longopts) 

158 if has_arg: 

159 if optarg is None: 

160 if not args: 

161 raise GetoptError(_('option --%s requires argument') % opt, opt) 

162 optarg, args = args[0], args[1:] 

163 elif optarg is not None: 

164 raise GetoptError(_('option --%s must not have an argument') % opt, opt) 

165 opts.append(('--' + opt, optarg or '')) 

166 return opts, args 

167 

168# Return: 

169# has_arg? 

170# full option name 

171def long_has_args(opt, longopts): 

172 possibilities = [o for o in longopts if o.startswith(opt)] 

173 if not possibilities: 

174 raise GetoptError(_('option --%s not recognized') % opt, opt) 

175 # Is there an exact match? 

176 if opt in possibilities: 

177 return False, opt 

178 elif opt + '=' in possibilities: 

179 return True, opt 

180 # No exact match, so better be unique. 

181 if len(possibilities) > 1: 

182 # XXX since possibilities contains all valid continuations, might be 

183 # nice to work them into the error msg 

184 raise GetoptError(_('option --%s not a unique prefix') % opt, opt) 

185 assert len(possibilities) == 1 

186 unique_match = possibilities[0] 

187 has_arg = unique_match.endswith('=') 

188 if has_arg: 

189 unique_match = unique_match[:-1] 

190 return has_arg, unique_match 

191 

192def do_shorts(opts, optstring, shortopts, args): 

193 while optstring != '': 

194 opt, optstring = optstring[0], optstring[1:] 

195 if short_has_arg(opt, shortopts): 

196 if optstring == '': 

197 if not args: 

198 raise GetoptError(_('option -%s requires argument') % opt, 

199 opt) 

200 optstring, args = args[0], args[1:] 

201 optarg, optstring = optstring, '' 

202 else: 

203 optarg = '' 

204 opts.append(('-' + opt, optarg)) 

205 return opts, args 

206 

207def short_has_arg(opt, shortopts): 

208 for i in range(len(shortopts)): 

209 if opt == shortopts[i] != ':': 

210 return shortopts.startswith(':', i+1) 

211 raise GetoptError(_('option -%s not recognized') % opt, opt) 

212 

213if __name__ == '__main__': 

214 import sys 

215 print(getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]))