|
1 """optik.option_parser |
|
2 |
|
3 Provides the OptionParser and Values classes. |
|
4 """ |
|
5 |
|
6 # Copyright (c) 2001-2004 Gregory P. Ward. All rights reserved. |
|
7 # See the README.txt distributed with Optik for licensing terms. |
|
8 |
|
9 import sys, os |
|
10 import types, string |
|
11 from optik.option import Option, NO_DEFAULT, _repr |
|
12 from optik.help import IndentedHelpFormatter |
|
13 from optik import errors |
|
14 from optik.errors import gettext |
|
15 _ = gettext |
|
16 |
|
17 __revision__ = "$Id: option_parser.py,v 1.1 2009/02/05 23:03:30 stechong Exp $" |
|
18 |
|
19 __all__ = ['SUPPRESS_HELP', 'SUPPRESS_USAGE', |
|
20 'Values', 'OptionContainer', 'OptionGroup', 'OptionParser'] |
|
21 |
|
22 |
|
23 SUPPRESS_HELP = "SUPPRESS"+"HELP" |
|
24 SUPPRESS_USAGE = "SUPPRESS"+"USAGE" |
|
25 |
|
26 # For compatibility with Python 2.2 |
|
27 try: |
|
28 True, False |
|
29 except NameError: |
|
30 (True, False) = (1, 0) |
|
31 def isbasestring(x): |
|
32 return isinstance(x, types.StringType) or isinstance(x, types.UnicodeType) |
|
33 if not hasattr(string, "startswith"): |
|
34 def startswith(s, prefix): |
|
35 return s[:len(prefix)] == prefix |
|
36 string.startswith = startswith |
|
37 |
|
38 class Values: |
|
39 |
|
40 def __init__(self, defaults=None): |
|
41 if defaults: |
|
42 for (attr, val) in defaults.items(): |
|
43 setattr(self, attr, val) |
|
44 |
|
45 def __str__(self): |
|
46 return str(self.__dict__) |
|
47 |
|
48 __repr__ = _repr |
|
49 |
|
50 def __cmp__(self, other): |
|
51 if isinstance(other, Values): |
|
52 return cmp(self.__dict__, other.__dict__) |
|
53 elif isinstance(other, types.DictType): |
|
54 return cmp(self.__dict__, other) |
|
55 else: |
|
56 return -1 |
|
57 |
|
58 def _update_careful(self, dict): |
|
59 """ |
|
60 Update the option values from an arbitrary dictionary, but only |
|
61 use keys from dict that already have a corresponding attribute |
|
62 in self. Any keys in dict without a corresponding attribute |
|
63 are silently ignored. |
|
64 """ |
|
65 for attr in dir(self): |
|
66 if dict.has_key(attr): |
|
67 dval = dict[attr] |
|
68 if dval is not None: |
|
69 setattr(self, attr, dval) |
|
70 |
|
71 def _update_loose(self, dict): |
|
72 """ |
|
73 Update the option values from an arbitrary dictionary, |
|
74 using all keys from the dictionary regardless of whether |
|
75 they have a corresponding attribute in self or not. |
|
76 """ |
|
77 self.__dict__.update(dict) |
|
78 |
|
79 def _update(self, dict, mode): |
|
80 if mode == "careful": |
|
81 self._update_careful(dict) |
|
82 elif mode == "loose": |
|
83 self._update_loose(dict) |
|
84 else: |
|
85 raise ValueError, "invalid update mode: %s" % repr(mode) |
|
86 |
|
87 def read_module(self, modname, mode="careful"): |
|
88 __import__(modname) |
|
89 mod = sys.modules[modname] |
|
90 self._update(vars(mod), mode) |
|
91 |
|
92 def read_file(self, filename, mode="careful"): |
|
93 vars = {} |
|
94 execfile(filename, vars) |
|
95 self._update(vars, mode) |
|
96 |
|
97 def ensure_value(self, attr, value): |
|
98 if not hasattr(self, attr) or getattr(self, attr) is None: |
|
99 setattr(self, attr, value) |
|
100 return getattr(self, attr) |
|
101 |
|
102 |
|
103 class OptionContainer: |
|
104 |
|
105 """ |
|
106 Abstract base class. |
|
107 |
|
108 Class attributes: |
|
109 standard_option_list : [Option] |
|
110 list of standard options that will be accepted by all instances |
|
111 of this parser class (intended to be overridden by subclasses). |
|
112 |
|
113 Instance attributes: |
|
114 option_list : [Option] |
|
115 the list of Option objects contained by this OptionContainer |
|
116 _short_opt : { string : Option } |
|
117 dictionary mapping short option strings, eg. "-f" or "-X", |
|
118 to the Option instances that implement them. If an Option |
|
119 has multiple short option strings, it will appears in this |
|
120 dictionary multiple times. [1] |
|
121 _long_opt : { string : Option } |
|
122 dictionary mapping long option strings, eg. "--file" or |
|
123 "--exclude", to the Option instances that implement them. |
|
124 Again, a given Option can occur multiple times in this |
|
125 dictionary. [1] |
|
126 defaults : { string : any } |
|
127 dictionary mapping option destination names to default |
|
128 values for each destination [1] |
|
129 |
|
130 [1] These mappings are common to (shared by) all components of the |
|
131 controlling OptionParser, where they are initially created. |
|
132 |
|
133 """ |
|
134 |
|
135 def __init__(self, option_class, conflict_handler, description): |
|
136 # Initialize the option list and related data structures. |
|
137 # This method must be provided by subclasses, and it must |
|
138 # initialize at least the following instance attributes: |
|
139 # option_list, _short_opt, _long_opt, defaults. |
|
140 self._create_option_list() |
|
141 |
|
142 self.option_class = option_class |
|
143 self.set_conflict_handler(conflict_handler) |
|
144 self.set_description(description) |
|
145 |
|
146 def _create_option_mappings(self): |
|
147 # For use by OptionParser constructor -- create the master |
|
148 # option mappings used by this OptionParser and all |
|
149 # OptionGroups that it owns. |
|
150 self._short_opt = {} # single letter -> Option instance |
|
151 self._long_opt = {} # long option -> Option instance |
|
152 self.defaults = {} # maps option dest -> default value |
|
153 |
|
154 |
|
155 def _share_option_mappings(self, parser): |
|
156 # For use by OptionGroup constructor -- use shared option |
|
157 # mappings from the OptionParser that owns this OptionGroup. |
|
158 self._short_opt = parser._short_opt |
|
159 self._long_opt = parser._long_opt |
|
160 self.defaults = parser.defaults |
|
161 |
|
162 def set_conflict_handler(self, handler): |
|
163 if handler not in ("error", "resolve"): |
|
164 raise ValueError, "invalid conflict_resolution value %s" % repr(handler) |
|
165 self.conflict_handler = handler |
|
166 |
|
167 def set_description(self, description): |
|
168 self.description = description |
|
169 |
|
170 def get_description(self): |
|
171 return self.description |
|
172 |
|
173 |
|
174 # -- Option-adding methods ----------------------------------------- |
|
175 |
|
176 def _check_conflict(self, option): |
|
177 conflict_opts = [] |
|
178 for opt in option._short_opts: |
|
179 if self._short_opt.has_key(opt): |
|
180 conflict_opts.append((opt, self._short_opt[opt])) |
|
181 for opt in option._long_opts: |
|
182 if self._long_opt.has_key(opt): |
|
183 conflict_opts.append((opt, self._long_opt[opt])) |
|
184 |
|
185 if conflict_opts: |
|
186 handler = self.conflict_handler |
|
187 if handler == "error": |
|
188 opts = [] |
|
189 for co in conflict_opts: |
|
190 opts.append(co[0]) |
|
191 raise errors.OptionConflictError( |
|
192 "conflicting option string(s): %s" |
|
193 % string.join(opts, ", "), |
|
194 option) |
|
195 elif handler == "resolve": |
|
196 for (opt, c_option) in conflict_opts: |
|
197 if string.startswith(opt, "--"): |
|
198 c_option._long_opts.remove(opt) |
|
199 del self._long_opt[opt] |
|
200 else: |
|
201 c_option._short_opts.remove(opt) |
|
202 del self._short_opt[opt] |
|
203 if not (c_option._short_opts or c_option._long_opts): |
|
204 c_option.container.option_list.remove(c_option) |
|
205 |
|
206 def add_option(self, *args, **kwargs): |
|
207 """add_option(Option) |
|
208 add_option(opt_str, ..., kwarg=val, ...) |
|
209 """ |
|
210 if type(args[0]) is types.StringType: |
|
211 option = apply(self.option_class, args, kwargs) |
|
212 elif len(args) == 1 and not kwargs: |
|
213 option = args[0] |
|
214 if not isinstance(option, Option): |
|
215 raise TypeError, "not an Option instance: %s" % repr(option) |
|
216 else: |
|
217 raise TypeError, "invalid arguments" |
|
218 |
|
219 self._check_conflict(option) |
|
220 |
|
221 self.option_list.append(option) |
|
222 option.container = self |
|
223 for opt in option._short_opts: |
|
224 self._short_opt[opt] = option |
|
225 for opt in option._long_opts: |
|
226 self._long_opt[opt] = option |
|
227 |
|
228 if option.dest is not None: # option has a dest, we need a default |
|
229 if option.default is not NO_DEFAULT: |
|
230 self.defaults[option.dest] = option.default |
|
231 elif not self.defaults.has_key(option.dest): |
|
232 self.defaults[option.dest] = None |
|
233 |
|
234 return option |
|
235 |
|
236 def add_options(self, option_list): |
|
237 for option in option_list: |
|
238 self.add_option(option) |
|
239 |
|
240 # -- Option query/removal methods ---------------------------------- |
|
241 |
|
242 def get_option(self, opt_str): |
|
243 return (self._short_opt.get(opt_str) or |
|
244 self._long_opt.get(opt_str)) |
|
245 |
|
246 def has_option(self, opt_str): |
|
247 return (self._short_opt.has_key(opt_str) or |
|
248 self._long_opt.has_key(opt_str)) |
|
249 |
|
250 def remove_option(self, opt_str): |
|
251 option = self._short_opt.get(opt_str) |
|
252 if option is None: |
|
253 option = self._long_opt.get(opt_str) |
|
254 if option is None: |
|
255 raise ValueError("no such option %s" % repr(opt_str)) |
|
256 |
|
257 for opt in option._short_opts: |
|
258 del self._short_opt[opt] |
|
259 for opt in option._long_opts: |
|
260 del self._long_opt[opt] |
|
261 option.container.option_list.remove(option) |
|
262 |
|
263 |
|
264 # -- Help-formatting methods --------------------------------------- |
|
265 |
|
266 def format_option_help(self, formatter): |
|
267 if not self.option_list: |
|
268 return "" |
|
269 result = [] |
|
270 for option in self.option_list: |
|
271 if not option.help is SUPPRESS_HELP: |
|
272 result.append(formatter.format_option(option)) |
|
273 return string.join(result, "") |
|
274 |
|
275 def format_description(self, formatter): |
|
276 return formatter.format_description(self.get_description()) |
|
277 |
|
278 def format_help(self, formatter): |
|
279 result = [] |
|
280 if self.description: |
|
281 result.append(self.format_description(formatter)) |
|
282 if self.option_list: |
|
283 result.append(self.format_option_help(formatter)) |
|
284 return string.join(result, "\n") |
|
285 |
|
286 |
|
287 class OptionGroup (OptionContainer): |
|
288 |
|
289 def __init__(self, parser, title, description=None): |
|
290 self.parser = parser |
|
291 OptionContainer.__init__( |
|
292 self, parser.option_class, parser.conflict_handler, description) |
|
293 self.title = title |
|
294 |
|
295 def _create_option_list(self): |
|
296 self.option_list = [] |
|
297 self._share_option_mappings(self.parser) |
|
298 |
|
299 def set_title(self, title): |
|
300 self.title = title |
|
301 |
|
302 # -- Help-formatting methods --------------------------------------- |
|
303 |
|
304 def format_help(self, formatter): |
|
305 result = formatter.format_heading(self.title) |
|
306 formatter.indent() |
|
307 result = result + OptionContainer.format_help(self, formatter) |
|
308 formatter.dedent() |
|
309 return result |
|
310 |
|
311 |
|
312 class OptionParser (OptionContainer): |
|
313 |
|
314 """ |
|
315 Class attributes: |
|
316 standard_option_list : [Option] |
|
317 list of standard options that will be accepted by all instances |
|
318 of this parser class (intended to be overridden by subclasses). |
|
319 |
|
320 Instance attributes: |
|
321 usage : string |
|
322 a usage string for your program. Before it is displayed |
|
323 to the user, "%prog" will be expanded to the name of |
|
324 your program (self.prog or os.path.basename(sys.argv[0])). |
|
325 prog : string |
|
326 the name of the current program (to override |
|
327 os.path.basename(sys.argv[0])). |
|
328 |
|
329 option_groups : [OptionGroup] |
|
330 list of option groups in this parser (option groups are |
|
331 irrelevant for parsing the command-line, but very useful |
|
332 for generating help) |
|
333 |
|
334 allow_interspersed_args : bool = true |
|
335 if true, positional arguments may be interspersed with options. |
|
336 Assuming -a and -b each take a single argument, the command-line |
|
337 -ablah foo bar -bboo baz |
|
338 will be interpreted the same as |
|
339 -ablah -bboo -- foo bar baz |
|
340 If this flag were false, that command line would be interpreted as |
|
341 -ablah -- foo bar -bboo baz |
|
342 -- ie. we stop processing options as soon as we see the first |
|
343 non-option argument. (This is the tradition followed by |
|
344 Python's getopt module, Perl's Getopt::Std, and other argument- |
|
345 parsing libraries, but it is generally annoying to users.) |
|
346 |
|
347 process_default_values : bool = true |
|
348 if true, option default values are processed similarly to option |
|
349 values from the command line: that is, they are passed to the |
|
350 type-checking function for the option's type (as long as the |
|
351 default value is a string). (This really only matters if you |
|
352 have defined custom types; see SF bug #955889.) Set it to false |
|
353 to restore the behaviour of Optik 1.4.1 and earlier. |
|
354 |
|
355 rargs : [string] |
|
356 the argument list currently being parsed. Only set when |
|
357 parse_args() is active, and continually trimmed down as |
|
358 we consume arguments. Mainly there for the benefit of |
|
359 callback options. |
|
360 largs : [string] |
|
361 the list of leftover arguments that we have skipped while |
|
362 parsing options. If allow_interspersed_args is false, this |
|
363 list is always empty. |
|
364 values : Values |
|
365 the set of option values currently being accumulated. Only |
|
366 set when parse_args() is active. Also mainly for callbacks. |
|
367 |
|
368 Because of the 'rargs', 'largs', and 'values' attributes, |
|
369 OptionParser is not thread-safe. If, for some perverse reason, you |
|
370 need to parse command-line arguments simultaneously in different |
|
371 threads, use different OptionParser instances. |
|
372 |
|
373 """ |
|
374 |
|
375 standard_option_list = [] |
|
376 |
|
377 def __init__(self, |
|
378 usage=None, |
|
379 option_list=None, |
|
380 option_class=Option, |
|
381 version=None, |
|
382 conflict_handler="error", |
|
383 description=None, |
|
384 formatter=None, |
|
385 add_help_option=True, |
|
386 prog=None): |
|
387 OptionContainer.__init__( |
|
388 self, option_class, conflict_handler, description) |
|
389 self.set_usage(usage) |
|
390 self.prog = prog |
|
391 self.version = version |
|
392 self.allow_interspersed_args = True |
|
393 self.process_default_values = True |
|
394 if formatter is None: |
|
395 formatter = IndentedHelpFormatter() |
|
396 self.formatter = formatter |
|
397 self.formatter.set_parser(self) |
|
398 |
|
399 # Populate the option list; initial sources are the |
|
400 # standard_option_list class attribute, the 'option_list' |
|
401 # argument, and (if applicable) the _add_version_option() and |
|
402 # _add_help_option() methods. |
|
403 self._populate_option_list(option_list, |
|
404 add_help=add_help_option) |
|
405 |
|
406 self._init_parsing_state() |
|
407 |
|
408 # -- Private methods ----------------------------------------------- |
|
409 # (used by our or OptionContainer's constructor) |
|
410 |
|
411 def _create_option_list(self): |
|
412 self.option_list = [] |
|
413 self.option_groups = [] |
|
414 self._create_option_mappings() |
|
415 |
|
416 def _add_help_option(self): |
|
417 self.add_option("-h", "--help", |
|
418 action="help", |
|
419 help=_("show this help message and exit")) |
|
420 |
|
421 def _add_version_option(self): |
|
422 self.add_option("--version", |
|
423 action="version", |
|
424 help=_("show program's version number and exit")) |
|
425 |
|
426 def _populate_option_list(self, option_list, add_help=True): |
|
427 if self.standard_option_list: |
|
428 self.add_options(self.standard_option_list) |
|
429 if option_list: |
|
430 self.add_options(option_list) |
|
431 if self.version: |
|
432 self._add_version_option() |
|
433 if add_help: |
|
434 self._add_help_option() |
|
435 |
|
436 def _init_parsing_state(self): |
|
437 # These are set in parse_args() for the convenience of callbacks. |
|
438 self.rargs = None |
|
439 self.largs = None |
|
440 self.values = None |
|
441 |
|
442 |
|
443 # -- Simple modifier methods --------------------------------------- |
|
444 |
|
445 def set_usage(self, usage): |
|
446 if usage is None: |
|
447 self.usage = _("%prog [options]") |
|
448 elif usage is SUPPRESS_USAGE: |
|
449 self.usage = None |
|
450 # For backwards compatibility with Optik 1.3 and earlier. |
|
451 elif string.startswith(usage, "usage:" + " "): |
|
452 self.usage = usage[7:] |
|
453 else: |
|
454 self.usage = usage |
|
455 |
|
456 def enable_interspersed_args(self): |
|
457 self.allow_interspersed_args = True |
|
458 |
|
459 def disable_interspersed_args(self): |
|
460 self.allow_interspersed_args = False |
|
461 |
|
462 def set_process_default_values(self, process): |
|
463 self.process_default_values = process |
|
464 |
|
465 def set_default(self, dest, value): |
|
466 self.defaults[dest] = value |
|
467 |
|
468 def set_defaults(self, **kwargs): |
|
469 self.defaults.update(kwargs) |
|
470 |
|
471 def _get_all_options(self): |
|
472 options = self.option_list[:] |
|
473 for group in self.option_groups: |
|
474 options.extend(group.option_list) |
|
475 return options |
|
476 |
|
477 def get_default_values(self): |
|
478 if not self.process_default_values: |
|
479 # Old, pre-Optik 1.5 behaviour. |
|
480 return Values(self.defaults) |
|
481 |
|
482 defaults = self.defaults.copy() |
|
483 for option in self._get_all_options(): |
|
484 default = defaults.get(option.dest) |
|
485 if isbasestring(default): |
|
486 opt_str = option.get_opt_string() |
|
487 defaults[option.dest] = option.check_value(opt_str, default) |
|
488 |
|
489 return Values(defaults) |
|
490 |
|
491 |
|
492 # -- OptionGroup methods ------------------------------------------- |
|
493 |
|
494 def add_option_group(self, *args, **kwargs): |
|
495 # XXX lots of overlap with OptionContainer.add_option() |
|
496 if type(args[0]) is types.StringType: |
|
497 group = apply(OptionGroup, (self,) + args, kwargs) |
|
498 elif len(args) == 1 and not kwargs: |
|
499 group = args[0] |
|
500 if not isinstance(group, OptionGroup): |
|
501 raise TypeError, "not an OptionGroup instance: %s" % repr(group) |
|
502 if group.parser is not self: |
|
503 raise ValueError, "invalid OptionGroup (wrong parser)" |
|
504 else: |
|
505 raise TypeError, "invalid arguments" |
|
506 |
|
507 self.option_groups.append(group) |
|
508 return group |
|
509 |
|
510 def get_option_group(self, opt_str): |
|
511 option = (self._short_opt.get(opt_str) or |
|
512 self._long_opt.get(opt_str)) |
|
513 if option and option.container is not self: |
|
514 return option.container |
|
515 return None |
|
516 |
|
517 |
|
518 # -- Option-parsing methods ---------------------------------------- |
|
519 |
|
520 def _get_args(self, args): |
|
521 if args is None: |
|
522 return sys.argv[1:] |
|
523 else: |
|
524 return args[:] # don't modify caller's list |
|
525 |
|
526 def parse_args(self, args=None, values=None): |
|
527 """ |
|
528 parse_args(args : [string] = sys.argv[1:], |
|
529 values : Values = None) |
|
530 -> (values : Values, args : [string]) |
|
531 |
|
532 Parse the command-line options found in 'args' (default: |
|
533 sys.argv[1:]). Any errors result in a call to 'error()', which |
|
534 by default prints the usage message to stderr and calls |
|
535 sys.exit() with an error message. On success returns a pair |
|
536 (values, args) where 'values' is an Values instance (with all |
|
537 your option values) and 'args' is the list of arguments left |
|
538 over after parsing options. |
|
539 """ |
|
540 rargs = self._get_args(args) |
|
541 if values is None: |
|
542 values = self.get_default_values() |
|
543 |
|
544 # Store the halves of the argument list as attributes for the |
|
545 # convenience of callbacks: |
|
546 # rargs |
|
547 # the rest of the command-line (the "r" stands for |
|
548 # "remaining" or "right-hand") |
|
549 # largs |
|
550 # the leftover arguments -- ie. what's left after removing |
|
551 # options and their arguments (the "l" stands for "leftover" |
|
552 # or "left-hand") |
|
553 self.rargs = rargs |
|
554 self.largs = largs = [] |
|
555 self.values = values |
|
556 |
|
557 try: |
|
558 stop = self._process_args(largs, rargs, values) |
|
559 except (errors.BadOptionError, errors.OptionValueError), err: |
|
560 self.error(str(err)) |
|
561 |
|
562 args = largs + rargs |
|
563 return self.check_values(values, args) |
|
564 |
|
565 def check_values(self, values, args): |
|
566 """ |
|
567 check_values(values : Values, args : [string]) |
|
568 -> (values : Values, args : [string]) |
|
569 |
|
570 Check that the supplied option values and leftover arguments are |
|
571 valid. Returns the option values and leftover arguments |
|
572 (possibly adjusted, possibly completely new -- whatever you |
|
573 like). Default implementation just returns the passed-in |
|
574 values; subclasses may override as desired. |
|
575 """ |
|
576 return (values, args) |
|
577 |
|
578 def _process_args(self, largs, rargs, values): |
|
579 """_process_args(largs : [string], |
|
580 rargs : [string], |
|
581 values : Values) |
|
582 |
|
583 Process command-line arguments and populate 'values', consuming |
|
584 options and arguments from 'rargs'. If 'allow_interspersed_args' is |
|
585 false, stop at the first non-option argument. If true, accumulate any |
|
586 interspersed non-option arguments in 'largs'. |
|
587 """ |
|
588 while rargs: |
|
589 arg = rargs[0] |
|
590 # We handle bare "--" explicitly, and bare "-" is handled by the |
|
591 # standard arg handler since the short arg case ensures that the |
|
592 # len of the opt string is greater than 1. |
|
593 if arg == "--": |
|
594 del rargs[0] |
|
595 return |
|
596 elif arg[0:2] == "--": |
|
597 # process a single long option (possibly with value(s)) |
|
598 self._process_long_opt(rargs, values) |
|
599 elif arg[:1] == "-" and len(arg) > 1: |
|
600 # process a cluster of short options (possibly with |
|
601 # value(s) for the last one only) |
|
602 self._process_short_opts(rargs, values) |
|
603 elif self.allow_interspersed_args: |
|
604 largs.append(arg) |
|
605 del rargs[0] |
|
606 else: |
|
607 return # stop now, leave this arg in rargs |
|
608 |
|
609 # Say this is the original argument list: |
|
610 # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] |
|
611 # ^ |
|
612 # (we are about to process arg(i)). |
|
613 # |
|
614 # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of |
|
615 # [arg0, ..., arg(i-1)] (any options and their arguments will have |
|
616 # been removed from largs). |
|
617 # |
|
618 # The while loop will usually consume 1 or more arguments per pass. |
|
619 # If it consumes 1 (eg. arg is an option that takes no arguments), |
|
620 # then after _process_arg() is done the situation is: |
|
621 # |
|
622 # largs = subset of [arg0, ..., arg(i)] |
|
623 # rargs = [arg(i+1), ..., arg(N-1)] |
|
624 # |
|
625 # If allow_interspersed_args is false, largs will always be |
|
626 # *empty* -- still a subset of [arg0, ..., arg(i-1)], but |
|
627 # not a very interesting subset! |
|
628 |
|
629 def _match_long_opt(self, opt): |
|
630 """_match_long_opt(opt : string) -> string |
|
631 |
|
632 Determine which long option string 'opt' matches, ie. which one |
|
633 it is an unambiguous abbrevation for. Raises BadOptionError if |
|
634 'opt' doesn't unambiguously match any long option string. |
|
635 """ |
|
636 return _match_abbrev(opt, self._long_opt) |
|
637 |
|
638 def _process_long_opt(self, rargs, values): |
|
639 arg = rargs.pop(0) |
|
640 |
|
641 # Value explicitly attached to arg? Pretend it's the next |
|
642 # argument. |
|
643 if "=" in arg: |
|
644 (opt, next_arg) = string.split(arg, "=", 1) |
|
645 rargs.insert(0, next_arg) |
|
646 had_explicit_value = True |
|
647 else: |
|
648 opt = arg |
|
649 had_explicit_value = False |
|
650 |
|
651 opt = self._match_long_opt(opt) |
|
652 option = self._long_opt[opt] |
|
653 if option.takes_value(): |
|
654 nargs = option.nargs |
|
655 if len(rargs) < nargs: |
|
656 if nargs == 1: |
|
657 self.error(_("%s option requires an argument") % opt) |
|
658 else: |
|
659 self.error(_("%s option requires %d arguments") |
|
660 % (opt, nargs)) |
|
661 elif nargs == 1: |
|
662 value = rargs.pop(0) |
|
663 else: |
|
664 value = tuple(rargs[0:nargs]) |
|
665 del rargs[0:nargs] |
|
666 |
|
667 elif had_explicit_value: |
|
668 self.error(_("%s option does not take a value") % opt) |
|
669 |
|
670 else: |
|
671 value = None |
|
672 |
|
673 option.process(opt, value, values, self) |
|
674 |
|
675 def _process_short_opts(self, rargs, values): |
|
676 arg = rargs.pop(0) |
|
677 stop = False |
|
678 i = 1 |
|
679 for ch in arg[1:]: |
|
680 opt = "-" + ch |
|
681 option = self._short_opt.get(opt) |
|
682 i = i+1 # we have consumed a character |
|
683 |
|
684 if not option: |
|
685 raise errors.BadOptionError(opt) |
|
686 #self.error(_("no such option: %s") % opt) |
|
687 if option.takes_value(): |
|
688 # Any characters left in arg? Pretend they're the |
|
689 # next arg, and stop consuming characters of arg. |
|
690 if i < len(arg): |
|
691 rargs.insert(0, arg[i:]) |
|
692 stop = True |
|
693 |
|
694 nargs = option.nargs |
|
695 if len(rargs) < nargs: |
|
696 if nargs == 1: |
|
697 self.error(_("%s option requires an argument") % opt) |
|
698 else: |
|
699 self.error(_("%s option requires %d arguments") |
|
700 % (opt, nargs)) |
|
701 elif nargs == 1: |
|
702 value = rargs.pop(0) |
|
703 else: |
|
704 value = tuple(rargs[0:nargs]) |
|
705 del rargs[0:nargs] |
|
706 |
|
707 else: # option doesn't take a value |
|
708 value = None |
|
709 |
|
710 option.process(opt, value, values, self) |
|
711 |
|
712 if stop: |
|
713 break |
|
714 |
|
715 |
|
716 # -- Feedback methods ---------------------------------------------- |
|
717 |
|
718 def get_prog_name(self): |
|
719 if self.prog is None: |
|
720 return os.path.basename(sys.argv[0]) |
|
721 else: |
|
722 return self.prog |
|
723 |
|
724 def expand_prog_name(self, s): |
|
725 return string.replace(s, "%prog", self.get_prog_name()) |
|
726 |
|
727 def get_description(self): |
|
728 return self.expand_prog_name(self.description) |
|
729 |
|
730 def exit(self, status=0, msg=None): |
|
731 if msg: |
|
732 sys.stderr.write(msg) |
|
733 sys.exit(status) |
|
734 |
|
735 def error(self, msg): |
|
736 """error(msg : string) |
|
737 |
|
738 Print a usage message incorporating 'msg' to stderr and exit. |
|
739 If you override this in a subclass, it should not return -- it |
|
740 should either exit or raise an exception. |
|
741 """ |
|
742 self.print_usage(sys.stderr) |
|
743 self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg)) |
|
744 |
|
745 def get_usage(self): |
|
746 if self.usage: |
|
747 return self.formatter.format_usage( |
|
748 self.expand_prog_name(self.usage)) |
|
749 else: |
|
750 return "" |
|
751 |
|
752 def print_usage(self, file=None): |
|
753 """print_usage(file : file = stdout) |
|
754 |
|
755 Print the usage message for the current program (self.usage) to |
|
756 'file' (default stdout). Any occurence of the string "%prog" in |
|
757 self.usage is replaced with the name of the current program |
|
758 (basename of sys.argv[0]). Does nothing if self.usage is empty |
|
759 or not defined. |
|
760 """ |
|
761 if self.usage: |
|
762 if file is None: |
|
763 file = sys.stdout |
|
764 file.write(self.get_usage() + "\n") |
|
765 |
|
766 def get_version(self): |
|
767 if self.version: |
|
768 return self.expand_prog_name(self.version) |
|
769 else: |
|
770 return "" |
|
771 |
|
772 def print_version(self, file=None): |
|
773 """print_version(file : file = stdout) |
|
774 |
|
775 Print the version message for this program (self.version) to |
|
776 'file' (default stdout). As with print_usage(), any occurence |
|
777 of "%prog" in self.version is replaced by the current program's |
|
778 name. Does nothing if self.version is empty or undefined. |
|
779 """ |
|
780 if self.version: |
|
781 if file is None: |
|
782 file = sys.stdout |
|
783 file.write(self.get_version() + "\n") |
|
784 |
|
785 def format_option_help(self, formatter=None): |
|
786 if formatter is None: |
|
787 formatter = self.formatter |
|
788 formatter.store_option_strings(self) |
|
789 result = [] |
|
790 result.append(formatter.format_heading(_("options"))) |
|
791 formatter.indent() |
|
792 if self.option_list: |
|
793 result.append(OptionContainer.format_option_help(self, formatter)) |
|
794 result.append("\n") |
|
795 for group in self.option_groups: |
|
796 result.append(group.format_help(formatter)) |
|
797 result.append("\n") |
|
798 formatter.dedent() |
|
799 # Drop the last "\n", or the header if no options or option groups: |
|
800 return string.join(result[:-1], "") |
|
801 |
|
802 def format_help(self, formatter=None): |
|
803 if formatter is None: |
|
804 formatter = self.formatter |
|
805 result = [] |
|
806 if self.usage: |
|
807 result.append(self.get_usage() + "\n") |
|
808 if self.description: |
|
809 result.append(self.format_description(formatter) + "\n") |
|
810 result.append(self.format_option_help(formatter)) |
|
811 return string.join(result, "") |
|
812 |
|
813 def print_help(self, file=None): |
|
814 """print_help(file : file = stdout) |
|
815 |
|
816 Print an extended help message, listing all options and any |
|
817 help text provided with them, to 'file' (default stdout). |
|
818 """ |
|
819 if file is None: |
|
820 file = sys.stdout |
|
821 file.write(self.format_help()) |
|
822 |
|
823 # class OptionParser |
|
824 |
|
825 |
|
826 def _match_abbrev(s, wordmap): |
|
827 """_match_abbrev(s : string, wordmap : {string : Option}) -> string |
|
828 |
|
829 Return the string key in 'wordmap' for which 's' is an unambiguous |
|
830 abbreviation. If 's' is found to be ambiguous or doesn't match any of |
|
831 'words', raise BadOptionError. |
|
832 """ |
|
833 # Is there an exact match? |
|
834 if wordmap.has_key(s): |
|
835 return s |
|
836 else: |
|
837 # Isolate all words with s as a prefix. |
|
838 possibilities = [] |
|
839 for word in wordmap.keys(): |
|
840 if string.startswith(word, s): |
|
841 possibilities.append(word) |
|
842 # No exact match, so there had better be just one possibility. |
|
843 if len(possibilities) == 1: |
|
844 return possibilities[0] |
|
845 elif not possibilities: |
|
846 raise errors.BadOptionError(s) |
|
847 else: |
|
848 # More than one possible completion: ambiguous prefix. |
|
849 raise errors.AmbiguousOptionError(s, possibilities) |