3 Provides the OptionParser and Values classes.
5 Cheetah modifications: added "Cheetah.Utils.optik." prefix to
6 all intra-Optik imports.
9 __revision__
= "$Id: option_parser.py,v 1.2 2002/09/12 06:56:51 hierro Exp $"
11 # Copyright (c) 2001 Gregory P. Ward. All rights reserved.
12 # See the README.txt distributed with Optik for licensing terms.
14 # created 2001/10/17, GPW (from optik.py)
18 from Cheetah
.Utils
.optik
.option
import Option
, NO_DEFAULT
19 from Cheetah
.Utils
.optik
.errors
import OptionConflictError
, OptionValueError
, BadOptionError
22 return os
.path
.basename(sys
.argv
[0])
25 SUPPRESS_HELP
= "SUPPRESS"+"HELP"
26 SUPPRESS_USAGE
= "SUPPRESS"+"USAGE"
28 STD_HELP_OPTION
= Option("-h", "--help",
30 help="show this help message and exit")
31 STD_VERSION_OPTION
= Option("--version",
33 help="show program's version number and exit")
38 def __init__ (self
, defaults
=None):
40 for (attr
, val
) in defaults
.items():
41 setattr(self
, attr
, val
)
44 def _update_careful (self
, dict):
46 Update the option values from an arbitrary dictionary, but only
47 use keys from dict that already have a corresponding attribute
48 in self. Any keys in dict without a corresponding attribute
51 for attr
in dir(self
):
52 if dict.has_key(attr
):
55 setattr(self
, attr
, dval
)
57 def _update_loose (self
, dict):
59 Update the option values from an arbitrary dictionary,
60 using all keys from the dictionary regardless of whether
61 they have a corresponding attribute in self or not.
63 self
.__dict
__.update(dict)
65 def _update (self
, dict, mode
):
67 self
._update
_careful
(dict)
69 self
._update
_loose
(dict)
71 raise ValueError, "invalid update mode: %r" % mode
73 def read_module (self
, modname
, mode
="careful"):
75 mod
= sys
.modules
[modname
]
76 self
._update
(vars(mod
), mode
)
78 def read_file (self
, filename
, mode
="careful"):
80 execfile(filename
, vars)
81 self
._update
(vars, mode
)
83 def ensure_value (self
, attr
, value
):
84 if not hasattr(self
, attr
) or getattr(self
, attr
) is None:
85 setattr(self
, attr
, value
)
86 return getattr(self
, attr
)
92 standard_option_list : [Option]
93 list of standard options that will be accepted by all instances
94 of this parser class (intended to be overridden by subclasses).
98 a usage string for your program. Before it is displayed
99 to the user, "%prog" will be expanded to the name of
100 your program (os.path.basename(sys.argv[0])).
101 option_list : [Option]
102 the list of all options accepted on the command-line of
104 _short_opt : { string : Option }
105 dictionary mapping short option strings, eg. "-f" or "-X",
106 to the Option instances that implement them. If an Option
107 has multiple short option strings, it will appears in this
108 dictionary multiple times.
109 _long_opt : { string : Option }
110 dictionary mapping long option strings, eg. "--file" or
111 "--exclude", to the Option instances that implement them.
112 Again, a given Option can occur multiple times in this
114 _long_opts : [string]
115 list of long option strings recognized by this option
116 parser. Should be equal to _long_opt.values().
117 defaults : { string : any }
118 dictionary mapping option destination names to default
119 values for each destination.
121 allow_interspersed_args : boolean = true
122 if true, positional arguments may be interspersed with options.
123 Assuming -a and -b each take a single argument, the command-line
124 -ablah foo bar -bboo baz
125 will be interpreted the same as
126 -ablah -bboo -- foo bar baz
127 If this flag were false, that command line would be interpreted as
128 -ablah -- foo bar -bboo baz
129 -- ie. we stop processing options as soon as we see the first
130 non-option argument. (This is the tradition followed by
131 Python's getopt module, Perl's Getopt::Std, and other argument-
132 parsing libraries, but it is generally annoying to users.)
135 the argument list currently being parsed. Only set when
136 parse_args() is active, and continually trimmed down as
137 we consume arguments. Mainly there for the benefit of
140 the list of leftover arguments that we have skipped while
141 parsing options. If allow_interspersed_args is false, this
142 list is always empty.
144 the set of option values currently being accumulated. Only
145 set when parse_args() is active. Also mainly for callbacks.
147 Because of the 'rargs', 'largs', and 'values' attributes,
148 OptionParser is not thread-safe. If, for some perverse reason, you
149 need to parse command-line arguments simultaneously in different
150 threads, use different OptionParser instances.
154 standard_option_list
= [STD_HELP_OPTION
]
162 conflict_handler
="error"):
163 self
.set_usage(usage
)
164 self
.option_class
= option_class
165 self
.version
= version
166 self
.set_conflict_handler(conflict_handler
)
167 self
.allow_interspersed_args
= 1
169 # Create the various lists and dicts that constitute the
170 # "option list". See class docstring for details about
172 self
._create
_option
_list
()
174 # Populate the option list; initial sources are the
175 # standard_option_list class attribute, the 'option_list'
176 # argument, and the STD_VERSION_OPTION global (if 'version'
178 self
._populate
_option
_list
(option_list
)
180 self
._init
_parsing
_state
()
182 # -- Private methods -----------------------------------------------
183 # (used by the constructor)
185 def _create_option_list (self
):
186 self
.option_list
= []
187 self
._short
_opt
= {} # single letter -> Option instance
188 self
._long
_opt
= {} # long option -> Option instance
189 self
._long
_opts
= [] # list of long options
190 self
.defaults
= {} # maps option dest -> default value
192 def _populate_option_list (self
, option_list
):
193 if self
.standard_option_list
:
194 self
.add_options(self
.standard_option_list
)
196 self
.add_option(STD_VERSION_OPTION
)
198 self
.add_options(option_list
)
200 def _init_parsing_state (self
):
201 # These are set in parse_args() for the convenience of callbacks.
207 # -- Simple modifier methods ---------------------------------------
209 def set_usage (self
, usage
):
211 self
.usage
= "usage: %prog [options]"
212 elif usage
is SUPPRESS_USAGE
:
217 def enable_interspersed_args (self
):
218 self
.allow_interspersed_args
= 1
220 def disable_interspersed_args (self
):
221 self
.allow_interspersed_args
= 0
223 def set_conflict_handler (self
, handler
):
224 if handler
not in ("ignore", "error", "resolve"):
225 raise ValueError, "invalid conflict_resolution value %r" % handler
226 self
.conflict_handler
= handler
228 def set_default (self
, dest
, value
):
229 self
.defaults
[dest
] = value
231 def set_defaults (self
, **kwargs
):
232 self
.defaults
.update(kwargs
)
235 # -- Option-adding methods -----------------------------------------
237 def _check_conflict (self
, option
):
239 for opt
in option
._short
_opts
:
240 if self
._short
_opt
.has_key(opt
):
241 conflict_opts
.append((opt
, self
._short
_opt
[opt
]))
242 for opt
in option
._long
_opts
:
243 if self
._long
_opt
.has_key(opt
):
244 conflict_opts
.append((opt
, self
._long
_opt
[opt
]))
247 handler
= self
.conflict_handler
248 if handler
== "ignore": # behaviour for Optik 1.0, 1.1
250 elif handler
== "error": # new in 1.2
251 raise OptionConflictError(
252 "conflicting option string(s): %s"
253 % ", ".join([co
[0] for co
in conflict_opts
]),
255 elif handler
== "resolve": # new in 1.2
256 for (opt
, c_option
) in conflict_opts
:
257 if opt
.startswith("--"):
258 c_option
._long
_opts
.remove(opt
)
259 del self
._long
_opt
[opt
]
261 c_option
._short
_opts
.remove(opt
)
262 del self
._short
_opt
[opt
]
263 if not (c_option
._short
_opts
or c_option
._long
_opts
):
264 self
.option_list
.remove(c_option
)
267 def add_option (self
, *args
, **kwargs
):
268 """add_option(Option)
269 add_option(opt_str, ..., kwarg=val, ...)
271 if type(args
[0]) is types
.StringType
:
272 option
= self
.option_class(*args
, **kwargs
)
273 elif len(args
) == 1 and not kwargs
:
275 if not isinstance(option
, Option
):
276 raise TypeError, "not an Option instance: %r" % option
278 raise TypeError, "invalid arguments"
280 self
._check
_conflict
(option
)
282 self
.option_list
.append(option
)
283 for opt
in option
._short
_opts
:
284 self
._short
_opt
[opt
] = option
285 for opt
in option
._long
_opts
:
286 self
._long
_opt
[opt
] = option
287 self
._long
_opts
.append(opt
)
289 if option
.dest
is not None: # option has a dest, we need a default
290 if option
.default
is not NO_DEFAULT
:
291 self
.defaults
[option
.dest
] = option
.default
292 elif not self
.defaults
.has_key(option
.dest
):
293 self
.defaults
[option
.dest
] = None
295 def add_options (self
, option_list
):
296 for option
in option_list
:
297 self
.add_option(option
)
300 # -- Option query/removal methods ----------------------------------
302 def get_option (self
, opt_str
):
303 return (self
._short
_opt
.get(opt_str
) or
304 self
._long
_opt
.get(opt_str
))
306 def has_option (self
, opt_str
):
307 return (self
._short
_opt
.has_key(opt_str
) or
308 self
._long
_opt
.has_key(opt_str
))
311 def remove_option (self
, opt_str
):
312 option
= self
._short
_opt
.get(opt_str
)
314 option
= self
._long
_opt
.get(opt_str
)
316 raise ValueError("no such option %r" % opt_str
)
318 for opt
in option
._short
_opts
:
319 del self
._short
_opt
[opt
]
320 for opt
in option
._long
_opts
:
321 del self
._long
_opt
[opt
]
322 self
._long
_opts
.remove(opt
)
323 self
.option_list
.remove(option
)
326 # -- Option-parsing methods ----------------------------------------
328 def _get_args (self
, args
):
332 return args
[:] # don't modify caller's list
334 def parse_args (self
, args
=None, values
=None):
336 parse_args(args : [string] = sys.argv[1:],
337 values : Values = None)
338 -> (values : Values, args : [string])
340 Parse the command-line options found in 'args' (default:
341 sys.argv[1:]). Any errors result in a call to 'error()', which
342 by default prints the usage message to stderr and calls
343 sys.exit() with an error message. On success returns a pair
344 (values, args) where 'values' is an Values instance (with all
345 your option values) and 'args' is the list of arguments left
346 over after parsing options.
348 rargs
= self
._get
_args
(args
)
350 values
= Values(self
.defaults
)
352 # Store the halves of the argument list as attributes for the
353 # convenience of callbacks:
355 # the rest of the command-line (the "r" stands for
356 # "remaining" or "right-hand")
358 # the leftover arguments -- ie. what's left after removing
359 # options and their arguments (the "l" stands for "leftover"
362 # Say this is the original argument list:
363 # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
365 # (we are about to process arg(i)).
367 # Then rargs is [arg(i), ..., arg(N-1)]
368 # and largs is a *subset* of [arg0, ..., arg(i-1)]
369 # (any options and their arguments will have been removed
372 # _process_arg() will always consume 1 or more arguments.
373 # If it consumes 1 (eg. arg is an option that takes no arguments),
374 # then after _process_arg() is done the situation is:
375 # largs = subset of [arg0, ..., arg(i)]
376 # rargs = [arg(i+1), ..., arg(N-1)]
378 # If allow_interspersed_args is false, largs will always be
379 # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
380 # not a very interesting subset!
383 self
.largs
= largs
= []
387 while rargs
and not stop
:
389 stop
= self
._process
_arg
(largs
, rargs
, values
)
390 except (BadOptionError
, OptionValueError
), err
:
394 return self
.check_values(values
, args
)
396 def check_values (self
, values
, args
):
398 check_values(values : Values, args : [string])
399 -> (values : Values, args : [string])
401 Check that the supplied option values and leftover arguments are
402 valid. Returns the option values and leftover arguments
403 (possibly adjusted, possibly completely new -- whatever you
404 like). Default implementation just returns the passed-in
405 values; subclasses may override as desired.
407 return (values
, args
)
409 def _process_arg (self
, largs
, rargs
, values
):
410 """_process_args(largs : [string],
415 Process a single command-line argument, consuming zero or more
416 arguments. The next argument to process is rargs[0], which will
417 almost certainly be consumed from rargs. (It might wind up in
418 largs, or it might affect a value in values, or -- if a callback
419 is involved -- almost anything might happen. It will not be
420 consumed if it is a non-option argument and
421 allow_interspersed_args is false.) More arguments from rargs
422 may also be consumed, depending on circumstances.
424 Returns true if option processing should stop after this
425 argument is processed.
428 # We handle bare "--" explicitly, and bare "-" is handled by the
429 # standard arg handler since the short arg case ensures that the len
430 # of the opt string is greater than 1.
436 elif arg
[0:2] == "--":
437 # process a single long option (possibly with value(s))
438 self
._process
_long
_opt
(rargs
, values
)
439 elif arg
[:1] == "-" and len(arg
) > 1:
440 # process a cluster of short options (possibly with
441 # value(s) for the last one only)
442 self
._process
_short
_opts
(rargs
, values
)
444 if self
.allow_interspersed_args
:
448 return 1 # stop now, leave this arg in rargs
450 return 0 # keep processing args
452 def _match_long_opt (self
, opt
):
453 """_match_long_opt(opt : string) -> string
455 Determine which long option string 'opt' matches, ie. which one
456 it is an unambiguous abbrevation for. Raises BadOptionError if
457 'opt' doesn't unambiguously match any long option string.
459 return _match_abbrev(opt
, self
._long
_opts
)
461 def _process_long_opt (self
, rargs
, values
):
464 # Value explicitly attached to arg? Pretend it's the next
467 (opt
, next_arg
) = arg
.split("=", 1)
468 rargs
.insert(0, next_arg
)
469 had_explicit_value
= 1
472 had_explicit_value
= 0
474 opt
= self
._match
_long
_opt
(opt
)
475 option
= self
._long
_opt
[opt
]
476 if option
.takes_value():
478 if len(rargs
) < nargs
:
480 self
.error("%s option requires a value" % opt
)
482 self
.error("%s option requires %d values"
487 value
= tuple(rargs
[0:nargs
])
490 elif had_explicit_value
:
491 self
.error("%s option does not take a value" % opt
)
496 option
.process(opt
, value
, values
, self
)
498 def _process_short_opts (self
, rargs
, values
):
504 option
= self
._short
_opt
.get(opt
)
505 i
+= 1 # we have consumed a character
508 self
.error("no such option: %s" % opt
)
509 if option
.takes_value():
510 # Any characters left in arg? Pretend they're the
511 # next arg, and stop consuming characters of arg.
513 rargs
.insert(0, arg
[i
:])
517 if len(rargs
) < nargs
:
519 self
.error("%s option requires a value" % opt
)
521 self
.error("%s option requires %s values"
526 value
= tuple(rargs
[0:nargs
])
529 else: # option doesn't take a value
532 option
.process(opt
, value
, values
, self
)
538 # -- Output/error methods ------------------------------------------
540 def error (self
, msg
):
541 self
.print_usage(sys
.stderr
)
542 sys
.exit("%s: error: %s" % (get_prog_name(), msg
))
544 def print_usage (self
, file=None):
546 usage
= self
.usage
.replace("%prog", get_prog_name())
550 def print_version (self
, file=None):
552 version
= self
.version
.replace("%prog", get_prog_name())
553 print >>file, version
555 def print_help (self
, file=None):
556 from distutils
.fancy_getopt
import wrap_text
561 self
.print_usage(file)
563 # The help for each option consists of two parts:
564 # * the opt strings and metavars
565 # eg. ("-x", or "-fFILENAME, --file=FILENAME")
566 # * the user-supplied help string
567 # eg. ("turn on expert mode", "read data from FILENAME")
569 # If possible, we write both of these on the same line:
570 # -x turn on expert mode
572 # But if the opt string list is too long, we put the help
573 # string on a second line, indented to the same column it would
574 # start in if it fit on the first line.
575 # -fFILENAME, --file=FILENAME
576 # read data from FILENAME
578 print >>file, "options:"
579 width
= 78 # assume 80 cols for now
581 option_help
= [] # list of (string, string) tuples
584 for option
in self
.option_list
:
585 takes_value
= option
.takes_value()
587 metavar
= option
.metavar
or option
.dest
.upper()
589 opts
= [] # list of "-a" or "--foo=FILE" strings
590 if option
.help is SUPPRESS_HELP
:
594 for sopt
in option
._short
_opts
:
595 opts
.append(sopt
+ metavar
)
596 for lopt
in option
._long
_opts
:
597 opts
.append(lopt
+ "=" + metavar
)
599 for opt
in option
._short
_opts
+ option
._long
_opts
:
602 opts
= ", ".join(opts
)
603 option_help
.append((opts
, option
.help))
604 lengths
.append(len(opts
))
606 max_opts
= min(max(lengths
), 20)
608 for (opts
, help) in option_help
:
609 # how much to indent lines 2 .. N of help text
610 indent_rest
= 2 + max_opts
+ 2
611 help_width
= width
- indent_rest
613 if len(opts
) > max_opts
:
614 opts
= " " + opts
+ "\n"
615 indent_first
= indent_rest
617 else: # start help on same line as opts
618 opts
= " %-*s " % (max_opts
, opts
)
624 help_lines
= wrap_text(help, help_width
)
625 print >>file, "%*s%s" % (indent_first
, "", help_lines
[0])
626 for line
in help_lines
[1:]:
627 print >>file, "%*s%s" % (indent_rest
, "", line
)
628 elif opts
[-1] != "\n":
634 def _match_abbrev (s
, words
):
635 """_match_abbrev(s : string, words : [string]) -> string
637 Returns the string in 'words' for which 's' is an unambiguous
638 abbreviation. If 's' is found to be ambiguous or doesn't match any
639 of 'words', raises BadOptionError.
643 # If s isn't even a prefix for this word, don't waste any
644 # more time on it: skip to the next word and try again.
645 if not word
.startswith(s
):
648 # Exact match? Great, return now.
652 # Now comes the tricky business of disambiguation. At this
653 # point, we know s is a proper prefix of word, eg. s='--foo' and
654 # word=='--foobar'. If we have already seen another word where
655 # this was the case, eg. '--foobaz', fail: s is ambiguous.
656 # Otherwise record this match and keep looping; we will return
657 # if we see an exact match, or when we fall out of the loop and
658 # it turns out that the current word is the match.
660 raise BadOptionError("ambiguous option: %s (%s, %s, ...?)"
667 raise BadOptionError("no such option: %s" % s
)