Changeset 455

Show
Ignore:
Timestamp:
Mon May 5 12:04:56 2008
Author:
naufraghi
Message:

Merged revisions 317-334 via svnmerge from
https://svn.pyinstaller.python-hosting.com/trunk[[BR]]
........

r317 | giovannibajo | 2007-05-07 01:19:09 +0200 (Mon, 07 May 2007) | 2 lines

Document the xmlplus hack
........
r318 | giovannibajo | 2007-08-08 09:44:20 +0200 (Wed, 08 Aug 2007) | 2 lines

Added hidden import in PyQt4 (consolidated module)
........
r319 | giovannibajo | 2007-10-02 14:51:28 +0200 (Tue, 02 Oct 2007) | 2 lines

Add support for new absolute imports in Python 2.5 (patch by Arve Knudsen <arve.knudsen@gmail.com>)
........
r320 | giovannibajo | 2007-11-06 09:26:59 +0100 (Tue, 06 Nov 2007) | 2 lines

Make optparse/optik use native line endings.
........
r321 | giovannibajo | 2007-11-06 09:29:35 +0100 (Tue, 06 Nov 2007) | 2 lines

Update CHANGES.TXT.
........
r322 | giovannibajo | 2007-11-06 09:40:38 +0100 (Tue, 06 Nov 2007) | 2 lines

Ticket #19: Missing Python 2.5 ElementTree? hook.
........
r323 | giovannibajo | 2007-11-14 12:51:41 +0100 (Wed, 14 Nov 2007) | 2 lines

Change wrong license from support files: they ought to be GPL+exceptions like the others.
........
r324 | danielevarrazzo | 2007-11-16 19:26:17 +0100 (Fri, 16 Nov 2007) | 5 lines

- Added getImports implementation using otool (available on darwin platform)

Covers the update [294] in /branches/mac.
[295] should not be required anymore.

- Using explicit names for implementation-dependant import functions.
........
r325 | danielevarrazzo | 2007-11-16 23:53:50 +0100 (Fri, 16 Nov 2007) | 4 lines

Perform case sensitive check if this is how Python is working.

Merged from [300].
........
r326 | danielevarrazzo | 2007-11-17 00:01:00 +0100 (Sat, 17 Nov 2007) | 2 lines

Search modules in the sys.path before than in other paths.
........
r327 | danielevarrazzo | 2007-11-17 00:10:02 +0100 (Sat, 17 Nov 2007) | 2 lines

Dependency exclusion implemented with a regular expression.
........
r328 | danielevarrazzo | 2007-11-17 00:11:36 +0100 (Sat, 17 Nov 2007) | 2 lines

Other libraries added to the exclude lists.
........
r329 | giovannibajo | 2007-11-20 14:25:35 +0100 (Tue, 20 Nov 2007) | 22 lines

Introduce printf()-style error macros in bootloader for Windows.

From: Anton Gyllenberg <anton@iki.fi>

The output macros -- VS(), FATALERROR() and OTHERERROR(), had no output
formatting options. This lead to unnatural constructs like

VS("Loading dll: ");
VS(dllpath);
VS("\n");


Worse, for a Windows windowed application, the above example would
generate three dialog boxes of which the last one blank.

Therefore, make the functions behave like and have the same signature
as printf(). They should be backwards compatible as the old invocations
had just one argument which for some configurations was used as a format
string to printf.

I could not find a way to use preprocessor macros with a variable
amount of arguments on Microsoft Visual Studio 2003, so I opted to
make real functions for the message boxes on Windows.
........
r330 | giovannibajo | 2007-11-20 14:26:38 +0100 (Tue, 20 Nov 2007) | 10 lines

Convert invocations of VS(), OTHERERROR() and FATALERROR().

From: Anton Gyllenberg <anton@iki.fi>

Convert some invocations of VS(), OTHERERROR() and FATALERROR() to use
the newly introduced printf style format strings. Examples of invocations
targetted for modification are cases multiple invocations could be handled
by one invocation with format string and those that used a string buffer
filled with strncpy() or the like.
........
r331 | giovannibajo | 2007-11-20 14:27:12 +0100 (Tue, 20 Nov 2007) | 2 lines

New bootloader binaries.
........
r332 | giovannibajo | 2007-11-20 14:32:54 +0100 (Tue, 20 Nov 2007) | 8 lines

Let the windows loader try to open myprog.pkg before myprog.exe.

From: Anton Gyllenberg <anton@iki.fi>

Having the archive in an external file makes it possible to work around some
problems stemming from the process opening its own executable and keeping it
open.
........
r333 | giovannibajo | 2007-11-20 14:34:11 +0100 (Tue, 20 Nov 2007) | 9 lines

Check doIt() return value.

From: Anton Gyllenberg <anton@iki.fi>

finalizePython() may crash if doIt() fails. Add some error checking
to fail more gracefully. This will prevent the "Do you want to send
information to Microsoft" dialog e.g., in case python.dll could not
be loaded.
........
r334 | giovannibajo | 2007-11-20 14:34:32 +0100 (Tue, 20 Nov 2007) | 2 lines

New bootloader binaries.
........

Files:

Legend:

Unmodified
Added
Removed
Modified
  • branches/crypt/bindepend.py

    r282 r455  
    70 70       'GLU32.DLL':1,  
    71 71       'GLUB32.DLL':1,  
    72         '/usr/lib':1,  
    73         '/lib':1,}  
      72       'NETAPI32.DLL':1,  
      73       'PSAPI.DLL':1,  
      74       'MSVCP80.DLL':1,  
      75       'MSVCR80.DLL':1,  
      76       '^/usr/lib':1,  
      77       '^/lib':1,  
      78       '^/lib/tls':1,  
      79       '^/System/Library/Frameworks':1,  
      80       }  
      81  
      82 excludesRe = re.compile('|'.join(excludes.keys()), re.I)  
    74 83  
    75 84 def getfullnameof(mod, xtrapath = None):  
     
    80 89       Return the full path name of MOD.  
    81 90       Will search the full Windows search path, as well as sys.path"""  
    82     epath = getWindowsPath() + sys.path  
      91   # Search sys.path first!  
      92   epath = sys.path + getWindowsPath()  
    83 93   if xtrapath is not None:  
    84 94     if type(xtrapath) == type(''):  
     
    92 102   return ''  
    93 103  
    94   def getImports1(pth):  
      104 def _getImports_dumpbin(pth):  
    94 104     """Find the binary dependencies of PTH.  
    95 105  
     
    111 121     return rslt  
    112 122  
    113   def getImports2x(pth):  
      123 def _getImports_pe_x(pth):  
    113 123     """Find the binary dependencies of PTH.  
    114 124  
     
    176 186     return rslt  
    177 187  
    178   def getImports2(path):  
      188 def _getImports_pe(path):  
    178 188     """Find the binary dependencies of PTH.  
    179 189  
     
    264 274             if excludes.get(dir,0):  
    265 275                 continue  
    266           if excludes.get(string.upper(lib),0):  
      276         else:  
      277             npth = getfullnameof(lib, os.path.dirname(pth))  
      278         if excludesRe.search(npth):  
    267 279             continue  
    268 280         if seen.get(string.upper(lib),0):  
    269 281             continue  
    270           if iswin or cygwin:  
    271               npth = getfullnameof(lib, os.path.dirname(pth))  
    272 282         if npth:  
    273 283             lTOC.append((lib, npth, 'BINARY'))  
     
    276 286   return lTOC  
    277 287  
    278   def getImports3(pth):  
      288 def _getImports_ldd(pth):  
    278 288     """Find the binary dependencies of PTH.  
    279 289  
     
    297 307     return rslt  
    298 308  
      309 def _getImports_otool(pth):  
      310     """Find the binary dependencies of PTH.  
      311  
      312         This implementation is for otool platforms"""  
      313     rslt = []  
      314     for line in os.popen('otool -L "%s"' % pth).readlines():  
      315         m = re.search(r"\s+(.*?)\s+\(.*\)", line)  
      316         if m:  
      317             lib = m.group(1)  
      318             if os.path.exists(lib):  
      319                 rslt.append(lib)  
      320             else:  
      321                 print 'E: cannot find path %s (needed by %s)' % \  
      322                       (lib, pth)  
      323  
      324     return rslt  
      325  
    299 326 def getImports(pth):  
    300       """Forwards to either getImports2 or getImports3  
      327     """Forwards to the correct getImports implementation for the platform.  
    300 327     """  
    301 328     if sys.platform[:3] == 'win' or sys.platform == 'cygwin':  
    302           return getImports2(pth)  
    303       return getImports3(pth)  
      329         return _getImports_pe(pth)  
      330     elif sys.platform == 'darwin':  
      331         return _getImports_otool(pth)  
      332     else:  
      333         return _getImports_ldd(pth)  
    304 334  
    305 335 def getWindowsPath():  
  • branches/crypt/hooks/hook-xml.py

    r316 r455  
    19 19  
    20 20 def hook(mod):  
      21     # This hook checks for the infamous _xmlcore hack  
      22     # http://www.amk.ca/diary/2003/03/pythons__xmlplus_hack.html  
    21 23     import os, tempfile, sys, string, marshal  
    22 24     fnm = tempfile.mktemp()  
  • branches/crypt/hooks/hook-PyQt4.QtTest.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtGui.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtCore.py

    r316 r455  
    1   hiddenimports = ['sip']  
      1 hiddenimports = ['sip', "PyQt4._qt"]  
     
  • branches/crypt/hooks/hook-PyQt4.QtNetwork.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtSvg.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtXml.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtAssistant.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtOpenGL.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4._qt']  
     
  • branches/crypt/hooks/hook-PyQt4.QtSql.py

    r316 r455  
    1   hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui']  
      1 hiddenimports = ['sip', 'PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4._qt']  
     
  • branches/crypt/optparse.py

    r109 r455  
    1   """  
    2   optparse -- forward-compatibility wrapper for use with Python 2.2.x and  
    3   earlier.  If you import from 'optparse' rather than 'optik', your code  
    4   will work on base Python 2.3 (and later), or on earlier Pythons with  
    5   Optik 1.4.1 or later installed.  
    6   """  
    7    
    8   from optik import __version__, __all__  
    9   from optik import *  
      1 """  
      2 optparse -- forward-compatibility wrapper for use with Python 2.2.x and  
      3 earlier.  If you import from 'optparse' rather than 'optik', your code  
      4 will work on base Python 2.3 (and later), or on earlier Pythons with  
      5 Optik 1.4.1 or later installed.  
      6 """  
      7  
      8 from optik import __version__, __all__  
      9 from optik import *  
  • branches/crypt/optik/help.py

    r112 r455  
    1   """optik.help  
    2    
    3   Provides HelpFormatter and subclasses -- used by OptionParser  
    4   to generate formatted help text.  
    5   """  
    6    
    7   # Copyright (c) 2001-2004 Gregory P. Ward.  All rights reserved.  
    8   # See the README.txt distributed with Optik for licensing terms.  
    9    
    10   import os  
    11   import string  
    12   import textwrap  
    13   from optik.option import NO_DEFAULT  
    14   from optik.errors import gettext  
    15   _ = gettext  
    16    
    17   __revision__ = "$Id: help.py 470 2004-12-07 01:39:56Z gward $"  
    18    
    19   __all__ = ['HelpFormatter', 'IndentedHelpFormatter', 'TitledHelpFormatter']  
    20    
    21   class HelpFormatter:  
    22    
    23       """  
    24       Abstract base class for formatting option help.  OptionParser  
    25       instances should use one of the HelpFormatter subclasses for  
    26       formatting help; by default IndentedHelpFormatter is used.  
    27    
    28       Instance attributes:  
    29         parser : OptionParser  
    30           the controlling OptionParser instance  
    31         indent_increment : int  
    32           the number of columns to indent per nesting level  
    33         max_help_position : int  
    34           the maximum starting column for option help text  
    35         help_position : int  
    36           the calculated starting column for option help text;  
    37           initially the same as the maximum  
    38         width : int  
    39           total number of columns for output (pass None to constructor for  
    40           this value to be taken from the $COLUMNS environment variable)  
    41         level : int  
    42           current indentation level  
    43         current_indent : int  
    44           current indentation level (in columns)  
    45         help_width : int  
    46           number of columns available for option help text (calculated)  
    47         default_tag : str  
    48           text to replace with each option's default value, "%default"  
    49           by default.  Set to false value to disable default value expansion.  
    50         option_strings : { Option : str }  
    51           maps Option instances to the snippet of help text explaining  
    52           the syntax of that option, e.g. "-h, --help" or  
    53           "-fFILE, --file=FILE"  
    54         _short_opt_fmt : str  
    55           format string controlling how short options with values are  
    56           printed in help text.  Must be either "%s%s" ("-fFILE") or  
    57           "%s %s" ("-f FILE"), because those are the two syntaxes that  
    58           Optik supports.  
    59         _long_opt_fmt : str  
    60           similar but for long options; must be either "%s %s" ("--file FILE")  
    61           or "%s=%s" ("--file=FILE").  
    62       """  
    63    
    64       NO_DEFAULT_VALUE = "none"  
    65    
    66       def __init__(self,  
    67                    indent_increment,  
    68                    max_help_position,  
    69                    width,  
    70                    short_first):  
    71           self.parser = None  
    72           self.indent_increment = indent_increment  
    73           self.help_position = self.max_help_position = max_help_position  
    74           if width is None:  
    75               try:  
    76                   width = int(os.environ['COLUMNS'])  
    77               except (KeyError, ValueError):  
    78                   width = 80  
    79               width = width - 2  
    80           self.width = width  
    81           self.current_indent = 0  
    82           self.level = 0  
    83           self.help_width = None          # computed later  
    84           self.short_first = short_first  
    85           self.default_tag = "%default"  
    86           self.option_strings = {}  
    87           self._short_opt_fmt = "%s %s"  
    88           self._long_opt_fmt = "%s=%s"  
    89    
    90       def set_parser(self, parser):  
    91           self.parser = parser  
    92    
    93       def set_short_opt_delimiter(self, delim):  
    94           if delim not in ("", " "):  
    95               raise ValueError(  
    96                   "invalid metavar delimiter for short options: %r" % delim)  
    97           self._short_opt_fmt = "%s" + delim + "%s"  
    98    
    99       def set_long_opt_delimiter(self, delim):  
    100           if delim not in ("=", " "):  
    101               raise ValueError(  
    102                   "invalid metavar delimiter for long options: %r" % delim)  
    103           self._long_opt_fmt = "%s" + delim + "%s"  
    104    
    105       def indent(self):  
    106           self.current_indent = self.current_indent + self.indent_increment  
    107           self.level = self.level + 1  
    108    
    109       def dedent(self):  
    110           self.current_indent = self.current_indent - self.indent_increment  
    111           assert self.current_indent >= 0, "Indent decreased below 0."  
    112           self.level = self.level - 1  
    113    
    114       def format_usage(self, usage):  
    115           raise NotImplementedError, "subclasses must implement"  
    116    
    117       def format_heading(self, heading):  
    118           raise NotImplementedError, "subclasses must implement"  
    119    
    120       def format_description(self, description):  
    121           if not description:  
    122               return ""  
    123           desc_width = self.width - self.current_indent  
    124           indent = " "*self.current_indent  
    125           return textwrap.fill(description,  
    126                                desc_width,  
    127                                initial_indent=indent,  
    128                                subsequent_indent=indent) + "\n"  
    129    
    130       def expand_default(self, option):  
    131           if self.parser is None or not self.default_tag:  
    132               return option.help  
    133    
    134           default_value = self.parser.defaults.get(option.dest)  
    135           if default_value is NO_DEFAULT or default_value is None:  
    136               default_value = self.NO_DEFAULT_VALUE  
    137    
    138           return string.replace(option.help, self.default_tag, str(default_value))  
    139    
    140       def format_option(self, option):  
    141           # The help for each option consists of two parts:  
    142           #   * the opt strings and metavars  
    143           #     eg. ("-x", or "-fFILENAME, --file=FILENAME")  
    144           #   * the user-supplied help string  
    145           #     eg. ("turn on expert mode", "read data from FILENAME")  
    146           #  
    147           # If possible, we write both of these on the same line:  
    148           #   -x      turn on expert mode  
    149           #  
    150           # But if the opt string list is too long, we put the help  
    151           # string on a second line, indented to the same column it would  
    152           # start in if it fit on the first line.  
    153           #   -fFILENAME, --file=FILENAME  
    154           #           read data from FILENAME  
    155           result = []  
    156           opts = self.option_strings[option]  
    157           opt_width = self.help_position - self.current_indent - 2  
    158           if len(opts) > opt_width:  
    159               opts = "%*s%s\n" % (self.current_indent, "", opts)  
    160               indent_first = self.help_position  
    161           else:                       # start help on same line as opts  
    162               opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)  
    163               indent_first = 0  
    164           result.append(opts)  
    165           if option.help:  
    166               help_text = self.expand_default(option)  
    167               help_lines = textwrap.wrap(help_text, self.help_width)  
    168               result.append("%*s%s\n" % (indent_first, "", help_lines[0]))  
    169               for line in help_lines[1:]:  
    170                   result.append("%*s%s\n" % (self.help_position, "", line))  
    171           elif opts[-1] != "\n":  
    172               result.append("\n")  
    173           return string.join(result, "")  
    174    
    175       def store_option_strings(self, parser):  
    176           self.indent()  
    177           max_len = 0  
    178           for opt in parser.option_list:  
    179               strings = self.format_option_strings(opt)  
    180               self.option_strings[opt] = strings  
    181               max_len = max(max_len, len(strings) + self.current_indent)  
    182           self.indent()  
    183           for group in parser.option_groups:  
    184               for opt in group.option_list:  
    185                   strings = self.format_option_strings(opt)  
    186                   self.option_strings[opt] = strings  
    187                   max_len = max(max_len, len(strings) + self.current_indent)  
    188           self.dedent()  
    189           self.dedent()  
    190           self.help_position = min(max_len + 2, self.max_help_position)  
    191           self.help_width = self.width - self.help_position  
    192    
    193       def format_option_strings(self, option):  
    194           """Return a comma-separated list of option strings & metavariables."""  
    195           if option.takes_value():  
    196               metavar = option.metavar or string.upper(option.dest)  
    197               short_opts = []  
    198               for sopt in option._short_opts:  
    199                   short_opts.append(self._short_opt_fmt % (sopt, metavar))  
    200               long_opts = []  
    201               for lopt in option._long_opts:  
    202                   long_opts.append(self._long_opt_fmt % (lopt, metavar))  
    203           else:  
    204               short_opts = option._short_opts  
    205               long_opts = option._long_opts  
    206    
    207           if self.short_first:  
    208               opts = short_opts + long_opts  
    209           else:  
    210               opts = long_opts + short_opts  
    211    
    212           return string.join(opts, ", ")  
    213    
    214   class IndentedHelpFormatter (HelpFormatter):  
    215       """Format help with indented section bodies.  
    216       """  
    217    
    218       def __init__(self,  
    219                    indent_increment=2,  
    220                    max_help_position=24,  
    221                    width=None,  
    222                    short_first=1):  
    223           HelpFormatter.__init__(  
    224               self, indent_increment, max_help_position, width, short_first)  
    225    
    226       def format_usage(self, usage):  
    227           return _("usage: %s\n") % usage  
    228    
    229       def format_heading(self, heading):  
    230           return "%*s%s:\n" % (self.current_indent, "", heading)  
    231    
    232    
    233   class TitledHelpFormatter (HelpFormatter):  
    234       """Format help with underlined section headers.  
    235       """  
    236    
    237       def __init__(self,  
    238                    indent_increment=0,  
    239                    max_help_position=24,  
    240                    width=None,  
    241                    short_first=0):  
    242           HelpFormatter.__init__ (  
    243               self, indent_increment, max_help_position, width, short_first)  
    244    
    245       def format_usage(self, usage):  
    246           return "%s  %s\n" % (self.format_heading(_("Usage")), usage)  
    247    
    248       def format_heading(self, heading):  
    249           return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))  
      1 """optik.help  
      2  
      3 Provides HelpFormatter and subclasses -- used by OptionParser  
      4 to generate formatted help text.  
      5 """  
      6  
      7 # Copyright (c) 2001-2004 Gregory P. Ward.  All rights reserved.  
      8 # See the README.txt distributed with Optik for licensing terms.  
      9  
      10 import os  
      11 import string  
      12 import textwrap  
      13 from optik.option import NO_DEFAULT  
      14 from optik.errors import gettext  
      15 _ = gettext  
      16  
      17 __revision__ = "$Id: help.py 470 2004-12-07 01:39:56Z gward $"  
      18  
      19 __all__ = ['HelpFormatter', 'IndentedHelpFormatter', 'TitledHelpFormatter']  
      20  
      21 class HelpFormatter:  
      22  
      23     """  
      24     Abstract base class for formatting option help.  OptionParser  
      25     instances should use one of the HelpFormatter subclasses for  
      26     formatting help; by default IndentedHelpFormatter is used.  
      27  
      28     Instance attributes:  
      29       parser : OptionParser  
      30         the controlling OptionParser instance  
      31       indent_increment : int  
      32         the number of columns to indent per nesting level  
      33       max_help_position : int  
      34         the maximum starting column for option help text  
      35       help_position : int  
      36         the calculated starting column for option help text;  
      37         initially the same as the maximum  
      38       width : int  
      39         total number of columns for output (pass None to constructor for  
      40         this value to be taken from the $COLUMNS environment variable)  
      41       level : int  
      42         current indentation level  
      43       current_indent : int  
      44         current indentation level (in columns)  
      45       help_width : int  
      46         number of columns available for option help text (calculated)  
      47       default_tag : str  
      48         text to replace with each option's default value, "%default"  
      49         by default.  Set to false value to disable default value expansion.  
      50       option_strings : { Option : str }  
      51         maps Option instances to the snippet of help text explaining  
      52         the syntax of that option, e.g. "-h, --help" or  
      53         "-fFILE, --file=FILE"  
      54       _short_opt_fmt : str  
      55         format string controlling how short options with values are  
      56         printed in help text.  Must be either "%s%s" ("-fFILE") or  
      57         "%s %s" ("-f FILE"), because those are the two syntaxes that  
      58         Optik supports.  
      59       _long_opt_fmt : str  
      60         similar but for long options; must be either "%s %s" ("--file FILE")  
      61         or "%s=%s" ("--file=FILE").  
      62     """  
      63  
      64     NO_DEFAULT_VALUE = "none"  
      65  
      66     def __init__(self,  
      67                  indent_increment,  
      68                  max_help_position,  
      69                  width,  
      70                  short_first):  
      71         self.parser = None  
      72         self.indent_increment = indent_increment  
      73         self.help_position = self.max_help_position = max_help_position  
      74         if width is None:  
      75             try:  
      76                 width = int(os.environ['COLUMNS'])  
      77             except (KeyError, ValueError):  
      78                 width = 80  
      79             width = width - 2  
      80         self.width = width  
      81         self.current_indent = 0  
      82         self.level = 0  
      83         self.help_width = None          # computed later  
      84         self.short_first = short_first  
      85         self.default_tag = "%default"  
      86         self.option_strings = {}  
      87         self._short_opt_fmt = "%s %s"  
      88         self._long_opt_fmt = "%s=%s"  
      89  
      90     def set_parser(self, parser):  
      91         self.parser = parser  
      92  
      93     def set_short_opt_delimiter(self, delim):  
      94         if delim not in ("", " "):  
      95             raise ValueError(  
      96                 "invalid metavar delimiter for short options: %r" % delim)  
      97         self._short_opt_fmt = "%s" + delim + "%s"  
      98  
      99     def set_long_opt_delimiter(self, delim):  
      100         if delim not in ("=", " "):  
      101             raise ValueError(  
      102                 "invalid metavar delimiter for long options: %r" % delim)  
      103         self._long_opt_fmt = "%s" + delim + "%s"  
      104  
      105     def indent(self):  
      106         self.current_indent = self.current_indent + self.indent_increment  
      107         self.level = self.level + 1  
      108  
      109     def dedent(self):  
      110         self.current_indent = self.current_indent - self.indent_increment  
      111         assert self.current_indent >= 0, "Indent decreased below 0."  
      112         self.level = self.level - 1  
      113  
      114     def format_usage(self, usage):  
      115         raise NotImplementedError, "subclasses must implement"  
      116  
      117     def format_heading(self, heading):  
      118         raise NotImplementedError, "subclasses must implement"  
      119  
      120     def format_description(self, description):  
      121         if not description:  
      122             return ""  
      123         desc_width = self.width - self.current_indent  
      124         indent = " "*self.current_indent  
      125         return textwrap.fill(description,  
      126                              desc_width,  
      127                              initial_indent=indent,  
      128                              subsequent_indent=indent) + "\n"  
      129  
      130     def expand_default(self, option):  
      131         if self.parser is None or not self.default_tag:  
      132             return option.help  
      133  
      134         default_value = self.parser.defaults.get(option.dest)  
      135         if default_value is NO_DEFAULT or default_value is None:  
      136             default_value = self.NO_DEFAULT_VALUE  
      137  
      138         return string.replace(option.help, self.default_tag, str(default_value))  
      139  
      140     def format_option(self, option):  
      141         # The help for each option consists of two parts:  
      142         #   * the opt strings and metavars  
      143         #     eg. ("-x", or "-fFILENAME, --file=FILENAME")  
      144         #   * the user-supplied help string  
      145         #     eg. ("turn on expert mode", "read data from FILENAME")  
      146         #  
      147         # If possible, we write both of these on the same line:  
      148         #   -x      turn on expert mode  
      149         #  
      150         # But if the opt string list is too long, we put the help  
      151         # string on a second line, indented to the same column it would  
      152         # start in if it fit on the first line.  
      153         #   -fFILENAME, --file=FILENAME  
      154         #           read data from FILENAME  
      155         result = []  
      156         opts = self.option_strings[option]  
      157         opt_width = self.help_position - self.current_indent - 2  
      158         if len(opts) > opt_width:  
      159             opts = "%*s%s\n" % (self.current_indent, "", opts)  
      160             indent_first = self.help_position  
      161         else:                       # start help on same line as opts  
      162             opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)  
      163             indent_first = 0  
      164 &n