Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Private Member Functions
distutils.fancy_getopt.FancyGetopt Class Reference

List of all members.

Public Member Functions

def __init__
def set_option_table
def add_option
def has_option
def get_attr_name
def set_aliases
def set_negative_aliases
def getopt
def get_option_order
def generate_help
def print_help

Public Attributes

 option_table
 option_index
 alias
 negative_alias
 short_opts
 long_opts
 short2long
 attr_name
 takes_arg
 option_order
 repeat

Private Member Functions

def _build_index
def _check_alias_dict
def _grok_option_table

Detailed Description

Wrapper around the standard 'getopt()' module that provides some
handy extra functionality:
  * short and long options are tied together
  * options have help strings, and help text can be assembled
    from them
  * options set attributes of a passed-in object
  * boolean options can have "negative aliases" -- eg. if
    --quiet is the "negative alias" of --verbose, then "--quiet"
    on the command line sets 'verbose' to false

Definition at line 29 of file fancy_getopt.py.


Constructor & Destructor Documentation

def distutils.fancy_getopt.FancyGetopt.__init__ (   self,
  option_table = None 
)

Definition at line 41 of file fancy_getopt.py.

00041 
00042     def __init__(self, option_table=None):
00043         # The option table is (currently) a list of tuples.  The
00044         # tuples may have 3 or four values:
00045         #   (long_option, short_option, help_string [, repeatable])
00046         # if an option takes an argument, its long_option should have '='
00047         # appended; short_option should just be a single character, no ':'
00048         # in any case.  If a long_option doesn't have a corresponding
00049         # short_option, short_option should be None.  All option tuples
00050         # must have long options.
00051         self.option_table = option_table
00052 
00053         # 'option_index' maps long option names to entries in the option
00054         # table (ie. those 3-tuples).
00055         self.option_index = {}
00056         if self.option_table:
00057             self._build_index()
00058 
00059         # 'alias' records (duh) alias options; {'foo': 'bar'} means
00060         # --foo is an alias for --bar
00061         self.alias = {}
00062 
00063         # 'negative_alias' keeps track of options that are the boolean
00064         # opposite of some other option
00065         self.negative_alias = {}
00066 
00067         # These keep track of the information in the option table.  We
00068         # don't actually populate these structures until we're ready to
00069         # parse the command-line, since the 'option_table' passed in here
00070         # isn't necessarily the final word.
00071         self.short_opts = []
00072         self.long_opts = []
00073         self.short2long = {}
00074         self.attr_name = {}
00075         self.takes_arg = {}
00076 
00077         # And 'option_order' is filled up in 'getopt()'; it records the
00078         # original order of options (and their values) on the command-line,
00079         # but expands short options, converts aliases, etc.
00080         self.option_order = []

Here is the caller graph for this function:


Member Function Documentation

Definition at line 81 of file fancy_getopt.py.

00081 
00082     def _build_index(self):
00083         self.option_index.clear()
00084         for option in self.option_table:
00085             self.option_index[option[0]] = option

Here is the caller graph for this function:

def distutils.fancy_getopt.FancyGetopt._check_alias_dict (   self,
  aliases,
  what 
) [private]

Definition at line 110 of file fancy_getopt.py.

00110 
00111     def _check_alias_dict(self, aliases, what):
00112         assert isinstance(aliases, dict)
00113         for (alias, opt) in aliases.items():
00114             if alias not in self.option_index:
00115                 raise DistutilsGetoptError(("invalid %s '%s': "
00116                        "option '%s' not defined") % (what, alias, alias))
00117             if opt not in self.option_index:
00118                 raise DistutilsGetoptError(("invalid %s '%s': "
00119                        "aliased option '%s' not defined") % (what, alias, opt))

Here is the caller graph for this function:

Populate the various data structures that keep tabs on the
option table.  Called by 'getopt()' before it can do anything
worthwhile.

Definition at line 133 of file fancy_getopt.py.

00133 
00134     def _grok_option_table(self):
00135         """Populate the various data structures that keep tabs on the
00136         option table.  Called by 'getopt()' before it can do anything
00137         worthwhile.
00138         """
00139         self.long_opts = []
00140         self.short_opts = []
00141         self.short2long.clear()
00142         self.repeat = {}
00143 
00144         for option in self.option_table:
00145             if len(option) == 3:
00146                 long, short, help = option
00147                 repeat = 0
00148             elif len(option) == 4:
00149                 long, short, help, repeat = option
00150             else:
00151                 # the option table is part of the code, so simply
00152                 # assert that it is correct
00153                 raise ValueError("invalid option tuple: %r" % (option,))
00154 
00155             # Type- and value-check the option names
00156             if not isinstance(long, str) or len(long) < 2:
00157                 raise DistutilsGetoptError(("invalid long option '%s': "
00158                        "must be a string of length >= 2") % long)
00159 
00160             if (not ((short is None) or
00161                      (isinstance(short, str) and len(short) == 1))):
00162                 raise DistutilsGetoptError("invalid short option '%s': "
00163                        "must a single character or None" % short)
00164 
00165             self.repeat[long] = repeat
00166             self.long_opts.append(long)
00167 
00168             if long[-1] == '=':             # option takes an argument?
00169                 if short: short = short + ':'
00170                 long = long[0:-1]
00171                 self.takes_arg[long] = 1
00172             else:
00173                 # Is option is a "negative alias" for some other option (eg.
00174                 # "quiet" == "!verbose")?
00175                 alias_to = self.negative_alias.get(long)
00176                 if alias_to is not None:
00177                     if self.takes_arg[alias_to]:
00178                         raise DistutilsGetoptError(
00179                               "invalid negative alias '%s': "
00180                               "aliased option '%s' takes a value"
00181                               % (long, alias_to))
00182 
00183                     self.long_opts[-1] = long # XXX redundant?!
00184                 self.takes_arg[long] = 0
00185 
00186             # If this is an alias option, make sure its "takes arg" flag is
00187             # the same as the option it's aliased to.
00188             alias_to = self.alias.get(long)
00189             if alias_to is not None:
00190                 if self.takes_arg[long] != self.takes_arg[alias_to]:
00191                     raise DistutilsGetoptError(
00192                           "invalid alias '%s': inconsistent with "
00193                           "aliased option '%s' (one of them takes a value, "
00194                           "the other doesn't"
00195                           % (long, alias_to))
00196 
00197             # Now enforce some bondage on the long option name, so we can
00198             # later translate it to an attribute name on some object.  Have
00199             # to do this a bit late to make sure we've removed any trailing
00200             # '='.
00201             if not longopt_re.match(long):
00202                 raise DistutilsGetoptError(
00203                        "invalid long option name '%s' "
00204                        "(must be letters, numbers, hyphens only" % long)
00205 
00206             self.attr_name[long] = self.get_attr_name(long)
00207             if short:
00208                 self.short_opts.append(short)
00209                 self.short2long[short[0]] = long

Here is the caller graph for this function:

def distutils.fancy_getopt.FancyGetopt.add_option (   self,
  long_option,
  short_option = None,
  help_string = None 
)

Definition at line 90 of file fancy_getopt.py.

00090 
00091     def add_option(self, long_option, short_option=None, help_string=None):
00092         if long_option in self.option_index:
00093             raise DistutilsGetoptError(
00094                   "option conflict: already an option '%s'" % long_option)
00095         else:
00096             option = (long_option, short_option, help_string)
00097             self.option_table.append(option)
00098             self.option_index[long_option] = option

Here is the caller graph for this function:

def distutils.fancy_getopt.FancyGetopt.generate_help (   self,
  header = None 
)
Generate help text (a list of strings, one per suggested line of
output) from the option table for this FancyGetopt object.

Definition at line 281 of file fancy_getopt.py.

00281 
00282     def generate_help(self, header=None):
00283         """Generate help text (a list of strings, one per suggested line of
00284         output) from the option table for this FancyGetopt object.
00285         """
00286         # Blithely assume the option table is good: probably wouldn't call
00287         # 'generate_help()' unless you've already called 'getopt()'.
00288 
00289         # First pass: determine maximum length of long option names
00290         max_opt = 0
00291         for option in self.option_table:
00292             long = option[0]
00293             short = option[1]
00294             l = len(long)
00295             if long[-1] == '=':
00296                 l = l - 1
00297             if short is not None:
00298                 l = l + 5                   # " (-x)" where short == 'x'
00299             if l > max_opt:
00300                 max_opt = l
00301 
00302         opt_width = max_opt + 2 + 2 + 2     # room for indent + dashes + gutter
00303 
00304         # Typical help block looks like this:
00305         #   --foo       controls foonabulation
00306         # Help block for longest option looks like this:
00307         #   --flimflam  set the flim-flam level
00308         # and with wrapped text:
00309         #   --flimflam  set the flim-flam level (must be between
00310         #               0 and 100, except on Tuesdays)
00311         # Options with short names will have the short name shown (but
00312         # it doesn't contribute to max_opt):
00313         #   --foo (-f)  controls foonabulation
00314         # If adding the short option would make the left column too wide,
00315         # we push the explanation off to the next line
00316         #   --flimflam (-l)
00317         #               set the flim-flam level
00318         # Important parameters:
00319         #   - 2 spaces before option block start lines
00320         #   - 2 dashes for each long option name
00321         #   - min. 2 spaces between option and explanation (gutter)
00322         #   - 5 characters (incl. space) for short option name
00323 
00324         # Now generate lines of help text.  (If 80 columns were good enough
00325         # for Jesus, then 78 columns are good enough for me!)
00326         line_width = 78
00327         text_width = line_width - opt_width
00328         big_indent = ' ' * opt_width
00329         if header:
00330             lines = [header]
00331         else:
00332             lines = ['Option summary:']
00333 
00334         for option in self.option_table:
00335             long, short, help = option[:3]
00336             text = wrap_text(help, text_width)
00337             if long[-1] == '=':
00338                 long = long[0:-1]
00339 
00340             # Case 1: no short option at all (makes life easy)
00341             if short is None:
00342                 if text:
00343                     lines.append("  --%-*s  %s" % (max_opt, long, text[0]))
00344                 else:
00345                     lines.append("  --%-*s  " % (max_opt, long))
00346 
00347             # Case 2: we have a short option, so we have to include it
00348             # just after the long option
00349             else:
00350                 opt_names = "%s (-%s)" % (long, short)
00351                 if text:
00352                     lines.append("  --%-*s  %s" %
00353                                  (max_opt, opt_names, text[0]))
00354                 else:
00355                     lines.append("  --%-*s" % opt_names)
00356 
00357             for l in text[1:]:
00358                 lines.append(big_indent + l)
00359         return lines

Here is the call graph for this function:

Here is the caller graph for this function:

def distutils.fancy_getopt.FancyGetopt.get_attr_name (   self,
  long_option 
)
Translate long option name 'long_option' to the form it
has as an attribute of some object: ie., translate hyphens
to underscores.

Definition at line 104 of file fancy_getopt.py.

00104 
00105     def get_attr_name(self, long_option):
00106         """Translate long option name 'long_option' to the form it
00107         has as an attribute of some object: ie., translate hyphens
00108         to underscores."""
00109         return long_option.translate(longopt_xlate)

Returns the list of (option, value) tuples processed by the
previous run of 'getopt()'.  Raises RuntimeError if
'getopt()' hasn't been called yet.

Definition at line 271 of file fancy_getopt.py.

00271 
00272     def get_option_order(self):
00273         """Returns the list of (option, value) tuples processed by the
00274         previous run of 'getopt()'.  Raises RuntimeError if
00275         'getopt()' hasn't been called yet.
00276         """
00277         if self.option_order is None:
00278             raise RuntimeError("'getopt()' hasn't been called yet")
00279         else:
00280             return self.option_order

def distutils.fancy_getopt.FancyGetopt.getopt (   self,
  args = None,
  object = None 
)
Parse command-line options in args. Store as attributes on object.

If 'args' is None or not supplied, uses 'sys.argv[1:]'.  If
'object' is None or not supplied, creates a new OptionDummy
object, stores option values there, and returns a tuple (args,
object).  If 'object' is supplied, it is modified in place and
'getopt()' just returns 'args'; in both cases, the returned
'args' is a modified copy of the passed-in 'args' list, which
is left untouched.

Definition at line 210 of file fancy_getopt.py.

00210 
00211     def getopt(self, args=None, object=None):
00212         """Parse command-line options in args. Store as attributes on object.
00213 
00214         If 'args' is None or not supplied, uses 'sys.argv[1:]'.  If
00215         'object' is None or not supplied, creates a new OptionDummy
00216         object, stores option values there, and returns a tuple (args,
00217         object).  If 'object' is supplied, it is modified in place and
00218         'getopt()' just returns 'args'; in both cases, the returned
00219         'args' is a modified copy of the passed-in 'args' list, which
00220         is left untouched.
00221         """
00222         if args is None:
00223             args = sys.argv[1:]
00224         if object is None:
00225             object = OptionDummy()
00226             created_object = True
00227         else:
00228             created_object = False
00229 
00230         self._grok_option_table()
00231 
00232         short_opts = ' '.join(self.short_opts)
00233         try:
00234             opts, args = getopt.getopt(args, short_opts, self.long_opts)
00235         except getopt.error as msg:
00236             raise DistutilsArgError(msg)
00237 
00238         for opt, val in opts:
00239             if len(opt) == 2 and opt[0] == '-': # it's a short option
00240                 opt = self.short2long[opt[1]]
00241             else:
00242                 assert len(opt) > 2 and opt[:2] == '--'
00243                 opt = opt[2:]
00244 
00245             alias = self.alias.get(opt)
00246             if alias:
00247                 opt = alias
00248 
00249             if not self.takes_arg[opt]:     # boolean option?
00250                 assert val == '', "boolean option can't have value"
00251                 alias = self.negative_alias.get(opt)
00252                 if alias:
00253                     opt = alias
00254                     val = 0
00255                 else:
00256                     val = 1
00257 
00258             attr = self.attr_name[opt]
00259             # The only repeating option at the moment is 'verbose'.
00260             # It has a negative option -q quiet, which should set verbose = 0.
00261             if val and self.repeat.get(attr) is not None:
00262                 val = getattr(object, attr, 0) + 1
00263             setattr(object, attr, val)
00264             self.option_order.append((opt, val))
00265 
00266         # for opts
00267         if created_object:
00268             return args, object
00269         else:
00270             return args

Here is the call graph for this function:

def distutils.fancy_getopt.FancyGetopt.has_option (   self,
  long_option 
)
Return true if the option table for this parser has an
option with long name 'long_option'.

Definition at line 99 of file fancy_getopt.py.

00099 
00100     def has_option(self, long_option):
00101         """Return true if the option table for this parser has an
00102         option with long name 'long_option'."""
00103         return long_option in self.option_index

def distutils.fancy_getopt.FancyGetopt.print_help (   self,
  header = None,
  file = None 
)

Definition at line 360 of file fancy_getopt.py.

00360 
00361     def print_help(self, header=None, file=None):
00362         if file is None:
00363             file = sys.stdout
00364         for line in self.generate_help(header):
00365             file.write(line + "\n")
00366 

Here is the call graph for this function:

Set the aliases for this option parser.

Definition at line 120 of file fancy_getopt.py.

00120 
00121     def set_aliases(self, alias):
00122         """Set the aliases for this option parser."""
00123         self._check_alias_dict(alias, "alias")
00124         self.alias = alias

Here is the call graph for this function:

def distutils.fancy_getopt.FancyGetopt.set_negative_aliases (   self,
  negative_alias 
)
Set the negative aliases for this option parser.
'negative_alias' should be a dictionary mapping option names to
option names, both the key and value must already be defined
in the option table.

Definition at line 125 of file fancy_getopt.py.

00125 
00126     def set_negative_aliases(self, negative_alias):
00127         """Set the negative aliases for this option parser.
00128         'negative_alias' should be a dictionary mapping option names to
00129         option names, both the key and value must already be defined
00130         in the option table."""
00131         self._check_alias_dict(negative_alias, "negative alias")
00132         self.negative_alias = negative_alias

Here is the call graph for this function:

def distutils.fancy_getopt.FancyGetopt.set_option_table (   self,
  option_table 
)

Definition at line 86 of file fancy_getopt.py.

00086 
00087     def set_option_table(self, option_table):
00088         self.option_table = option_table
00089         self._build_index()

Here is the call graph for this function:


Member Data Documentation

Definition at line 60 of file fancy_getopt.py.

Definition at line 73 of file fancy_getopt.py.

Definition at line 71 of file fancy_getopt.py.

Definition at line 64 of file fancy_getopt.py.

Definition at line 54 of file fancy_getopt.py.

Definition at line 79 of file fancy_getopt.py.

Definition at line 50 of file fancy_getopt.py.

Definition at line 141 of file fancy_getopt.py.

Definition at line 72 of file fancy_getopt.py.

Definition at line 70 of file fancy_getopt.py.

Definition at line 74 of file fancy_getopt.py.


The documentation for this class was generated from the following file: