Blame SOURCES/0002-cleanup-ANCIENT_PYTHON-stuff-and-unused-imports.patch

1330ca
From 3b70442331338696847abc23b8e0d8d4f9618bba Mon Sep 17 00:00:00 2001
1330ca
From: Tomas Kasparek <tkasparek@redhat.com>
1330ca
Date: Mon, 5 Mar 2018 11:06:22 +0100
1330ca
Subject: [PATCH 02/17] cleanup ANCIENT_PYTHON stuff and unused imports
1330ca
1330ca
---
1330ca
 koan/app.py         |   98 +--
1330ca
 koan/opt_parse.py   | 1682 ---------------------------------------------------
1330ca
 koan/register.py    |   13 +-
1330ca
 koan/sub_process.py | 1149 -----------------------------------
1330ca
 koan/text_wrap.py   |  354 -----------
1330ca
 koan/utils.py       |   50 +-
1330ca
 koan/vmwcreate.py   |    6 +-
1330ca
 7 files changed, 39 insertions(+), 3313 deletions(-)
1330ca
 delete mode 100644 koan/opt_parse.py
1330ca
 delete mode 100644 koan/sub_process.py
1330ca
 delete mode 100644 koan/text_wrap.py
1330ca
1330ca
diff --git a/koan/app.py b/koan/app.py
1330ca
index d911dad..801fedd 100755
1330ca
--- a/koan/app.py
1330ca
+++ b/koan/app.py
1330ca
@@ -27,40 +27,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1330ca
 import random
1330ca
 import os
1330ca
 import traceback
1330ca
-import tempfile
1330ca
 import shlex
1330ca
 
1330ca
-ANCIENT_PYTHON = 0
1330ca
-try:
1330ca
-    try:
1330ca
-        from optparse import OptionParser
1330ca
-    except:
1330ca
-        from opt_parse import OptionParser # importing this for backwards compat with 2.2
1330ca
-    try:
1330ca
-        import subprocess as sub_process
1330ca
-    except:
1330ca
-        import sub_process
1330ca
-except:
1330ca
-    # the main "replace-self" codepath of koan must support
1330ca
-    # Python 1.5.  Other sections may use 2.3 features (nothing newer)
1330ca
-    # provided they are conditionally imported.  This is to support
1330ca
-    # EL 2.1. -- mpd
1330ca
-    ANCIENT_PYTHON = 1
1330ca
-    True = 1
1330ca
-    False = 0
1330ca
+from optparse import OptionParser
1330ca
+import subprocess as sub_process
1330ca
 
1330ca
 import time
1330ca
 import shutil
1330ca
 import errno
1330ca
-import re
1330ca
 import sys
1330ca
 import xmlrpclib
1330ca
 import string
1330ca
 import re
1330ca
-import glob
1330ca
-import socket
1330ca
 import utils
1330ca
-import time
1330ca
 
1330ca
 COBBLER_REQUIRED = 1.300
1330ca
 
1330ca
@@ -94,11 +73,6 @@ def main():
1330ca
         # most likely running RHEL3, where we don't need virt logging anyway
1330ca
         pass
1330ca
 
1330ca
-    if ANCIENT_PYTHON:
1330ca
-        print "- command line usage on this version of python is unsupported"
1330ca
-        print "- usage via spacewalk APIs only.  Python x>=2.3 required"
1330ca
-        return
1330ca
-
1330ca
     p = OptionParser()
1330ca
     p.add_option("-k", "--kopts",
1330ca
                  dest="kopts_override",
1330ca
@@ -538,16 +512,15 @@ class Koan:
1330ca
                 else:
1330ca
                     # FIXME: auto never selects vmware, maybe it should if we find it?
1330ca
 
1330ca
-                    if not ANCIENT_PYTHON:
1330ca
-                        cmd = sub_process.Popen("/bin/uname -r", stdout=sub_process.PIPE, shell=True)
1330ca
-                        uname_str = cmd.communicate()[0]
1330ca
-                        if uname_str.find("xen") != -1:
1330ca
-                            self.virt_type = "xenpv"
1330ca
-                        elif os.path.exists("/usr/bin/qemu-img"):
1330ca
-                            self.virt_type = "qemu"
1330ca
-                        else:
1330ca
-                            # assume Xen, we'll check to see if virt-type is really usable later.
1330ca
-                            raise InfoException, "Not running a Xen kernel and qemu is not installed"
1330ca
+                    cmd = sub_process.Popen("/bin/uname -r", stdout=sub_process.PIPE, shell=True)
1330ca
+                    uname_str = cmd.communicate()[0]
1330ca
+                    if uname_str.find("xen") != -1:
1330ca
+                        self.virt_type = "xenpv"
1330ca
+                    elif os.path.exists("/usr/bin/qemu-img"):
1330ca
+                        self.virt_type = "qemu"
1330ca
+                    else:
1330ca
+                        # assume Xen, we'll check to see if virt-type is really usable later.
1330ca
+                        raise InfoException, "Not running a Xen kernel and qemu is not installed"
1330ca
 
1330ca
                 print "- no virt-type specified, auto-selecting %s" % self.virt_type
1330ca
 
1330ca
@@ -811,12 +784,6 @@ class Koan:
1330ca
     #---------------------------------------------------
1330ca
         
1330ca
     def get_boot_loader_info(self):
1330ca
-        if ANCIENT_PYTHON:
1330ca
-            # FIXME: implement this to work w/o subprocess
1330ca
-            if os.path.exists("/etc/grub.conf"):
1330ca
-               return (0, "grub")
1330ca
-            else:
1330ca
-               return (0, "lilo") 
1330ca
         cmd = [ "/sbin/grubby", "--bootloader-probe" ]
1330ca
         probe_process = sub_process.Popen(cmd, stdout=sub_process.PIPE)
1330ca
         which_loader = probe_process.communicate()[0]
1330ca
@@ -862,11 +829,8 @@ class Koan:
1330ca
                         profile_data
1330ca
                     )
1330ca
 
1330ca
-            if not ANCIENT_PYTHON:
1330ca
-                arch_cmd = sub_process.Popen("/bin/uname -m", stdout=sub_process.PIPE, shell=True)
1330ca
-                arch = arch_cmd.communicate()[0]
1330ca
-            else:
1330ca
-                arch = "i386"
1330ca
+            arch_cmd = sub_process.Popen("/bin/uname -m", stdout=sub_process.PIPE, shell=True)
1330ca
+            arch = arch_cmd.communicate()[0]
1330ca
 
1330ca
             # Validate kernel argument length (limit depends on architecture --
1330ca
             # see asm-*/setup.h).  For example:
1330ca
@@ -875,15 +839,14 @@ class Koan:
1330ca
             #   asm-powerpc/setup.h:#define COMMAND_LINE_SIZE   512
1330ca
             #   asm-s390/setup.h:#define COMMAND_LINE_SIZE  896
1330ca
             #   asm-x86_64/setup.h:#define COMMAND_LINE_SIZE    2048
1330ca
-            if not ANCIENT_PYTHON:
1330ca
-                if arch.startswith("ppc") or arch.startswith("ia64"):
1330ca
-                    if len(k_args) > 511:
1330ca
-                        raise InfoException, "Kernel options are too long, 512 chars exceeded: %s" % k_args
1330ca
-                elif arch.startswith("s390"):
1330ca
-                    if len(k_args) > 895:
1330ca
-                        raise InfoException, "Kernel options are too long, 896 chars exceeded: %s" % k_args
1330ca
-                elif len(k_args) > 2047:
1330ca
-                    raise InfoException, "Kernel options are too long, 2047 chars exceeded: %s" % k_args
1330ca
+            if arch.startswith("ppc") or arch.startswith("ia64"):
1330ca
+                if len(k_args) > 511:
1330ca
+                    raise InfoException, "Kernel options are too long, 512 chars exceeded: %s" % k_args
1330ca
+            elif arch.startswith("s390"):
1330ca
+                if len(k_args) > 895:
1330ca
+                    raise InfoException, "Kernel options are too long, 896 chars exceeded: %s" % k_args
1330ca
+            elif len(k_args) > 2047:
1330ca
+                raise InfoException, "Kernel options are too long, 2047 chars exceeded: %s" % k_args
1330ca
 
1330ca
             cmd = [ "/sbin/grubby",
1330ca
                     "--add-kernel", self.safe_load(profile_data,'kernel_local'),
1330ca
@@ -910,14 +873,13 @@ class Koan:
1330ca
                cmd.append("--config-file=/tmp/boot/boot/grub/grub.conf")
1330ca
 
1330ca
             # Are we running on ppc?
1330ca
-            if not ANCIENT_PYTHON:
1330ca
-               if arch.startswith("ppc"):
1330ca
-                   if "grub2" in probe_output:
1330ca
-                       cmd.append("--grub2")
1330ca
-                   else:
1330ca
-                       cmd.append("--yaboot")
1330ca
-               elif arch.startswith("s390"):
1330ca
-                   cmd.append("--zipl")
1330ca
+            if arch.startswith("ppc"):
1330ca
+                if "grub2" in probe_output:
1330ca
+                    cmd.append("--grub2")
1330ca
+                else:
1330ca
+                    cmd.append("--yaboot")
1330ca
+            elif arch.startswith("s390"):
1330ca
+                cmd.append("--zipl")
1330ca
 
1330ca
             utils.subprocess_call(cmd)
1330ca
 
1330ca
@@ -933,12 +895,12 @@ class Koan:
1330ca
             utils.subprocess_call(cmd)
1330ca
 
1330ca
             # Any post-grubby processing required (e.g. ybin, zipl, lilo)?
1330ca
-            if not ANCIENT_PYTHON and arch.startswith("ppc") and "grub2" not in probe_output:
1330ca
+            if arch.startswith("ppc") and "grub2" not in probe_output:
1330ca
                 # FIXME - CHRP hardware uses a 'PPC PReP Boot' partition and doesn't require running ybin
1330ca
                 print "- applying ybin changes"
1330ca
                 cmd = [ "/sbin/ybin" ]
1330ca
                 utils.subprocess_call(cmd)
1330ca
-            elif not ANCIENT_PYTHON and arch.startswith("s390"):
1330ca
+            elif arch.startswith("s390"):
1330ca
                 print "- applying zipl changes"
1330ca
                 cmd = [ "/sbin/zipl" ]
1330ca
                 utils.subprocess_call(cmd)
1330ca
diff --git a/koan/opt_parse.py b/koan/opt_parse.py
1330ca
deleted file mode 100644
1330ca
index 233d192..0000000
1330ca
--- a/koan/opt_parse.py
1330ca
+++ /dev/null
1330ca
@@ -1,1682 +0,0 @@
1330ca
-"""optparse - a powerful, extensible, and easy-to-use option parser.
1330ca
-
1330ca
-By Greg Ward <gward@python.net>
1330ca
-
1330ca
-Originally distributed as Optik; see http://optik.sourceforge.net/ .
1330ca
-
1330ca
-If you have problems with this module, please do not file bugs,
1330ca
-patches, or feature requests with Python; instead, use Optik's
1330ca
-SourceForge project page:
1330ca
-  http://sourceforge.net/projects/optik
1330ca
-
1330ca
-For support, use the optik-users@lists.sourceforge.net mailing list
1330ca
-(http://lists.sourceforge.net/lists/listinfo/optik-users).
1330ca
-"""
1330ca
-
1330ca
-# Python developers: please do not make changes to this file, since
1330ca
-# it is automatically generated from the Optik source code.
1330ca
-
1330ca
-__version__ = "1.5.3"
1330ca
-
1330ca
-__all__ = ['Option',
1330ca
-           'SUPPRESS_HELP',
1330ca
-           'SUPPRESS_USAGE',
1330ca
-           'Values',
1330ca
-           'OptionContainer',
1330ca
-           'OptionGroup',
1330ca
-           'OptionParser',
1330ca
-           'HelpFormatter',
1330ca
-           'IndentedHelpFormatter',
1330ca
-           'TitledHelpFormatter',
1330ca
-           'OptParseError',
1330ca
-           'OptionError',
1330ca
-           'OptionConflictError',
1330ca
-           'OptionValueError',
1330ca
-           'BadOptionError']
1330ca
-
1330ca
-__copyright__ = """
1330ca
-Copyright (c) 2001-2006 Gregory P. Ward.  All rights reserved.
1330ca
-Copyright (c) 2002-2006 Python Software Foundation.  All rights reserved.
1330ca
-
1330ca
-Redistribution and use in source and binary forms, with or without
1330ca
-modification, are permitted provided that the following conditions are
1330ca
-met:
1330ca
-
1330ca
-  * Redistributions of source code must retain the above copyright
1330ca
-    notice, this list of conditions and the following disclaimer.
1330ca
-
1330ca
-  * Redistributions in binary form must reproduce the above copyright
1330ca
-    notice, this list of conditions and the following disclaimer in the
1330ca
-    documentation and/or other materials provided with the distribution.
1330ca
-
1330ca
-  * Neither the name of the author nor the names of its
1330ca
-    contributors may be used to endorse or promote products derived from
1330ca
-    this software without specific prior written permission.
1330ca
-
1330ca
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
1330ca
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1330ca
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
1330ca
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
1330ca
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1330ca
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1330ca
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1330ca
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1330ca
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1330ca
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1330ca
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1330ca
-"""
1330ca
-
1330ca
-import sys, os
1330ca
-import types
1330ca
-import text_wrap as textwrap # repackaged here because not in RHEL3
1330ca
-
1330ca
-def _repr(self):
1330ca
-    return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
1330ca
-
1330ca
-
1330ca
-# This file was generated from:
1330ca
-#   Id: option_parser.py 527 2006-07-23 15:21:30Z greg
1330ca
-#   Id: option.py 522 2006-06-11 16:22:03Z gward
1330ca
-#   Id: help.py 527 2006-07-23 15:21:30Z greg
1330ca
-#   Id: errors.py 509 2006-04-20 00:58:24Z gward
1330ca
-
1330ca
-try:
1330ca
-    from gettext import gettext
1330ca
-except ImportError:
1330ca
-    def gettext(message):
1330ca
-        return message
1330ca
-_ = gettext
1330ca
-
1330ca
-
1330ca
-class OptParseError (Exception):
1330ca
-    def __init__(self, msg):
1330ca
-        self.msg = msg
1330ca
-
1330ca
-    def __str__(self):
1330ca
-        return self.msg
1330ca
-
1330ca
-
1330ca
-class OptionError (OptParseError):
1330ca
-    """
1330ca
-    Raised if an Option instance is created with invalid or
1330ca
-    inconsistent arguments.
1330ca
-    """
1330ca
-
1330ca
-    def __init__(self, msg, option):
1330ca
-        self.msg = msg
1330ca
-        self.option_id = str(option)
1330ca
-
1330ca
-    def __str__(self):
1330ca
-        if self.option_id:
1330ca
-            return "option %s: %s" % (self.option_id, self.msg)
1330ca
-        else:
1330ca
-            return self.msg
1330ca
-
1330ca
-class OptionConflictError (OptionError):
1330ca
-    """
1330ca
-    Raised if conflicting options are added to an OptionParser.
1330ca
-    """
1330ca
-
1330ca
-class OptionValueError (OptParseError):
1330ca
-    """
1330ca
-    Raised if an invalid option value is encountered on the command
1330ca
-    line.
1330ca
-    """
1330ca
-
1330ca
-class BadOptionError (OptParseError):
1330ca
-    """
1330ca
-    Raised if an invalid option is seen on the command line.
1330ca
-    """
1330ca
-    def __init__(self, opt_str):
1330ca
-        self.opt_str = opt_str
1330ca
-
1330ca
-    def __str__(self):
1330ca
-        return _("no such option: %s") % self.opt_str
1330ca
-
1330ca
-class AmbiguousOptionError (BadOptionError):
1330ca
-    """
1330ca
-    Raised if an ambiguous option is seen on the command line.
1330ca
-    """
1330ca
-    def __init__(self, opt_str, possibilities):
1330ca
-        BadOptionError.__init__(self, opt_str)
1330ca
-        self.possibilities = possibilities
1330ca
-
1330ca
-    def __str__(self):
1330ca
-        return (_("ambiguous option: %s (%s?)")
1330ca
-                % (self.opt_str, ", ".join(self.possibilities)))
1330ca
-
1330ca
-
1330ca
-class HelpFormatter:
1330ca
-
1330ca
-    """
1330ca
-    Abstract base class for formatting option help.  OptionParser
1330ca
-    instances should use one of the HelpFormatter subclasses for
1330ca
-    formatting help; by default IndentedHelpFormatter is used.
1330ca
-
1330ca
-    Instance attributes:
1330ca
-      parser : OptionParser
1330ca
-        the controlling OptionParser instance
1330ca
-      indent_increment : int
1330ca
-        the number of columns to indent per nesting level
1330ca
-      max_help_position : int
1330ca
-        the maximum starting column for option help text
1330ca
-      help_position : int
1330ca
-        the calculated starting column for option help text;
1330ca
-        initially the same as the maximum
1330ca
-      width : int
1330ca
-        total number of columns for output (pass None to constructor for
1330ca
-        this value to be taken from the $COLUMNS environment variable)
1330ca
-      level : int
1330ca
-        current indentation level
1330ca
-      current_indent : int
1330ca
-        current indentation level (in columns)
1330ca
-      help_width : int
1330ca
-        number of columns available for option help text (calculated)
1330ca
-      default_tag : str
1330ca
-        text to replace with each option's default value, "%default"
1330ca
-        by default.  Set to false value to disable default value expansion.
1330ca
-      option_strings : { Option : str }
1330ca
-        maps Option instances to the snippet of help text explaining
1330ca
-        the syntax of that option, e.g. "-h, --help" or
1330ca
-        "-fFILE, --file=FILE"
1330ca
-      _short_opt_fmt : str
1330ca
-        format string controlling how short options with values are
1330ca
-        printed in help text.  Must be either "%s%s" ("-fFILE") or
1330ca
-        "%s %s" ("-f FILE"), because those are the two syntaxes that
1330ca
-        Optik supports.
1330ca
-      _long_opt_fmt : str
1330ca
-        similar but for long options; must be either "%s %s" ("--file FILE")
1330ca
-        or "%s=%s" ("--file=FILE").
1330ca
-    """
1330ca
-
1330ca
-    NO_DEFAULT_VALUE = "none"
1330ca
-
1330ca
-    def __init__(self,
1330ca
-                 indent_increment,
1330ca
-                 max_help_position,
1330ca
-                 width,
1330ca
-                 short_first):
1330ca
-        self.parser = None
1330ca
-        self.indent_increment = indent_increment
1330ca
-        self.help_position = self.max_help_position = max_help_position
1330ca
-        if width is None:
1330ca
-            try:
1330ca
-                width = int(os.environ['COLUMNS'])
1330ca
-            except (KeyError, ValueError):
1330ca
-                width = 80
1330ca
-            width -= 2
1330ca
-        self.width = width
1330ca
-        self.current_indent = 0
1330ca
-        self.level = 0
1330ca
-        self.help_width = None          # computed later
1330ca
-        self.short_first = short_first
1330ca
-        self.default_tag = "%default"
1330ca
-        self.option_strings = {}
1330ca
-        self._short_opt_fmt = "%s %s"
1330ca
-        self._long_opt_fmt = "%s=%s"
1330ca
-
1330ca
-    def set_parser(self, parser):
1330ca
-        self.parser = parser
1330ca
-
1330ca
-    def set_short_opt_delimiter(self, delim):
1330ca
-        if delim not in ("", " "):
1330ca
-            raise ValueError(
1330ca
-                "invalid metavar delimiter for short options: %r" % delim)
1330ca
-        self._short_opt_fmt = "%s" + delim + "%s"
1330ca
-
1330ca
-    def set_long_opt_delimiter(self, delim):
1330ca
-        if delim not in ("=", " "):
1330ca
-            raise ValueError(
1330ca
-                "invalid metavar delimiter for long options: %r" % delim)
1330ca
-        self._long_opt_fmt = "%s" + delim + "%s"
1330ca
-
1330ca
-    def indent(self):
1330ca
-        self.current_indent += self.indent_increment
1330ca
-        self.level += 1
1330ca
-
1330ca
-    def dedent(self):
1330ca
-        self.current_indent -= self.indent_increment
1330ca
-        assert self.current_indent >= 0, "Indent decreased below 0."
1330ca
-        self.level -= 1
1330ca
-
1330ca
-    def format_usage(self, usage):
1330ca
-        raise NotImplementedError, "subclasses must implement"
1330ca
-
1330ca
-    def format_heading(self, heading):
1330ca
-        raise NotImplementedError, "subclasses must implement"
1330ca
-
1330ca
-    def _format_text(self, text):
1330ca
-        """
1330ca
-        Format a paragraph of free-form text for inclusion in the
1330ca
-        help output at the current indentation level.
1330ca
-        """
1330ca
-        text_width = self.width - self.current_indent
1330ca
-        indent = " "*self.current_indent
1330ca
-        return textwrap.fill(text,
1330ca
-                             text_width,
1330ca
-                             initial_indent=indent,
1330ca
-                             subsequent_indent=indent)
1330ca
-
1330ca
-    def format_description(self, description):
1330ca
-        if description:
1330ca
-            return self._format_text(description) + "\n"
1330ca
-        else:
1330ca
-            return ""
1330ca
-
1330ca
-    def format_epilog(self, epilog):
1330ca
-        if epilog:
1330ca
-            return "\n" + self._format_text(epilog) + "\n"
1330ca
-        else:
1330ca
-            return ""
1330ca
-
1330ca
-
1330ca
-    def expand_default(self, option):
1330ca
-        if self.parser is None or not self.default_tag:
1330ca
-            return option.help
1330ca
-
1330ca
-        default_value = self.parser.defaults.get(option.dest)
1330ca
-        if default_value is NO_DEFAULT or default_value is None:
1330ca
-            default_value = self.NO_DEFAULT_VALUE
1330ca
-
1330ca
-        return option.help.replace(self.default_tag, str(default_value))
1330ca
-
1330ca
-    def format_option(self, option):
1330ca
-        # The help for each option consists of two parts:
1330ca
-        #   * the opt strings and metavars
1330ca
-        #     eg. ("-x", or "-fFILENAME, --file=FILENAME")
1330ca
-        #   * the user-supplied help string
1330ca
-        #     eg. ("turn on expert mode", "read data from FILENAME")
1330ca
-        #
1330ca
-        # If possible, we write both of these on the same line:
1330ca
-        #   -x      turn on expert mode
1330ca
-        #
1330ca
-        # But if the opt string list is too long, we put the help
1330ca
-        # string on a second line, indented to the same column it would
1330ca
-        # start in if it fit on the first line.
1330ca
-        #   -fFILENAME, --file=FILENAME
1330ca
-        #           read data from FILENAME
1330ca
-        result = []
1330ca
-        opts = self.option_strings[option]
1330ca
-        opt_width = self.help_position - self.current_indent - 2
1330ca
-        if len(opts) > opt_width:
1330ca
-            opts = "%*s%s\n" % (self.current_indent, "", opts)
1330ca
-            indent_first = self.help_position
1330ca
-        else:                       # start help on same line as opts
1330ca
-            opts = "%*s%-*s  " % (self.current_indent, "", opt_width, opts)
1330ca
-            indent_first = 0
1330ca
-        result.append(opts)
1330ca
-        if option.help:
1330ca
-            help_text = self.expand_default(option)
1330ca
-            help_lines = textwrap.wrap(help_text, self.help_width)
1330ca
-            result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
1330ca
-            result.extend(["%*s%s\n" % (self.help_position, "", line)
1330ca
-                           for line in help_lines[1:]])
1330ca
-        elif opts[-1] != "\n":
1330ca
-            result.append("\n")
1330ca
-        return "".join(result)
1330ca
-
1330ca
-    def store_option_strings(self, parser):
1330ca
-        self.indent()
1330ca
-        max_len = 0
1330ca
-        for opt in parser.option_list:
1330ca
-            strings = self.format_option_strings(opt)
1330ca
-            self.option_strings[opt] = strings
1330ca
-            max_len = max(max_len, len(strings) + self.current_indent)
1330ca
-        self.indent()
1330ca
-        for group in parser.option_groups:
1330ca
-            for opt in group.option_list:
1330ca
-                strings = self.format_option_strings(opt)
1330ca
-                self.option_strings[opt] = strings
1330ca
-                max_len = max(max_len, len(strings) + self.current_indent)
1330ca
-        self.dedent()
1330ca
-        self.dedent()
1330ca
-        self.help_position = min(max_len + 2, self.max_help_position)
1330ca
-        self.help_width = self.width - self.help_position
1330ca
-
1330ca
-    def format_option_strings(self, option):
1330ca
-        """Return a comma-separated list of option strings & metavariables."""
1330ca
-        if option.takes_value():
1330ca
-            metavar = option.metavar or option.dest.upper()
1330ca
-            short_opts = [self._short_opt_fmt % (sopt, metavar)
1330ca
-                          for sopt in option._short_opts]
1330ca
-            long_opts = [self._long_opt_fmt % (lopt, metavar)
1330ca
-                         for lopt in option._long_opts]
1330ca
-        else:
1330ca
-            short_opts = option._short_opts
1330ca
-            long_opts = option._long_opts
1330ca
-
1330ca
-        if self.short_first:
1330ca
-            opts = short_opts + long_opts
1330ca
-        else:
1330ca
-            opts = long_opts + short_opts
1330ca
-
1330ca
-        return ", ".join(opts)
1330ca
-
1330ca
-class IndentedHelpFormatter (HelpFormatter):
1330ca
-    """Format help with indented section bodies.
1330ca
-    """
1330ca
-
1330ca
-    def __init__(self,
1330ca
-                 indent_increment=2,
1330ca
-                 max_help_position=24,
1330ca
-                 width=None,
1330ca
-                 short_first=1):
1330ca
-        HelpFormatter.__init__(
1330ca
-            self, indent_increment, max_help_position, width, short_first)
1330ca
-
1330ca
-    def format_usage(self, usage):
1330ca
-        return _("Usage: %s\n") % usage
1330ca
-
1330ca
-    def format_heading(self, heading):
1330ca
-        return "%*s%s:\n" % (self.current_indent, "", heading)
1330ca
-
1330ca
-
1330ca
-class TitledHelpFormatter (HelpFormatter):
1330ca
-    """Format help with underlined section headers.
1330ca
-    """
1330ca
-
1330ca
-    def __init__(self,
1330ca
-                 indent_increment=0,
1330ca
-                 max_help_position=24,
1330ca
-                 width=None,
1330ca
-                 short_first=0):
1330ca
-        HelpFormatter.__init__ (
1330ca
-            self, indent_increment, max_help_position, width, short_first)
1330ca
-
1330ca
-    def format_usage(self, usage):
1330ca
-        return "%s  %s\n" % (self.format_heading(_("Usage")), usage)
1330ca
-
1330ca
-    def format_heading(self, heading):
1330ca
-        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
1330ca
-
1330ca
-
1330ca
-def _parse_num(val, type):
1330ca
-    if val[:2].lower() == "0x":         # hexadecimal
1330ca
-        radix = 16
1330ca
-    elif val[:2].lower() == "0b":       # binary
1330ca
-        radix = 2
1330ca
-        val = val[2:] or "0"            # have to remove "0b" prefix
1330ca
-    elif val[:1] == "0":                # octal
1330ca
-        radix = 8
1330ca
-    else:                               # decimal
1330ca
-        radix = 10
1330ca
-
1330ca
-    return type(val, radix)
1330ca
-
1330ca
-def _parse_int(val):
1330ca
-    return _parse_num(val, int)
1330ca
-
1330ca
-def _parse_long(val):
1330ca
-    return _parse_num(val, long)
1330ca
-
1330ca
-_builtin_cvt = { "int" : (_parse_int, _("integer")),
1330ca
-                 "long" : (_parse_long, _("long integer")),
1330ca
-                 "float" : (float, _("floating-point")),
1330ca
-                 "complex" : (complex, _("complex")) }
1330ca
-
1330ca
-def check_builtin(option, opt, value):
1330ca
-    (cvt, what) = _builtin_cvt[option.type]
1330ca
-    try:
1330ca
-        return cvt(value)
1330ca
-    except ValueError:
1330ca
-        raise OptionValueError(
1330ca
-            _("option %s: invalid %s value: %r") % (opt, what, value))
1330ca
-
1330ca
-def check_choice(option, opt, value):
1330ca
-    if value in option.choices:
1330ca
-        return value
1330ca
-    else:
1330ca
-        choices = ", ".join(map(repr, option.choices))
1330ca
-        raise OptionValueError(
1330ca
-            _("option %s: invalid choice: %r (choose from %s)")
1330ca
-            % (opt, value, choices))
1330ca
-
1330ca
-# Not supplying a default is different from a default of None,
1330ca
-# so we need an explicit "not supplied" value.
1330ca
-NO_DEFAULT = ("NO", "DEFAULT")
1330ca
-
1330ca
-
1330ca
-class Option:
1330ca
-    """
1330ca
-    Instance attributes:
1330ca
-      _short_opts : [string]
1330ca
-      _long_opts : [string]
1330ca
-
1330ca
-      action : string
1330ca
-      type : string
1330ca
-      dest : string
1330ca
-      default : any
1330ca
-      nargs : int
1330ca
-      const : any
1330ca
-      choices : [string]
1330ca
-      callback : function
1330ca
-      callback_args : (any*)
1330ca
-      callback_kwargs : { string : any }
1330ca
-      help : string
1330ca
-      metavar : string
1330ca
-    """
1330ca
-
1330ca
-    # The list of instance attributes that may be set through
1330ca
-    # keyword args to the constructor.
1330ca
-    ATTRS = ['action',
1330ca
-             'type',
1330ca
-             'dest',
1330ca
-             'default',
1330ca
-             'nargs',
1330ca
-             'const',
1330ca
-             'choices',
1330ca
-             'callback',
1330ca
-             'callback_args',
1330ca
-             'callback_kwargs',
1330ca
-             'help',
1330ca
-             'metavar']
1330ca
-
1330ca
-    # The set of actions allowed by option parsers.  Explicitly listed
1330ca
-    # here so the constructor can validate its arguments.
1330ca
-    ACTIONS = ("store",
1330ca
-               "store_const",
1330ca
-               "store_true",
1330ca
-               "store_false",
1330ca
-               "append",
1330ca
-               "append_const",
1330ca
-               "count",
1330ca
-               "callback",
1330ca
-               "help",
1330ca
-               "version")
1330ca
-
1330ca
-    # The set of actions that involve storing a value somewhere;
1330ca
-    # also listed just for constructor argument validation.  (If
1330ca
-    # the action is one of these, there must be a destination.)
1330ca
-    STORE_ACTIONS = ("store",
1330ca
-                     "store_const",
1330ca
-                     "store_true",
1330ca
-                     "store_false",
1330ca
-                     "append",
1330ca
-                     "append_const",
1330ca
-                     "count")
1330ca
-
1330ca
-    # The set of actions for which it makes sense to supply a value
1330ca
-    # type, ie. which may consume an argument from the command line.
1330ca
-    TYPED_ACTIONS = ("store",
1330ca
-                     "append",
1330ca
-                     "callback")
1330ca
-
1330ca
-    # The set of actions which *require* a value type, ie. that
1330ca
-    # always consume an argument from the command line.
1330ca
-    ALWAYS_TYPED_ACTIONS = ("store",
1330ca
-                            "append")
1330ca
-
1330ca
-    # The set of actions which take a 'const' attribute.
1330ca
-    CONST_ACTIONS = ("store_const",
1330ca
-                     "append_const")
1330ca
-
1330ca
-    # The set of known types for option parsers.  Again, listed here for
1330ca
-    # constructor argument validation.
1330ca
-    TYPES = ("string", "int", "long", "float", "complex", "choice")
1330ca
-
1330ca
-    # Dictionary of argument checking functions, which convert and
1330ca
-    # validate option arguments according to the option type.
1330ca
-    #
1330ca
-    # Signature of checking functions is:
1330ca
-    #   check(option : Option, opt : string, value : string) -> any
1330ca
-    # where
1330ca
-    #   option is the Option instance calling the checker
1330ca
-    #   opt is the actual option seen on the command-line
1330ca
-    #     (eg. "-a", "--file")
1330ca
-    #   value is the option argument seen on the command-line
1330ca
-    #
1330ca
-    # The return value should be in the appropriate Python type
1330ca
-    # for option.type -- eg. an integer if option.type == "int".
1330ca
-    #
1330ca
-    # If no checker is defined for a type, arguments will be
1330ca
-    # unchecked and remain strings.
1330ca
-    TYPE_CHECKER = { "int"    : check_builtin,
1330ca
-                     "long"   : check_builtin,
1330ca
-                     "float"  : check_builtin,
1330ca
-                     "complex": check_builtin,
1330ca
-                     "choice" : check_choice,
1330ca
-                   }
1330ca
-
1330ca
-
1330ca
-    # CHECK_METHODS is a list of unbound method objects; they are called
1330ca
-    # by the constructor, in order, after all attributes are
1330ca
-    # initialized.  The list is created and filled in later, after all
1330ca
-    # the methods are actually defined.  (I just put it here because I
1330ca
-    # like to define and document all class attributes in the same
1330ca
-    # place.)  Subclasses that add another _check_*() method should
1330ca
-    # define their own CHECK_METHODS list that adds their check method
1330ca
-    # to those from this class.
1330ca
-    CHECK_METHODS = None
1330ca
-
1330ca
-
1330ca
-    # -- Constructor/initialization methods ----------------------------
1330ca
-
1330ca
-    def __init__(self, *opts, **attrs):
1330ca
-        # Set _short_opts, _long_opts attrs from 'opts' tuple.
1330ca
-        # Have to be set now, in case no option strings are supplied.
1330ca
-        self._short_opts = []
1330ca
-        self._long_opts = []
1330ca
-        opts = self._check_opt_strings(opts)
1330ca
-        self._set_opt_strings(opts)
1330ca
-
1330ca
-        # Set all other attrs (action, type, etc.) from 'attrs' dict
1330ca
-        self._set_attrs(attrs)
1330ca
-
1330ca
-        # Check all the attributes we just set.  There are lots of
1330ca
-        # complicated interdependencies, but luckily they can be farmed
1330ca
-        # out to the _check_*() methods listed in CHECK_METHODS -- which
1330ca
-        # could be handy for subclasses!  The one thing these all share
1330ca
-        # is that they raise OptionError if they discover a problem.
1330ca
-        for checker in self.CHECK_METHODS:
1330ca
-            checker(self)
1330ca
-
1330ca
-    def _check_opt_strings(self, opts):
1330ca
-        # Filter out None because early versions of Optik had exactly
1330ca
-        # one short option and one long option, either of which
1330ca
-        # could be None.
1330ca
-        opts = filter(None, opts)
1330ca
-        if not opts:
1330ca
-            raise TypeError("at least one option string must be supplied")
1330ca
-        return opts
1330ca
-
1330ca
-    def _set_opt_strings(self, opts):
1330ca
-        for opt in opts:
1330ca
-            if len(opt) < 2:
1330ca
-                raise OptionError(
1330ca
-                    "invalid option string %r: "
1330ca
-                    "must be at least two characters long" % opt, self)
1330ca
-            elif len(opt) == 2:
1330ca
-                if not (opt[0] == "-" and opt[1] != "-"):
1330ca
-                    raise OptionError(
1330ca
-                        "invalid short option string %r: "
1330ca
-                        "must be of the form -x, (x any non-dash char)" % opt,
1330ca
-                        self)
1330ca
-                self._short_opts.append(opt)
1330ca
-            else:
1330ca
-                if not (opt[0:2] == "--" and opt[2] != "-"):
1330ca
-                    raise OptionError(
1330ca
-                        "invalid long option string %r: "
1330ca
-                        "must start with --, followed by non-dash" % opt,
1330ca
-                        self)
1330ca
-                self._long_opts.append(opt)
1330ca
-
1330ca
-    def _set_attrs(self, attrs):
1330ca
-        for attr in self.ATTRS:
1330ca
-            if attrs.has_key(attr):
1330ca
-                setattr(self, attr, attrs[attr])
1330ca
-                del attrs[attr]
1330ca
-            else:
1330ca
-                if attr == 'default':
1330ca
-                    setattr(self, attr, NO_DEFAULT)
1330ca
-                else:
1330ca
-                    setattr(self, attr, None)
1330ca
-        if attrs:
1330ca
-            attrs = attrs.keys()
1330ca
-            attrs.sort()
1330ca
-            raise OptionError(
1330ca
-                "invalid keyword arguments: %s" % ", ".join(attrs),
1330ca
-                self)
1330ca
-
1330ca
-
1330ca
-    # -- Constructor validation methods --------------------------------
1330ca
-
1330ca
-    def _check_action(self):
1330ca
-        if self.action is None:
1330ca
-            self.action = "store"
1330ca
-        elif self.action not in self.ACTIONS:
1330ca
-            raise OptionError("invalid action: %r" % self.action, self)
1330ca
-
1330ca
-    def _check_type(self):
1330ca
-        if self.type is None:
1330ca
-            if self.action in self.ALWAYS_TYPED_ACTIONS:
1330ca
-                if self.choices is not None:
1330ca
-                    # The "choices" attribute implies "choice" type.
1330ca
-                    self.type = "choice"
1330ca
-                else:
1330ca
-                    # No type given?  "string" is the most sensible default.
1330ca
-                    self.type = "string"
1330ca
-        else:
1330ca
-            # Allow type objects or builtin type conversion functions
1330ca
-            # (int, str, etc.) as an alternative to their names.  (The
1330ca
-            # complicated check of __builtin__ is only necessary for
1330ca
-            # Python 2.1 and earlier, and is short-circuited by the
1330ca
-            # first check on modern Pythons.)
1330ca
-            import __builtin__
1330ca
-            if ( type(self.type) is types.TypeType or
1330ca
-                 (hasattr(self.type, "__name__") and
1330ca
-                  getattr(__builtin__, self.type.__name__, None) is self.type) ):
1330ca
-                self.type = self.type.__name__
1330ca
-
1330ca
-            if self.type == "str":
1330ca
-                self.type = "string"
1330ca
-
1330ca
-            if self.type not in self.TYPES:
1330ca
-                raise OptionError("invalid option type: %r" % self.type, self)
1330ca
-            if self.action not in self.TYPED_ACTIONS:
1330ca
-                raise OptionError(
1330ca
-                    "must not supply a type for action %r" % self.action, self)
1330ca
-
1330ca
-    def _check_choice(self):
1330ca
-        if self.type == "choice":
1330ca
-            if self.choices is None:
1330ca
-                raise OptionError(
1330ca
-                    "must supply a list of choices for type 'choice'", self)
1330ca
-            elif type(self.choices) not in (types.TupleType, types.ListType):
1330ca
-                raise OptionError(
1330ca
-                    "choices must be a list of strings ('%s' supplied)"
1330ca
-                    % str(type(self.choices)).split("'")[1], self)
1330ca
-        elif self.choices is not None:
1330ca
-            raise OptionError(
1330ca
-                "must not supply choices for type %r" % self.type, self)
1330ca
-
1330ca
-    def _check_dest(self):
1330ca
-        # No destination given, and we need one for this action.  The
1330ca
-        # self.type check is for callbacks that take a value.
1330ca
-        takes_value = (self.action in self.STORE_ACTIONS or
1330ca
-                       self.type is not None)
1330ca
-        if self.dest is None and takes_value:
1330ca
-
1330ca
-            # Glean a destination from the first long option string,
1330ca
-            # or from the first short option string if no long options.
1330ca
-            if self._long_opts:
1330ca
-                # eg. "--foo-bar" -> "foo_bar"
1330ca
-                self.dest = self._long_opts[0][2:].replace('-', '_')
1330ca
-            else:
1330ca
-                self.dest = self._short_opts[0][1]
1330ca
-
1330ca
-    def _check_const(self):
1330ca
-        if self.action not in self.CONST_ACTIONS and self.const is not None:
1330ca
-            raise OptionError(
1330ca
-                "'const' must not be supplied for action %r" % self.action,
1330ca
-                self)
1330ca
-
1330ca
-    def _check_nargs(self):
1330ca
-        if self.action in self.TYPED_ACTIONS:
1330ca
-            if self.nargs is None:
1330ca
-                self.nargs = 1
1330ca
-        elif self.nargs is not None:
1330ca
-            raise OptionError(
1330ca
-                "'nargs' must not be supplied for action %r" % self.action,
1330ca
-                self)
1330ca
-
1330ca
-    def _check_callback(self):
1330ca
-        if self.action == "callback":
1330ca
-            if not callable(self.callback):
1330ca
-                raise OptionError(
1330ca
-                    "callback not callable: %r" % self.callback, self)
1330ca
-            if (self.callback_args is not None and
1330ca
-                type(self.callback_args) is not types.TupleType):
1330ca
-                raise OptionError(
1330ca
-                    "callback_args, if supplied, must be a tuple: not %r"
1330ca
-                    % self.callback_args, self)
1330ca
-            if (self.callback_kwargs is not None and
1330ca
-                type(self.callback_kwargs) is not types.DictType):
1330ca
-                raise OptionError(
1330ca
-                    "callback_kwargs, if supplied, must be a dict: not %r"
1330ca
-                    % self.callback_kwargs, self)
1330ca
-        else:
1330ca
-            if self.callback is not None:
1330ca
-                raise OptionError(
1330ca
-                    "callback supplied (%r) for non-callback option"
1330ca
-                    % self.callback, self)
1330ca
-            if self.callback_args is not None:
1330ca
-                raise OptionError(
1330ca
-                    "callback_args supplied for non-callback option", self)
1330ca
-            if self.callback_kwargs is not None:
1330ca
-                raise OptionError(
1330ca
-                    "callback_kwargs supplied for non-callback option", self)
1330ca
-
1330ca
-
1330ca
-    CHECK_METHODS = [_check_action,
1330ca
-                     _check_type,
1330ca
-                     _check_choice,
1330ca
-                     _check_dest,
1330ca
-                     _check_const,
1330ca
-                     _check_nargs,
1330ca
-                     _check_callback]
1330ca
-
1330ca
-
1330ca
-    # -- Miscellaneous methods -----------------------------------------
1330ca
-
1330ca
-    def __str__(self):
1330ca
-        return "/".join(self._short_opts + self._long_opts)
1330ca
-
1330ca
-    __repr__ = _repr
1330ca
-
1330ca
-    def takes_value(self):
1330ca
-        return self.type is not None
1330ca
-
1330ca
-    def get_opt_string(self):
1330ca
-        if self._long_opts:
1330ca
-            return self._long_opts[0]
1330ca
-        else:
1330ca
-            return self._short_opts[0]
1330ca
-
1330ca
-
1330ca
-    # -- Processing methods --------------------------------------------
1330ca
-
1330ca
-    def check_value(self, opt, value):
1330ca
-        checker = self.TYPE_CHECKER.get(self.type)
1330ca
-        if checker is None:
1330ca
-            return value
1330ca
-        else:
1330ca
-            return checker(self, opt, value)
1330ca
-
1330ca
-    def convert_value(self, opt, value):
1330ca
-        if value is not None:
1330ca
-            if self.nargs == 1:
1330ca
-                return self.check_value(opt, value)
1330ca
-            else:
1330ca
-                return tuple([self.check_value(opt, v) for v in value])
1330ca
-
1330ca
-    def process(self, opt, value, values, parser):
1330ca
-
1330ca
-        # First, convert the value(s) to the right type.  Howl if any
1330ca
-        # value(s) are bogus.
1330ca
-        value = self.convert_value(opt, value)
1330ca
-
1330ca
-        # And then take whatever action is expected of us.
1330ca
-        # This is a separate method to make life easier for
1330ca
-        # subclasses to add new actions.
1330ca
-        return self.take_action(
1330ca
-            self.action, self.dest, opt, value, values, parser)
1330ca
-
1330ca
-    def take_action(self, action, dest, opt, value, values, parser):
1330ca
-        if action == "store":
1330ca
-            setattr(values, dest, value)
1330ca
-        elif action == "store_const":
1330ca
-            setattr(values, dest, self.const)
1330ca
-        elif action == "store_true":
1330ca
-            setattr(values, dest, True)
1330ca
-        elif action == "store_false":
1330ca
-            setattr(values, dest, False)
1330ca
-        elif action == "append":
1330ca
-            values.ensure_value(dest, []).append(value)
1330ca
-        elif action == "append_const":
1330ca
-            values.ensure_value(dest, []).append(self.const)
1330ca
-        elif action == "count":
1330ca
-            setattr(values, dest, values.ensure_value(dest, 0) + 1)
1330ca
-        elif action == "callback":
1330ca
-            args = self.callback_args or ()
1330ca
-            kwargs = self.callback_kwargs or {}
1330ca
-            self.callback(self, opt, value, parser, *args, **kwargs)
1330ca
-        elif action == "help":
1330ca
-            parser.print_help()
1330ca
-            parser.exit()
1330ca
-        elif action == "version":
1330ca
-            parser.print_version()
1330ca
-            parser.exit()
1330ca
-        else:
1330ca
-            raise RuntimeError, "unknown action %r" % self.action
1330ca
-
1330ca
-        return 1
1330ca
-
1330ca
-# class Option
1330ca
-
1330ca
-
1330ca
-SUPPRESS_HELP = "SUPPRESS"+"HELP"
1330ca
-SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
1330ca
-
1330ca
-# For compatibility with Python 2.2
1330ca
-try:
1330ca
-    True, False
1330ca
-except NameError:
1330ca
-    (True, False) = (1, 0)
1330ca
-
1330ca
-def isbasestring(x):
1330ca
-    return isinstance(x, types.StringType) or isinstance(x, types.UnicodeType)
1330ca
-
1330ca
-class Values:
1330ca
-
1330ca
-    def __init__(self, defaults=None):
1330ca
-        if defaults:
1330ca
-            for (attr, val) in defaults.items():
1330ca
-                setattr(self, attr, val)
1330ca
-
1330ca
-    def __str__(self):
1330ca
-        return str(self.__dict__)
1330ca
-
1330ca
-    __repr__ = _repr
1330ca
-
1330ca
-    def __cmp__(self, other):
1330ca
-        if isinstance(other, Values):
1330ca
-            return cmp(self.__dict__, other.__dict__)
1330ca
-        elif isinstance(other, types.DictType):
1330ca
-            return cmp(self.__dict__, other)
1330ca
-        else:
1330ca
-            return -1
1330ca
-
1330ca
-    def _update_careful(self, dict):
1330ca
-        """
1330ca
-        Update the option values from an arbitrary dictionary, but only
1330ca
-        use keys from dict that already have a corresponding attribute
1330ca
-        in self.  Any keys in dict without a corresponding attribute
1330ca
-        are silently ignored.
1330ca
-        """
1330ca
-        for attr in dir(self):
1330ca
-            if dict.has_key(attr):
1330ca
-                dval = dict[attr]
1330ca
-                if dval is not None:
1330ca
-                    setattr(self, attr, dval)
1330ca
-
1330ca
-    def _update_loose(self, dict):
1330ca
-        """
1330ca
-        Update the option values from an arbitrary dictionary,
1330ca
-        using all keys from the dictionary regardless of whether
1330ca
-        they have a corresponding attribute in self or not.
1330ca
-        """
1330ca
-        self.__dict__.update(dict)
1330ca
-
1330ca
-    def _update(self, dict, mode):
1330ca
-        if mode == "careful":
1330ca
-            self._update_careful(dict)
1330ca
-        elif mode == "loose":
1330ca
-            self._update_loose(dict)
1330ca
-        else:
1330ca
-            raise ValueError, "invalid update mode: %r" % mode
1330ca
-
1330ca
-    def read_module(self, modname, mode="careful"):
1330ca
-        __import__(modname)
1330ca
-        mod = sys.modules[modname]
1330ca
-        self._update(vars(mod), mode)
1330ca
-
1330ca
-    def read_file(self, filename, mode="careful"):
1330ca
-        vars = {}
1330ca
-        execfile(filename, vars)
1330ca
-        self._update(vars, mode)
1330ca
-
1330ca
-    def ensure_value(self, attr, value):
1330ca
-        if not hasattr(self, attr) or getattr(self, attr) is None:
1330ca
-            setattr(self, attr, value)
1330ca
-        return getattr(self, attr)
1330ca
-
1330ca
-
1330ca
-class OptionContainer:
1330ca
-
1330ca
-    """
1330ca
-    Abstract base class.
1330ca
-
1330ca
-    Class attributes:
1330ca
-      standard_option_list : [Option]
1330ca
-        list of standard options that will be accepted by all instances
1330ca
-        of this parser class (intended to be overridden by subclasses).
1330ca
-
1330ca
-    Instance attributes:
1330ca
-      option_list : [Option]
1330ca
-        the list of Option objects contained by this OptionContainer
1330ca
-      _short_opt : { string : Option }
1330ca
-        dictionary mapping short option strings, eg. "-f" or "-X",
1330ca
-        to the Option instances that implement them.  If an Option
1330ca
-        has multiple short option strings, it will appears in this
1330ca
-        dictionary multiple times. [1]
1330ca
-      _long_opt : { string : Option }
1330ca
-        dictionary mapping long option strings, eg. "--file" or
1330ca
-        "--exclude", to the Option instances that implement them.
1330ca
-        Again, a given Option can occur multiple times in this
1330ca
-        dictionary. [1]
1330ca
-      defaults : { string : any }
1330ca
-        dictionary mapping option destination names to default
1330ca
-        values for each destination [1]
1330ca
-
1330ca
-    [1] These mappings are common to (shared by) all components of the
1330ca
-        controlling OptionParser, where they are initially created.
1330ca
-
1330ca
-    """
1330ca
-
1330ca
-    def __init__(self, option_class, conflict_handler, description):
1330ca
-        # Initialize the option list and related data structures.
1330ca
-        # This method must be provided by subclasses, and it must
1330ca
-        # initialize at least the following instance attributes:
1330ca
-        # option_list, _short_opt, _long_opt, defaults.
1330ca
-        self._create_option_list()
1330ca
-
1330ca
-        self.option_class = option_class
1330ca
-        self.set_conflict_handler(conflict_handler)
1330ca
-        self.set_description(description)
1330ca
-
1330ca
-    def _create_option_mappings(self):
1330ca
-        # For use by OptionParser constructor -- create the master
1330ca
-        # option mappings used by this OptionParser and all
1330ca
-        # OptionGroups that it owns.
1330ca
-        self._short_opt = {}            # single letter -> Option instance
1330ca
-        self._long_opt = {}             # long option -> Option instance
1330ca
-        self.defaults = {}              # maps option dest -> default value
1330ca
-
1330ca
-
1330ca
-    def _share_option_mappings(self, parser):
1330ca
-        # For use by OptionGroup constructor -- use shared option
1330ca
-        # mappings from the OptionParser that owns this OptionGroup.
1330ca
-        self._short_opt = parser._short_opt
1330ca
-        self._long_opt = parser._long_opt
1330ca
-        self.defaults = parser.defaults
1330ca
-
1330ca
-    def set_conflict_handler(self, handler):
1330ca
-        if handler not in ("error", "resolve"):
1330ca
-            raise ValueError, "invalid conflict_resolution value %r" % handler
1330ca
-        self.conflict_handler = handler
1330ca
-
1330ca
-    def set_description(self, description):
1330ca
-        self.description = description
1330ca
-
1330ca
-    def get_description(self):
1330ca
-        return self.description
1330ca
-
1330ca
-
1330ca
-    def destroy(self):
1330ca
-        """see OptionParser.destroy()."""
1330ca
-        del self._short_opt
1330ca
-        del self._long_opt
1330ca
-        del self.defaults
1330ca
-
1330ca
-
1330ca
-    # -- Option-adding methods -----------------------------------------
1330ca
-
1330ca
-    def _check_conflict(self, option):
1330ca
-        conflict_opts = []
1330ca
-        for opt in option._short_opts:
1330ca
-            if self._short_opt.has_key(opt):
1330ca
-                conflict_opts.append((opt, self._short_opt[opt]))
1330ca
-        for opt in option._long_opts:
1330ca
-            if self._long_opt.has_key(opt):
1330ca
-                conflict_opts.append((opt, self._long_opt[opt]))
1330ca
-
1330ca
-        if conflict_opts:
1330ca
-            handler = self.conflict_handler
1330ca
-            if handler == "error":
1330ca
-                raise OptionConflictError(
1330ca
-                    "conflicting option string(s): %s"
1330ca
-                    % ", ".join([co[0] for co in conflict_opts]),
1330ca
-                    option)
1330ca
-            elif handler == "resolve":
1330ca
-                for (opt, c_option) in conflict_opts:
1330ca
-                    if opt.startswith("--"):
1330ca
-                        c_option._long_opts.remove(opt)
1330ca
-                        del self._long_opt[opt]
1330ca
-                    else:
1330ca
-                        c_option._short_opts.remove(opt)
1330ca
-                        del self._short_opt[opt]
1330ca
-                    if not (c_option._short_opts or c_option._long_opts):
1330ca
-                        c_option.container.option_list.remove(c_option)
1330ca
-
1330ca
-    def add_option(self, *args, **kwargs):
1330ca
-        """add_option(Option)
1330ca
-           add_option(opt_str, ..., kwarg=val, ...)
1330ca
-        """
1330ca
-        if type(args[0]) is types.StringType:
1330ca
-            option = self.option_class(*args, **kwargs)
1330ca
-        elif len(args) == 1 and not kwargs:
1330ca
-            option = args[0]
1330ca
-            if not isinstance(option, Option):
1330ca
-                raise TypeError, "not an Option instance: %r" % option
1330ca
-        else:
1330ca
-            raise TypeError, "invalid arguments"
1330ca
-
1330ca
-        self._check_conflict(option)
1330ca
-
1330ca
-        self.option_list.append(option)
1330ca
-        option.container = self
1330ca
-        for opt in option._short_opts:
1330ca
-            self._short_opt[opt] = option
1330ca
-        for opt in option._long_opts:
1330ca
-            self._long_opt[opt] = option
1330ca
-
1330ca
-        if option.dest is not None:     # option has a dest, we need a default
1330ca
-            if option.default is not NO_DEFAULT:
1330ca
-                self.defaults[option.dest] = option.default
1330ca
-            elif not self.defaults.has_key(option.dest):
1330ca
-                self.defaults[option.dest] = None
1330ca
-
1330ca
-        return option
1330ca
-
1330ca
-    def add_options(self, option_list):
1330ca
-        for option in option_list:
1330ca
-            self.add_option(option)
1330ca
-
1330ca
-    # -- Option query/removal methods ----------------------------------
1330ca
-
1330ca
-    def get_option(self, opt_str):
1330ca
-        return (self._short_opt.get(opt_str) or
1330ca
-                self._long_opt.get(opt_str))
1330ca
-
1330ca
-    def has_option(self, opt_str):
1330ca
-        return (self._short_opt.has_key(opt_str) or
1330ca
-                self._long_opt.has_key(opt_str))
1330ca
-
1330ca
-    def remove_option(self, opt_str):
1330ca
-        option = self._short_opt.get(opt_str)
1330ca
-        if option is None:
1330ca
-            option = self._long_opt.get(opt_str)
1330ca
-        if option is None:
1330ca
-            raise ValueError("no such option %r" % opt_str)
1330ca
-
1330ca
-        for opt in option._short_opts:
1330ca
-            del self._short_opt[opt]
1330ca
-        for opt in option._long_opts:
1330ca
-            del self._long_opt[opt]
1330ca
-        option.container.option_list.remove(option)
1330ca
-
1330ca
-
1330ca
-    # -- Help-formatting methods ---------------------------------------
1330ca
-
1330ca
-    def format_option_help(self, formatter):
1330ca
-        if not self.option_list:
1330ca
-            return ""
1330ca
-        result = []
1330ca
-        for option in self.option_list:
1330ca
-            if not option.help is SUPPRESS_HELP:
1330ca
-                result.append(formatter.format_option(option))
1330ca
-        return "".join(result)
1330ca
-
1330ca
-    def format_description(self, formatter):
1330ca
-        return formatter.format_description(self.get_description())
1330ca
-
1330ca
-    def format_help(self, formatter):
1330ca
-        result = []
1330ca
-        if self.description:
1330ca
-            result.append(self.format_description(formatter))
1330ca
-        if self.option_list:
1330ca
-            result.append(self.format_option_help(formatter))
1330ca
-        return "\n".join(result)
1330ca
-
1330ca
-
1330ca
-class OptionGroup (OptionContainer):
1330ca
-
1330ca
-    def __init__(self, parser, title, description=None):
1330ca
-        self.parser = parser
1330ca
-        OptionContainer.__init__(
1330ca
-            self, parser.option_class, parser.conflict_handler, description)
1330ca
-        self.title = title
1330ca
-
1330ca
-    def _create_option_list(self):
1330ca
-        self.option_list = []
1330ca
-        self._share_option_mappings(self.parser)
1330ca
-
1330ca
-    def set_title(self, title):
1330ca
-        self.title = title
1330ca
-
1330ca
-    def destroy(self):
1330ca
-        """see OptionParser.destroy()."""
1330ca
-        OptionContainer.destroy(self)
1330ca
-        del self.option_list
1330ca
-
1330ca
-    # -- Help-formatting methods ---------------------------------------
1330ca
-
1330ca
-    def format_help(self, formatter):
1330ca
-        result = formatter.format_heading(self.title)
1330ca
-        formatter.indent()
1330ca
-        result += OptionContainer.format_help(self, formatter)
1330ca
-        formatter.dedent()
1330ca
-        return result
1330ca
-
1330ca
-
1330ca
-class OptionParser (OptionContainer):
1330ca
-
1330ca
-    """
1330ca
-    Class attributes:
1330ca
-      standard_option_list : [Option]
1330ca
-        list of standard options that will be accepted by all instances
1330ca
-        of this parser class (intended to be overridden by subclasses).
1330ca
-
1330ca
-    Instance attributes:
1330ca
-      usage : string
1330ca
-        a usage string for your program.  Before it is displayed
1330ca
-        to the user, "%prog" will be expanded to the name of
1330ca
-        your program (self.prog or os.path.basename(sys.argv[0])).
1330ca
-      prog : string
1330ca
-        the name of the current program (to override
1330ca
-        os.path.basename(sys.argv[0])).
1330ca
-      epilog : string
1330ca
-        paragraph of help text to print after option help
1330ca
-
1330ca
-      option_groups : [OptionGroup]
1330ca
-        list of option groups in this parser (option groups are
1330ca
-        irrelevant for parsing the command-line, but very useful
1330ca
-        for generating help)
1330ca
-
1330ca
-      allow_interspersed_args : bool = true
1330ca
-        if true, positional arguments may be interspersed with options.
1330ca
-        Assuming -a and -b each take a single argument, the command-line
1330ca
-          -ablah foo bar -bboo baz
1330ca
-        will be interpreted the same as
1330ca
-          -ablah -bboo -- foo bar baz
1330ca
-        If this flag were false, that command line would be interpreted as
1330ca
-          -ablah -- foo bar -bboo baz
1330ca
-        -- ie. we stop processing options as soon as we see the first
1330ca
-        non-option argument.  (This is the tradition followed by
1330ca
-        Python's getopt module, Perl's Getopt::Std, and other argument-
1330ca
-        parsing libraries, but it is generally annoying to users.)
1330ca
-
1330ca
-      process_default_values : bool = true
1330ca
-        if true, option default values are processed similarly to option
1330ca
-        values from the command line: that is, they are passed to the
1330ca
-        type-checking function for the option's type (as long as the
1330ca
-        default value is a string).  (This really only matters if you
1330ca
-        have defined custom types; see SF bug #955889.)  Set it to false
1330ca
-        to restore the behaviour of Optik 1.4.1 and earlier.
1330ca
-
1330ca
-      rargs : [string]
1330ca
-        the argument list currently being parsed.  Only set when
1330ca
-        parse_args() is active, and continually trimmed down as
1330ca
-        we consume arguments.  Mainly there for the benefit of
1330ca
-        callback options.
1330ca
-      largs : [string]
1330ca
-        the list of leftover arguments that we have skipped while
1330ca
-        parsing options.  If allow_interspersed_args is false, this
1330ca
-        list is always empty.
1330ca
-      values : Values
1330ca
-        the set of option values currently being accumulated.  Only
1330ca
-        set when parse_args() is active.  Also mainly for callbacks.
1330ca
-
1330ca
-    Because of the 'rargs', 'largs', and 'values' attributes,
1330ca
-    OptionParser is not thread-safe.  If, for some perverse reason, you
1330ca
-    need to parse command-line arguments simultaneously in different
1330ca
-    threads, use different OptionParser instances.
1330ca
-
1330ca
-    """
1330ca
-
1330ca
-    standard_option_list = []
1330ca
-
1330ca
-    def __init__(self,
1330ca
-                 usage=None,
1330ca
-                 option_list=None,
1330ca
-                 option_class=Option,
1330ca
-                 version=None,
1330ca
-                 conflict_handler="error",
1330ca
-                 description=None,
1330ca
-                 formatter=None,
1330ca
-                 add_help_option=True,
1330ca
-                 prog=None,
1330ca
-                 epilog=None):
1330ca
-        OptionContainer.__init__(
1330ca
-            self, option_class, conflict_handler, description)
1330ca
-        self.set_usage(usage)
1330ca
-        self.prog = prog
1330ca
-        self.version = version
1330ca
-        self.allow_interspersed_args = True
1330ca
-        self.process_default_values = True
1330ca
-        if formatter is None:
1330ca
-            formatter = IndentedHelpFormatter()
1330ca
-        self.formatter = formatter
1330ca
-        self.formatter.set_parser(self)
1330ca
-        self.epilog = epilog
1330ca
-
1330ca
-        # Populate the option list; initial sources are the
1330ca
-        # standard_option_list class attribute, the 'option_list'
1330ca
-        # argument, and (if applicable) the _add_version_option() and
1330ca
-        # _add_help_option() methods.
1330ca
-        self._populate_option_list(option_list,
1330ca
-                                   add_help=add_help_option)
1330ca
-
1330ca
-        self._init_parsing_state()
1330ca
-
1330ca
-
1330ca
-    def destroy(self):
1330ca
-        """
1330ca
-        Declare that you are done with this OptionParser.  This cleans up
1330ca
-        reference cycles so the OptionParser (and all objects referenced by
1330ca
-        it) can be garbage-collected promptly.  After calling destroy(), the
1330ca
-        OptionParser is unusable.
1330ca
-        """
1330ca
-        OptionContainer.destroy(self)
1330ca
-        for group in self.option_groups:
1330ca
-            group.destroy()
1330ca
-        del self.option_list
1330ca
-        del self.option_groups
1330ca
-        del self.formatter
1330ca
-
1330ca
-
1330ca
-    # -- Private methods -----------------------------------------------
1330ca
-    # (used by our or OptionContainer's constructor)
1330ca
-
1330ca
-    def _create_option_list(self):
1330ca
-        self.option_list = []
1330ca
-        self.option_groups = []
1330ca
-        self._create_option_mappings()
1330ca
-
1330ca
-    def _add_help_option(self):
1330ca
-        self.add_option("-h", "--help",
1330ca
-                        action="help",
1330ca
-                        help=_("show this help message and exit"))
1330ca
-
1330ca
-    def _add_version_option(self):
1330ca
-        self.add_option("--version",
1330ca
-                        action="version",
1330ca
-                        help=_("show program's version number and exit"))
1330ca
-
1330ca
-    def _populate_option_list(self, option_list, add_help=True):
1330ca
-        if self.standard_option_list:
1330ca
-            self.add_options(self.standard_option_list)
1330ca
-        if option_list:
1330ca
-            self.add_options(option_list)
1330ca
-        if self.version:
1330ca
-            self._add_version_option()
1330ca
-        if add_help:
1330ca
-            self._add_help_option()
1330ca
-
1330ca
-    def _init_parsing_state(self):
1330ca
-        # These are set in parse_args() for the convenience of callbacks.
1330ca
-        self.rargs = None
1330ca
-        self.largs = None
1330ca
-        self.values = None
1330ca
-
1330ca
-
1330ca
-    # -- Simple modifier methods ---------------------------------------
1330ca
-
1330ca
-    def set_usage(self, usage):
1330ca
-        if usage is None:
1330ca
-            self.usage = _("%prog [options]")
1330ca
-        elif usage is SUPPRESS_USAGE:
1330ca
-            self.usage = None
1330ca
-        # For backwards compatibility with Optik 1.3 and earlier.
1330ca
-        elif usage.lower().startswith("usage: "):
1330ca
-            self.usage = usage[7:]
1330ca
-        else:
1330ca
-            self.usage = usage
1330ca
-
1330ca
-    def enable_interspersed_args(self):
1330ca
-        self.allow_interspersed_args = True
1330ca
-
1330ca
-    def disable_interspersed_args(self):
1330ca
-        self.allow_interspersed_args = False
1330ca
-
1330ca
-    def set_process_default_values(self, process):
1330ca
-        self.process_default_values = process
1330ca
-
1330ca
-    def set_default(self, dest, value):
1330ca
-        self.defaults[dest] = value
1330ca
-
1330ca
-    def set_defaults(self, **kwargs):
1330ca
-        self.defaults.update(kwargs)
1330ca
-
1330ca
-    def _get_all_options(self):
1330ca
-        options = self.option_list[:]
1330ca
-        for group in self.option_groups:
1330ca
-            options.extend(group.option_list)
1330ca
-        return options
1330ca
-
1330ca
-    def get_default_values(self):
1330ca
-        if not self.process_default_values:
1330ca
-            # Old, pre-Optik 1.5 behaviour.
1330ca
-            return Values(self.defaults)
1330ca
-
1330ca
-        defaults = self.defaults.copy()
1330ca
-        for option in self._get_all_options():
1330ca
-            default = defaults.get(option.dest)
1330ca
-            if isbasestring(default):
1330ca
-                opt_str = option.get_opt_string()
1330ca
-                defaults[option.dest] = option.check_value(opt_str, default)
1330ca
-
1330ca
-        return Values(defaults)
1330ca
-
1330ca
-
1330ca
-    # -- OptionGroup methods -------------------------------------------
1330ca
-
1330ca
-    def add_option_group(self, *args, **kwargs):
1330ca
-        # XXX lots of overlap with OptionContainer.add_option()
1330ca
-        if type(args[0]) is types.StringType:
1330ca
-            group = OptionGroup(self, *args, **kwargs)
1330ca
-        elif len(args) == 1 and not kwargs:
1330ca
-            group = args[0]
1330ca
-            if not isinstance(group, OptionGroup):
1330ca
-                raise TypeError, "not an OptionGroup instance: %r" % group
1330ca
-            if group.parser is not self:
1330ca
-                raise ValueError, "invalid OptionGroup (wrong parser)"
1330ca
-        else:
1330ca
-            raise TypeError, "invalid arguments"
1330ca
-
1330ca
-        self.option_groups.append(group)
1330ca
-        return group
1330ca
-
1330ca
-    def get_option_group(self, opt_str):
1330ca
-        option = (self._short_opt.get(opt_str) or
1330ca
-                  self._long_opt.get(opt_str))
1330ca
-        if option and option.container is not self:
1330ca
-            return option.container
1330ca
-        return None
1330ca
-
1330ca
-
1330ca
-    # -- Option-parsing methods ----------------------------------------
1330ca
-
1330ca
-    def _get_args(self, args):
1330ca
-        if args is None:
1330ca
-            return sys.argv[1:]
1330ca
-        else:
1330ca
-            return args[:]              # don't modify caller's list
1330ca
-
1330ca
-    def parse_args(self, args=None, values=None):
1330ca
-        """
1330ca
-        parse_args(args : [string] = sys.argv[1:],
1330ca
-                   values : Values = None)
1330ca
-        -> (values : Values, args : [string])
1330ca
-
1330ca
-        Parse the command-line options found in 'args' (default:
1330ca
-        sys.argv[1:]).  Any errors result in a call to 'error()', which
1330ca
-        by default prints the usage message to stderr and calls
1330ca
-        sys.exit() with an error message.  On success returns a pair
1330ca
-        (values, args) where 'values' is an Values instance (with all
1330ca
-        your option values) and 'args' is the list of arguments left
1330ca
-        over after parsing options.
1330ca
-        """
1330ca
-        rargs = self._get_args(args)
1330ca
-        if values is None:
1330ca
-            values = self.get_default_values()
1330ca
-
1330ca
-        # Store the halves of the argument list as attributes for the
1330ca
-        # convenience of callbacks:
1330ca
-        #   rargs
1330ca
-        #     the rest of the command-line (the "r" stands for
1330ca
-        #     "remaining" or "right-hand")
1330ca
-        #   largs
1330ca
-        #     the leftover arguments -- ie. what's left after removing
1330ca
-        #     options and their arguments (the "l" stands for "leftover"
1330ca
-        #     or "left-hand")
1330ca
-        self.rargs = rargs
1330ca
-        self.largs = largs = []
1330ca
-        self.values = values
1330ca
-
1330ca
-        try:
1330ca
-            stop = self._process_args(largs, rargs, values)
1330ca
-        except (BadOptionError, OptionValueError), err:
1330ca
-            self.error(str(err))
1330ca
-
1330ca
-        args = largs + rargs
1330ca
-        return self.check_values(values, args)
1330ca
-
1330ca
-    def check_values(self, values, args):
1330ca
-        """
1330ca
-        check_values(values : Values, args : [string])
1330ca
-        -> (values : Values, args : [string])
1330ca
-
1330ca
-        Check that the supplied option values and leftover arguments are
1330ca
-        valid.  Returns the option values and leftover arguments
1330ca
-        (possibly adjusted, possibly completely new -- whatever you
1330ca
-        like).  Default implementation just returns the passed-in
1330ca
-        values; subclasses may override as desired.
1330ca
-        """
1330ca
-        return (values, args)
1330ca
-
1330ca
-    def _process_args(self, largs, rargs, values):
1330ca
-        """_process_args(largs : [string],
1330ca
-                         rargs : [string],
1330ca
-                         values : Values)
1330ca
-
1330ca
-        Process command-line arguments and populate 'values', consuming
1330ca
-        options and arguments from 'rargs'.  If 'allow_interspersed_args' is
1330ca
-        false, stop at the first non-option argument.  If true, accumulate any
1330ca
-        interspersed non-option arguments in 'largs'.
1330ca
-        """
1330ca
-        while rargs:
1330ca
-            arg = rargs[0]
1330ca
-            # We handle bare "--" explicitly, and bare "-" is handled by the
1330ca
-            # standard arg handler since the short arg case ensures that the
1330ca
-            # len of the opt string is greater than 1.
1330ca
-            if arg == "--":
1330ca
-                del rargs[0]
1330ca
-                return
1330ca
-            elif arg[0:2] == "--":
1330ca
-                # process a single long option (possibly with value(s))
1330ca
-                self._process_long_opt(rargs, values)
1330ca
-            elif arg[:1] == "-" and len(arg) > 1:
1330ca
-                # process a cluster of short options (possibly with
1330ca
-                # value(s) for the last one only)
1330ca
-                self._process_short_opts(rargs, values)
1330ca
-            elif self.allow_interspersed_args:
1330ca
-                largs.append(arg)
1330ca
-                del rargs[0]
1330ca
-            else:
1330ca
-                return                  # stop now, leave this arg in rargs
1330ca
-
1330ca
-        # Say this is the original argument list:
1330ca
-        # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
1330ca
-        #                            ^
1330ca
-        # (we are about to process arg(i)).
1330ca
-        #
1330ca
-        # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of
1330ca
-        # [arg0, ..., arg(i-1)] (any options and their arguments will have
1330ca
-        # been removed from largs).
1330ca
-        #
1330ca
-        # The while loop will usually consume 1 or more arguments per pass.
1330ca
-        # If it consumes 1 (eg. arg is an option that takes no arguments),
1330ca
-        # then after _process_arg() is done the situation is:
1330ca
-        #
1330ca
-        #   largs = subset of [arg0, ..., arg(i)]
1330ca
-        #   rargs = [arg(i+1), ..., arg(N-1)]
1330ca
-        #
1330ca
-        # If allow_interspersed_args is false, largs will always be
1330ca
-        # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
1330ca
-        # not a very interesting subset!
1330ca
-
1330ca
-    def _match_long_opt(self, opt):
1330ca
-        """_match_long_opt(opt : string) -> string
1330ca
-
1330ca
-        Determine which long option string 'opt' matches, ie. which one
1330ca
-        it is an unambiguous abbrevation for.  Raises BadOptionError if
1330ca
-        'opt' doesn't unambiguously match any long option string.
1330ca
-        """
1330ca
-        return _match_abbrev(opt, self._long_opt)
1330ca
-
1330ca
-    def _process_long_opt(self, rargs, values):
1330ca
-        arg = rargs.pop(0)
1330ca
-
1330ca
-        # Value explicitly attached to arg?  Pretend it's the next
1330ca
-        # argument.
1330ca
-        if "=" in arg:
1330ca
-            (opt, next_arg) = arg.split("=", 1)
1330ca
-            rargs.insert(0, next_arg)
1330ca
-            had_explicit_value = True
1330ca
-        else:
1330ca
-            opt = arg
1330ca
-            had_explicit_value = False
1330ca
-
1330ca
-        opt = self._match_long_opt(opt)
1330ca
-        option = self._long_opt[opt]
1330ca
-        if option.takes_value():
1330ca
-            nargs = option.nargs
1330ca
-            if len(rargs) < nargs:
1330ca
-                if nargs == 1:
1330ca
-                    self.error(_("%s option requires an argument") % opt)
1330ca
-                else:
1330ca
-                    self.error(_("%s option requires %d arguments")
1330ca
-                               % (opt, nargs))
1330ca
-            elif nargs == 1:
1330ca
-                value = rargs.pop(0)
1330ca
-            else:
1330ca
-                value = tuple(rargs[0:nargs])
1330ca
-                del rargs[0:nargs]
1330ca
-
1330ca
-        elif had_explicit_value:
1330ca
-            self.error(_("%s option does not take a value") % opt)
1330ca
-
1330ca
-        else:
1330ca
-            value = None
1330ca
-
1330ca
-        option.process(opt, value, values, self)
1330ca
-
1330ca
-    def _process_short_opts(self, rargs, values):
1330ca
-        arg = rargs.pop(0)
1330ca
-        stop = False
1330ca
-        i = 1
1330ca
-        for ch in arg[1:]:
1330ca
-            opt = "-" + ch
1330ca
-            option = self._short_opt.get(opt)
1330ca
-            i += 1                      # we have consumed a character
1330ca
-
1330ca
-            if not option:
1330ca
-                raise BadOptionError(opt)
1330ca
-            if option.takes_value():
1330ca
-                # Any characters left in arg?  Pretend they're the
1330ca
-                # next arg, and stop consuming characters of arg.
1330ca
-                if i < len(arg):
1330ca
-                    rargs.insert(0, arg[i:])
1330ca
-                    stop = True
1330ca
-
1330ca
-                nargs = option.nargs
1330ca
-                if len(rargs) < nargs:
1330ca
-                    if nargs == 1:
1330ca
-                        self.error(_("%s option requires an argument") % opt)
1330ca
-                    else:
1330ca
-                        self.error(_("%s option requires %d arguments")
1330ca
-                                   % (opt, nargs))
1330ca
-                elif nargs == 1:
1330ca
-                    value = rargs.pop(0)
1330ca
-                else:
1330ca
-                    value = tuple(rargs[0:nargs])
1330ca
-                    del rargs[0:nargs]
1330ca
-
1330ca
-            else:                       # option doesn't take a value
1330ca
-                value = None
1330ca
-
1330ca
-            option.process(opt, value, values, self)
1330ca
-
1330ca
-            if stop:
1330ca
-                break
1330ca
-
1330ca
-
1330ca
-    # -- Feedback methods ----------------------------------------------
1330ca
-
1330ca
-    def get_prog_name(self):
1330ca
-        if self.prog is None:
1330ca
-            return os.path.basename(sys.argv[0])
1330ca
-        else:
1330ca
-            return self.prog
1330ca
-
1330ca
-    def expand_prog_name(self, s):
1330ca
-        return s.replace("%prog", self.get_prog_name())
1330ca
-
1330ca
-    def get_description(self):
1330ca
-        return self.expand_prog_name(self.description)
1330ca
-
1330ca
-    def exit(self, status=0, msg=None):
1330ca
-        if msg:
1330ca
-            sys.stderr.write(msg)
1330ca
-        sys.exit(status)
1330ca
-
1330ca
-    def error(self, msg):
1330ca
-        """error(msg : string)
1330ca
-
1330ca
-        Print a usage message incorporating 'msg' to stderr and exit.
1330ca
-        If you override this in a subclass, it should not return -- it
1330ca
-        should either exit or raise an exception.
1330ca
-        """
1330ca
-        self.print_usage(sys.stderr)
1330ca
-        self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
1330ca
-
1330ca
-    def get_usage(self):
1330ca
-        if self.usage:
1330ca
-            return self.formatter.format_usage(
1330ca
-                self.expand_prog_name(self.usage))
1330ca
-        else:
1330ca
-            return ""
1330ca
-
1330ca
-    def print_usage(self, file=None):
1330ca
-        """print_usage(file : file = stdout)
1330ca
-
1330ca
-        Print the usage message for the current program (self.usage) to
1330ca
-        'file' (default stdout).  Any occurence of the string "%prog" in
1330ca
-        self.usage is replaced with the name of the current program
1330ca
-        (basename of sys.argv[0]).  Does nothing if self.usage is empty
1330ca
-        or not defined.
1330ca
-        """
1330ca
-        if self.usage:
1330ca
-            print >>file, self.get_usage()
1330ca
-
1330ca
-    def get_version(self):
1330ca
-        if self.version:
1330ca
-            return self.expand_prog_name(self.version)
1330ca
-        else:
1330ca
-            return ""
1330ca
-
1330ca
-    def print_version(self, file=None):
1330ca
-        """print_version(file : file = stdout)
1330ca
-
1330ca
-        Print the version message for this program (self.version) to
1330ca
-        'file' (default stdout).  As with print_usage(), any occurence
1330ca
-        of "%prog" in self.version is replaced by the current program's
1330ca
-        name.  Does nothing if self.version is empty or undefined.
1330ca
-        """
1330ca
-        if self.version:
1330ca
-            print >>file, self.get_version()
1330ca
-
1330ca
-    def format_option_help(self, formatter=None):
1330ca
-        if formatter is None:
1330ca
-            formatter = self.formatter
1330ca
-        formatter.store_option_strings(self)
1330ca
-        result = []
1330ca
-        result.append(formatter.format_heading(_("Options")))
1330ca
-        formatter.indent()
1330ca
-        if self.option_list:
1330ca
-            result.append(OptionContainer.format_option_help(self, formatter))
1330ca
-            result.append("\n")
1330ca
-        for group in self.option_groups:
1330ca
-            result.append(group.format_help(formatter))
1330ca
-            result.append("\n")
1330ca
-        formatter.dedent()
1330ca
-        # Drop the last "\n", or the header if no options or option groups:
1330ca
-        return "".join(result[:-1])
1330ca
-
1330ca
-    def format_epilog(self, formatter):
1330ca
-        return formatter.format_epilog(self.epilog)
1330ca
-
1330ca
-    def format_help(self, formatter=None):
1330ca
-        if formatter is None:
1330ca
-            formatter = self.formatter
1330ca
-        result = []
1330ca
-        if self.usage:
1330ca
-            result.append(self.get_usage() + "\n")
1330ca
-        if self.description:
1330ca
-            result.append(self.format_description(formatter) + "\n")
1330ca
-        result.append(self.format_option_help(formatter))
1330ca
-        result.append(self.format_epilog(formatter))
1330ca
-        return "".join(result)
1330ca
-
1330ca
-    # used by test suite
1330ca
-    def _get_encoding(self, file):
1330ca
-        encoding = getattr(file, "encoding", None)
1330ca
-        if not encoding:
1330ca
-            encoding = sys.getdefaultencoding()
1330ca
-        return encoding
1330ca
-
1330ca
-    def print_help(self, file=None):
1330ca
-        """print_help(file : file = stdout)
1330ca
-
1330ca
-        Print an extended help message, listing all options and any
1330ca
-        help text provided with them, to 'file' (default stdout).
1330ca
-        """
1330ca
-        if file is None:
1330ca
-            file = sys.stdout
1330ca
-        encoding = self._get_encoding(file)
1330ca
-        file.write(self.format_help().encode(encoding, "replace"))
1330ca
-
1330ca
-# class OptionParser
1330ca
-
1330ca
-
1330ca
-def _match_abbrev(s, wordmap):
1330ca
-    """_match_abbrev(s : string, wordmap : {string : Option}) -> string
1330ca
-
1330ca
-    Return the string key in 'wordmap' for which 's' is an unambiguous
1330ca
-    abbreviation.  If 's' is found to be ambiguous or doesn't match any of
1330ca
-    'words', raise BadOptionError.
1330ca
-    """
1330ca
-    # Is there an exact match?
1330ca
-    if wordmap.has_key(s):
1330ca
-        return s
1330ca
-    else:
1330ca
-        # Isolate all words with s as a prefix.
1330ca
-        possibilities = [word for word in wordmap.keys()
1330ca
-                         if word.startswith(s)]
1330ca
-        # No exact match, so there had better be just one possibility.
1330ca
-        if len(possibilities) == 1:
1330ca
-            return possibilities[0]
1330ca
-        elif not possibilities:
1330ca
-            raise BadOptionError(s)
1330ca
-        else:
1330ca
-            # More than one possible completion: ambiguous prefix.
1330ca
-            possibilities.sort()
1330ca
-            raise AmbiguousOptionError(s, possibilities)
1330ca
-
1330ca
-
1330ca
-# Some day, there might be many Option classes.  As of Optik 1.3, the
1330ca
-# preferred way to instantiate Options is indirectly, via make_option(),
1330ca
-# which will become a factory function when there are many Option
1330ca
-# classes.
1330ca
-make_option = Option
1330ca
diff --git a/koan/register.py b/koan/register.py
1330ca
index 9924d85..871b8ac 100755
1330ca
--- a/koan/register.py
1330ca
+++ b/koan/register.py
1330ca
@@ -20,26 +20,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1330ca
 02110-1301  USA
1330ca
 """
1330ca
 
1330ca
-import random
1330ca
 import os
1330ca
 import traceback
1330ca
-try:
1330ca
-    from optparse import OptionParser
1330ca
-except:
1330ca
-    from opt_parse import OptionParser  # importing this for backwards compat with 2.2
1330ca
-try:
1330ca
-    import subprocess as sub_process
1330ca
-except:
1330ca
-    import sub_process
1330ca
+from optparse import OptionParser
1330ca
 import time
1330ca
-import errno
1330ca
 import sys
1330ca
 import xmlrpclib
1330ca
-import glob
1330ca
 import socket
1330ca
 import utils
1330ca
 import string
1330ca
-import pprint
1330ca
 
1330ca
 # usage: cobbler-register [--server=server] [--hostname=hostname] --profile=foo
1330ca
 
1330ca
diff --git a/koan/sub_process.py b/koan/sub_process.py
1330ca
deleted file mode 100644
1330ca
index bbd26c7..0000000
1330ca
--- a/koan/sub_process.py
1330ca
+++ /dev/null
1330ca
@@ -1,1149 +0,0 @@
1330ca
-# subprocess - Subprocesses with accessible I/O streams
1330ca
-#
1330ca
-# For more information about this module, see PEP 324.
1330ca
-#
1330ca
-# This module should remain compatible with Python 2.2, see PEP 291.
1330ca
-#
1330ca
-# Copyright (c) 2003-2005 by Peter Astrand <astrand@lysator.liu.se>
1330ca
-#
1330ca
-# Licensed to PSF under a Contributor Agreement.
1330ca
-# See http://www.python.org/2.4/license for licensing details.
1330ca
-
1330ca
-r"""subprocess - Subprocesses with accessible I/O streams
1330ca
-
1330ca
-This module allows you to spawn processes, connect to their
1330ca
-input/output/error pipes, and obtain their return codes.  This module
1330ca
-intends to replace several other, older modules and functions, like:
1330ca
-
1330ca
-os.system
1330ca
-os.spawn*
1330ca
-os.popen*
1330ca
-popen2.*
1330ca
-commands.*
1330ca
-
1330ca
-Information about how the subprocess module can be used to replace these
1330ca
-modules and functions can be found below.
1330ca
-
1330ca
-
1330ca
-
1330ca
-Using the subprocess module
1330ca
-===========================
1330ca
-This module defines one class called Popen:
1330ca
-
1330ca
-class Popen(args, bufsize=0, executable=None,
1330ca
-            stdin=None, stdout=None, stderr=None,
1330ca
-            preexec_fn=None, close_fds=False, shell=False,
1330ca
-            cwd=None, env=None, universal_newlines=False,
1330ca
-            startupinfo=None, creationflags=0):
1330ca
-
1330ca
-
1330ca
-Arguments are:
1330ca
-
1330ca
-args should be a string, or a sequence of program arguments.  The
1330ca
-program to execute is normally the first item in the args sequence or
1330ca
-string, but can be explicitly set by using the executable argument.
1330ca
-
1330ca
-On UNIX, with shell=False (default): In this case, the Popen class
1330ca
-uses os.execvp() to execute the child program.  args should normally
1330ca
-be a sequence.  A string will be treated as a sequence with the string
1330ca
-as the only item (the program to execute).
1330ca
-
1330ca
-On UNIX, with shell=True: If args is a string, it specifies the
1330ca
-command string to execute through the shell.  If args is a sequence,
1330ca
-the first item specifies the command string, and any additional items
1330ca
-will be treated as additional shell arguments.
1330ca
-
1330ca
-On Windows: the Popen class uses CreateProcess() to execute the child
1330ca
-program, which operates on strings.  If args is a sequence, it will be
1330ca
-converted to a string using the list2cmdline method.  Please note that
1330ca
-not all MS Windows applications interpret the command line the same
1330ca
-way: The list2cmdline is designed for applications using the same
1330ca
-rules as the MS C runtime.
1330ca
-
1330ca
-bufsize, if given, has the same meaning as the corresponding argument
1330ca
-to the built-in open() function: 0 means unbuffered, 1 means line
1330ca
-buffered, any other positive value means use a buffer of
1330ca
-(approximately) that size.  A negative bufsize means to use the system
1330ca
-default, which usually means fully buffered.  The default value for
1330ca
-bufsize is 0 (unbuffered).
1330ca
-
1330ca
-stdin, stdout and stderr specify the executed programs' standard
1330ca
-input, standard output and standard error file handles, respectively.
1330ca
-Valid values are PIPE, an existing file descriptor (a positive
1330ca
-integer), an existing file object, and None.  PIPE indicates that a
1330ca
-new pipe to the child should be created.  With None, no redirection
1330ca
-will occur; the child's file handles will be inherited from the
1330ca
-parent.  Additionally, stderr can be STDOUT, which indicates that the
1330ca
-stderr data from the applications should be captured into the same
1330ca
-file handle as for stdout.
1330ca
-
1330ca
-If preexec_fn is set to a callable object, this object will be called
1330ca
-in the child process just before the child is executed.
1330ca
-
1330ca
-If close_fds is true, all file descriptors except 0, 1 and 2 will be
1330ca
-closed before the child process is executed.
1330ca
-
1330ca
-if shell is true, the specified command will be executed through the
1330ca
-shell.
1330ca
-
1330ca
-If cwd is not None, the current directory will be changed to cwd
1330ca
-before the child is executed.
1330ca
-
1330ca
-If env is not None, it defines the environment variables for the new
1330ca
-process.
1330ca
-
1330ca
-If universal_newlines is true, the file objects stdout and stderr are
1330ca
-opened as a text files, but lines may be terminated by any of '\n',
1330ca
-the Unix end-of-line convention, '\r', the Macintosh convention or
1330ca
-'\r\n', the Windows convention.  All of these external representations
1330ca
-are seen as '\n' by the Python program.  Note: This feature is only
1330ca
-available if Python is built with universal newline support (the
1330ca
-default).  Also, the newlines attribute of the file objects stdout,
1330ca
-stdin and stderr are not updated by the communicate() method.
1330ca
-
1330ca
-The startupinfo and creationflags, if given, will be passed to the
1330ca
-underlying CreateProcess() function.  They can specify things such as
1330ca
-appearance of the main window and priority for the new process.
1330ca
-(Windows only)
1330ca
-
1330ca
-
1330ca
-This module also defines two shortcut functions:
1330ca
-
1330ca
-call(*args, **kwargs):
1330ca
-    Run command with arguments.  Wait for command to complete, then
1330ca
-    return the returncode attribute.
1330ca
-
1330ca
-    The arguments are the same as for the Popen constructor.  Example:
1330ca
-
1330ca
-    retcode = call(["ls", "-l"])
1330ca
-
1330ca
-
1330ca
-Exceptions
1330ca
-----------
1330ca
-Exceptions raised in the child process, before the new program has
1330ca
-started to execute, will be re-raised in the parent.  Additionally,
1330ca
-the exception object will have one extra attribute called
1330ca
-'child_traceback', which is a string containing traceback information
1330ca
-from the childs point of view.
1330ca
-
1330ca
-The most common exception raised is OSError.  This occurs, for
1330ca
-example, when trying to execute a non-existent file.  Applications
1330ca
-should prepare for OSErrors.
1330ca
-
1330ca
-A ValueError will be raised if Popen is called with invalid arguments.
1330ca
-
1330ca
-
1330ca
-Security
1330ca
---------
1330ca
-Unlike some other popen functions, this implementation will never call
1330ca
-/bin/sh implicitly.  This means that all characters, including shell
1330ca
-metacharacters, can safely be passed to child processes.
1330ca
-
1330ca
-
1330ca
-Popen objects
1330ca
-=============
1330ca
-Instances of the Popen class have the following methods:
1330ca
-
1330ca
-poll()
1330ca
-    Check if child process has terminated.  Returns returncode
1330ca
-    attribute.
1330ca
-
1330ca
-wait()
1330ca
-    Wait for child process to terminate.  Returns returncode attribute.
1330ca
-
1330ca
-communicate(input=None)
1330ca
-    Interact with process: Send data to stdin.  Read data from stdout
1330ca
-    and stderr, until end-of-file is reached.  Wait for process to
1330ca
-    terminate.  The optional stdin argument should be a string to be
1330ca
-    sent to the child process, or None, if no data should be sent to
1330ca
-    the child.
1330ca
-
1330ca
-    communicate() returns a tuple (stdout, stderr).
1330ca
-
1330ca
-    Note: The data read is buffered in memory, so do not use this
1330ca
-    method if the data size is large or unlimited.
1330ca
-
1330ca
-The following attributes are also available:
1330ca
-
1330ca
-stdin
1330ca
-    If the stdin argument is PIPE, this attribute is a file object
1330ca
-    that provides input to the child process.  Otherwise, it is None.
1330ca
-
1330ca
-stdout
1330ca
-    If the stdout argument is PIPE, this attribute is a file object
1330ca
-    that provides output from the child process.  Otherwise, it is
1330ca
-    None.
1330ca
-
1330ca
-stderr
1330ca
-    If the stderr argument is PIPE, this attribute is file object that
1330ca
-    provides error output from the child process.  Otherwise, it is
1330ca
-    None.
1330ca
-
1330ca
-pid
1330ca
-    The process ID of the child process.
1330ca
-
1330ca
-returncode
1330ca
-    The child return code.  A None value indicates that the process
1330ca
-    hasn't terminated yet.  A negative value -N indicates that the
1330ca
-    child was terminated by signal N (UNIX only).
1330ca
-
1330ca
-
1330ca
-Replacing older functions with the subprocess module
1330ca
-====================================================
1330ca
-In this section, "a ==> b" means that b can be used as a replacement
1330ca
-for a.
1330ca
-
1330ca
-Note: All functions in this section fail (more or less) silently if
1330ca
-the executed program cannot be found; this module raises an OSError
1330ca
-exception.
1330ca
-
1330ca
-In the following examples, we assume that the subprocess module is
1330ca
-imported with "from subprocess import *".
1330ca
-
1330ca
-
1330ca
-Replacing /bin/sh shell backquote
1330ca
----------------------------------
1330ca
-output=`mycmd myarg`
1330ca
-==>
1330ca
-output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
1330ca
-
1330ca
-
1330ca
-Replacing shell pipe line
1330ca
--------------------------
1330ca
-output=`dmesg | grep hda`
1330ca
-==>
1330ca
-p1 = Popen(["dmesg"], stdout=PIPE)
1330ca
-p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
1330ca
-output = p2.communicate()[0]
1330ca
-
1330ca
-
1330ca
-Replacing os.system()
1330ca
----------------------
1330ca
-sts = os.system("mycmd" + " myarg")
1330ca
-==>
1330ca
-p = Popen("mycmd" + " myarg", shell=True)
1330ca
-sts = os.waitpid(p.pid, 0)
1330ca
-
1330ca
-Note:
1330ca
-
1330ca
-* Calling the program through the shell is usually not required.
1330ca
-
1330ca
-* It's easier to look at the returncode attribute than the
1330ca
-  exitstatus.
1330ca
-
1330ca
-A more real-world example would look like this:
1330ca
-
1330ca
-try:
1330ca
-    retcode = call("mycmd" + " myarg", shell=True)
1330ca
-    if retcode < 0:
1330ca
-        print >>sys.stderr, "Child was terminated by signal", -retcode
1330ca
-    else:
1330ca
-        print >>sys.stderr, "Child returned", retcode
1330ca
-except OSError, e:
1330ca
-    print >>sys.stderr, "Execution failed:", e
1330ca
-
1330ca
-
1330ca
-Replacing os.spawn*
1330ca
--------------------
1330ca
-P_NOWAIT example:
1330ca
-
1330ca
-pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
1330ca
-==>
1330ca
-pid = Popen(["/bin/mycmd", "myarg"]).pid
1330ca
-
1330ca
-
1330ca
-P_WAIT example:
1330ca
-
1330ca
-retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
1330ca
-==>
1330ca
-retcode = call(["/bin/mycmd", "myarg"])
1330ca
-
1330ca
-
1330ca
-Vector example:
1330ca
-
1330ca
-os.spawnvp(os.P_NOWAIT, path, args)
1330ca
-==>
1330ca
-Popen([path] + args[1:])
1330ca
-
1330ca
-
1330ca
-Environment example:
1330ca
-
1330ca
-os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
1330ca
-==>
1330ca
-Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
1330ca
-
1330ca
-
1330ca
-Replacing os.popen*
1330ca
--------------------
1330ca
-pipe = os.popen(cmd, mode='r', bufsize)
1330ca
-==>
1330ca
-pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
1330ca
-
1330ca
-pipe = os.popen(cmd, mode='w', bufsize)
1330ca
-==>
1330ca
-pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
1330ca
-
1330ca
-
1330ca
-(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
1330ca
-==>
1330ca
-p = Popen(cmd, shell=True, bufsize=bufsize,
1330ca
-          stdin=PIPE, stdout=PIPE, close_fds=True)
1330ca
-(child_stdin, child_stdout) = (p.stdin, p.stdout)
1330ca
-
1330ca
-
1330ca
-(child_stdin,
1330ca
- child_stdout,
1330ca
- child_stderr) = os.popen3(cmd, mode, bufsize)
1330ca
-==>
1330ca
-p = Popen(cmd, shell=True, bufsize=bufsize,
1330ca
-          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
1330ca
-(child_stdin,
1330ca
- child_stdout,
1330ca
- child_stderr) = (p.stdin, p.stdout, p.stderr)
1330ca
-
1330ca
-
1330ca
-(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
1330ca
-==>
1330ca
-p = Popen(cmd, shell=True, bufsize=bufsize,
1330ca
-          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
1330ca
-(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
1330ca
-
1330ca
-
1330ca
-Replacing popen2.*
1330ca
-------------------
1330ca
-Note: If the cmd argument to popen2 functions is a string, the command
1330ca
-is executed through /bin/sh.  If it is a list, the command is directly
1330ca
-executed.
1330ca
-
1330ca
-(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
1330ca
-==>
1330ca
-p = Popen(["somestring"], shell=True, bufsize=bufsize
1330ca
-          stdin=PIPE, stdout=PIPE, close_fds=True)
1330ca
-(child_stdout, child_stdin) = (p.stdout, p.stdin)
1330ca
-
1330ca
-
1330ca
-(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
1330ca
-==>
1330ca
-p = Popen(["mycmd", "myarg"], bufsize=bufsize,
1330ca
-          stdin=PIPE, stdout=PIPE, close_fds=True)
1330ca
-(child_stdout, child_stdin) = (p.stdout, p.stdin)
1330ca
-
1330ca
-The popen2.Popen3 and popen3.Popen4 basically works as subprocess.Popen,
1330ca
-except that:
1330ca
-
1330ca
-* subprocess.Popen raises an exception if the execution fails
1330ca
-* the capturestderr argument is replaced with the stderr argument.
1330ca
-* stdin=PIPE and stdout=PIPE must be specified.
1330ca
-* popen2 closes all filedescriptors by default, but you have to specify
1330ca
-  close_fds=True with subprocess.Popen.
1330ca
-
1330ca
-
1330ca
-"""
1330ca
-
1330ca
-import sys
1330ca
-mswindows = (sys.platform == "win32")
1330ca
-
1330ca
-import os
1330ca
-import types
1330ca
-import traceback
1330ca
-
1330ca
-if mswindows:
1330ca
-    import threading
1330ca
-    import msvcrt
1330ca
-    if 0: # <-- change this to use pywin32 instead of the _subprocess driver
1330ca
-        import pywintypes
1330ca
-        from win32api import GetStdHandle, STD_INPUT_HANDLE, \
1330ca
-                             STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
1330ca
-        from win32api import GetCurrentProcess, DuplicateHandle, \
1330ca
-                             GetModuleFileName, GetVersion
1330ca
-        from win32con import DUPLICATE_SAME_ACCESS, SW_HIDE
1330ca
-        from win32pipe import CreatePipe
1330ca
-        from win32process import CreateProcess, STARTUPINFO, \
1330ca
-                                 GetExitCodeProcess, STARTF_USESTDHANDLES, \
1330ca
-                                 STARTF_USESHOWWINDOW, CREATE_NEW_CONSOLE
1330ca
-        from win32event import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
1330ca
-    else:
1330ca
-        from _subprocess import *
1330ca
-        class STARTUPINFO:
1330ca
-            dwFlags = 0
1330ca
-            hStdInput = None
1330ca
-            hStdOutput = None
1330ca
-            hStdError = None
1330ca
-        class pywintypes:
1330ca
-            error = IOError
1330ca
-else:
1330ca
-    import select
1330ca
-    import errno
1330ca
-    import fcntl
1330ca
-    import pickle
1330ca
-
1330ca
-__all__ = ["Popen", "PIPE", "STDOUT", "call"]
1330ca
-
1330ca
-try:
1330ca
-    MAXFD = os.sysconf("SC_OPEN_MAX")
1330ca
-except:
1330ca
-    MAXFD = 256
1330ca
-
1330ca
-# True/False does not exist on 2.2.0
1330ca
-try:
1330ca
-    False
1330ca
-except NameError:
1330ca
-    False = 0
1330ca
-    True = 1
1330ca
-
1330ca
-_active = []
1330ca
-
1330ca
-def _cleanup():
1330ca
-    for inst in _active[:]:
1330ca
-        inst.poll()
1330ca
-
1330ca
-PIPE = -1
1330ca
-STDOUT = -2
1330ca
-
1330ca
-
1330ca
-def call(*args, **kwargs):
1330ca
-    """Run command with arguments.  Wait for command to complete, then
1330ca
-    return the returncode attribute.
1330ca
-
1330ca
-    The arguments are the same as for the Popen constructor.  Example:
1330ca
-
1330ca
-    retcode = call(["ls", "-l"])
1330ca
-    """
1330ca
-    return Popen(*args, **kwargs).wait()
1330ca
-
1330ca
-
1330ca
-def list2cmdline(seq):
1330ca
-    """
1330ca
-    Translate a sequence of arguments into a command line
1330ca
-    string, using the same rules as the MS C runtime:
1330ca
-
1330ca
-    1) Arguments are delimited by white space, which is either a
1330ca
-       space or a tab.
1330ca
-
1330ca
-    2) A string surrounded by double quotation marks is
1330ca
-       interpreted as a single argument, regardless of white space
1330ca
-       contained within.  A quoted string can be embedded in an
1330ca
-       argument.
1330ca
-
1330ca
-    3) A double quotation mark preceded by a backslash is
1330ca
-       interpreted as a literal double quotation mark.
1330ca
-
1330ca
-    4) Backslashes are interpreted literally, unless they
1330ca
-       immediately precede a double quotation mark.
1330ca
-
1330ca
-    5) If backslashes immediately precede a double quotation mark,
1330ca
-       every pair of backslashes is interpreted as a literal
1330ca
-       backslash.  If the number of backslashes is odd, the last
1330ca
-       backslash escapes the next double quotation mark as
1330ca
-       described in rule 3.
1330ca
-    """
1330ca
-
1330ca
-    # See
1330ca
-    # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp
1330ca
-    result = []
1330ca
-    needquote = False
1330ca
-    for arg in seq:
1330ca
-        bs_buf = []
1330ca
-
1330ca
-        # Add a space to separate this argument from the others
1330ca
-        if result:
1330ca
-            result.append(' ')
1330ca
-
1330ca
-        needquote = (" " in arg) or ("\t" in arg)
1330ca
-        if needquote:
1330ca
-            result.append('"')
1330ca
-
1330ca
-        for c in arg:
1330ca
-            if c == '\\':
1330ca
-                # Don't know if we need to double yet.
1330ca
-                bs_buf.append(c)
1330ca
-            elif c == '"':
1330ca
-                # Double backspaces.
1330ca
-                result.append('\\' * len(bs_buf)*2)
1330ca
-                bs_buf = []
1330ca
-                result.append('\\"')
1330ca
-            else:
1330ca
-                # Normal char
1330ca
-                if bs_buf:
1330ca
-                    result.extend(bs_buf)
1330ca
-                    bs_buf = []
1330ca
-                result.append(c)
1330ca
-
1330ca
-        # Add remaining backspaces, if any.
1330ca
-        if bs_buf:
1330ca
-            result.extend(bs_buf)
1330ca
-
1330ca
-        if needquote:
1330ca
-            result.extend(bs_buf)
1330ca
-            result.append('"')
1330ca
-
1330ca
-    return ''.join(result)
1330ca
-
1330ca
-
1330ca
-class Popen(object):
1330ca
-    def __init__(self, args, bufsize=0, executable=None,
1330ca
-                 stdin=None, stdout=None, stderr=None,
1330ca
-                 preexec_fn=None, close_fds=False, shell=False,
1330ca
-                 cwd=None, env=None, universal_newlines=False,
1330ca
-                 startupinfo=None, creationflags=0):
1330ca
-        """Create new Popen instance."""
1330ca
-        _cleanup()
1330ca
-
1330ca
-        if not isinstance(bufsize, (int, long)):
1330ca
-            raise TypeError("bufsize must be an integer")
1330ca
-
1330ca
-        if mswindows:
1330ca
-            if preexec_fn is not None:
1330ca
-                raise ValueError("preexec_fn is not supported on Windows "
1330ca
-                                 "platforms")
1330ca
-            if close_fds:
1330ca
-                raise ValueError("close_fds is not supported on Windows "
1330ca
-                                 "platforms")
1330ca
-        else:
1330ca
-            # POSIX
1330ca
-            if startupinfo is not None:
1330ca
-                raise ValueError("startupinfo is only supported on Windows "
1330ca
-                                 "platforms")
1330ca
-            if creationflags != 0:
1330ca
-                raise ValueError("creationflags is only supported on Windows "
1330ca
-                                 "platforms")
1330ca
-
1330ca
-        self.stdin = None
1330ca
-        self.stdout = None
1330ca
-        self.stderr = None
1330ca
-        self.pid = None
1330ca
-        self.returncode = None
1330ca
-        self.universal_newlines = universal_newlines
1330ca
-
1330ca
-        # Input and output objects. The general principle is like
1330ca
-        # this:
1330ca
-        #
1330ca
-        # Parent                   Child
1330ca
-        # ------                   -----
1330ca
-        # p2cwrite   ---stdin--->  p2cread
1330ca
-        # c2pread    <--stdout---  c2pwrite
1330ca
-        # errread    <--stderr---  errwrite
1330ca
-        #
1330ca
-        # On POSIX, the child objects are file descriptors.  On
1330ca
-        # Windows, these are Windows file handles.  The parent objects
1330ca
-        # are file descriptors on both platforms.  The parent objects
1330ca
-        # are None when not using PIPEs. The child objects are None
1330ca
-        # when not redirecting.
1330ca
-
1330ca
-        (p2cread, p2cwrite,
1330ca
-         c2pread, c2pwrite,
1330ca
-         errread, errwrite) = self._get_handles(stdin, stdout, stderr)
1330ca
-
1330ca
-        self._execute_child(args, executable, preexec_fn, close_fds,
1330ca
-                            cwd, env, universal_newlines,
1330ca
-                            startupinfo, creationflags, shell,
1330ca
-                            p2cread, p2cwrite,
1330ca
-                            c2pread, c2pwrite,
1330ca
-                            errread, errwrite)
1330ca
-
1330ca
-        if p2cwrite:
1330ca
-            self.stdin = os.fdopen(p2cwrite, 'wb', bufsize)
1330ca
-        if c2pread:
1330ca
-            if universal_newlines:
1330ca
-                self.stdout = os.fdopen(c2pread, 'rU', bufsize)
1330ca
-            else:
1330ca
-                self.stdout = os.fdopen(c2pread, 'rb', bufsize)
1330ca
-        if errread:
1330ca
-            if universal_newlines:
1330ca
-                self.stderr = os.fdopen(errread, 'rU', bufsize)
1330ca
-            else:
1330ca
-                self.stderr = os.fdopen(errread, 'rb', bufsize)
1330ca
-
1330ca
-        _active.append(self)
1330ca
-
1330ca
-
1330ca
-    def _translate_newlines(self, data):
1330ca
-        data = data.replace("\r\n", "\n")
1330ca
-        data = data.replace("\r", "\n")
1330ca
-        return data
1330ca
-
1330ca
-
1330ca
-    if mswindows:
1330ca
-        #
1330ca
-        # Windows methods
1330ca
-        #
1330ca
-        def _get_handles(self, stdin, stdout, stderr):
1330ca
-            """Construct and return tupel with IO objects:
1330ca
-            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
1330ca
-            """
1330ca
-            if stdin == None and stdout == None and stderr == None:
1330ca
-                return (None, None, None, None, None, None)
1330ca
-
1330ca
-            p2cread, p2cwrite = None, None
1330ca
-            c2pread, c2pwrite = None, None
1330ca
-            errread, errwrite = None, None
1330ca
-
1330ca
-            if stdin == None:
1330ca
-                p2cread = GetStdHandle(STD_INPUT_HANDLE)
1330ca
-            elif stdin == PIPE:
1330ca
-                p2cread, p2cwrite = CreatePipe(None, 0)
1330ca
-                # Detach and turn into fd
1330ca
-                p2cwrite = p2cwrite.Detach()
1330ca
-                p2cwrite = msvcrt.open_osfhandle(p2cwrite, 0)
1330ca
-            elif type(stdin) == types.IntType:
1330ca
-                p2cread = msvcrt.get_osfhandle(stdin)
1330ca
-            else:
1330ca
-                # Assuming file-like object
1330ca
-                p2cread = msvcrt.get_osfhandle(stdin.fileno())
1330ca
-            p2cread = self._make_inheritable(p2cread)
1330ca
-
1330ca
-            if stdout == None:
1330ca
-                c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE)
1330ca
-            elif stdout == PIPE:
1330ca
-                c2pread, c2pwrite = CreatePipe(None, 0)
1330ca
-                # Detach and turn into fd
1330ca
-                c2pread = c2pread.Detach()
1330ca
-                c2pread = msvcrt.open_osfhandle(c2pread, 0)
1330ca
-            elif type(stdout) == types.IntType:
1330ca
-                c2pwrite = msvcrt.get_osfhandle(stdout)
1330ca
-            else:
1330ca
-                # Assuming file-like object
1330ca
-                c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
1330ca
-            c2pwrite = self._make_inheritable(c2pwrite)
1330ca
-
1330ca
-            if stderr == None:
1330ca
-                errwrite = GetStdHandle(STD_ERROR_HANDLE)
1330ca
-            elif stderr == PIPE:
1330ca
-                errread, errwrite = CreatePipe(None, 0)
1330ca
-                # Detach and turn into fd
1330ca
-                errread = errread.Detach()
1330ca
-                errread = msvcrt.open_osfhandle(errread, 0)
1330ca
-            elif stderr == STDOUT:
1330ca
-                errwrite = c2pwrite
1330ca
-            elif type(stderr) == types.IntType:
1330ca
-                errwrite = msvcrt.get_osfhandle(stderr)
1330ca
-            else:
1330ca
-                # Assuming file-like object
1330ca
-                errwrite = msvcrt.get_osfhandle(stderr.fileno())
1330ca
-            errwrite = self._make_inheritable(errwrite)
1330ca
-
1330ca
-            return (p2cread, p2cwrite,
1330ca
-                    c2pread, c2pwrite,
1330ca
-                    errread, errwrite)
1330ca
-
1330ca
-
1330ca
-        def _make_inheritable(self, handle):
1330ca
-            """Return a duplicate of handle, which is inheritable"""
1330ca
-            return DuplicateHandle(GetCurrentProcess(), handle,
1330ca
-                                   GetCurrentProcess(), 0, 1,
1330ca
-                                   DUPLICATE_SAME_ACCESS)
1330ca
-
1330ca
-
1330ca
-        def _find_w9xpopen(self):
1330ca
-            """Find and return absolut path to w9xpopen.exe"""
1330ca
-            w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
1330ca
-                                    "w9xpopen.exe")
1330ca
-            if not os.path.exists(w9xpopen):
1330ca
-                # Eeek - file-not-found - possibly an embedding
1330ca
-                # situation - see if we can locate it in sys.exec_prefix
1330ca
-                w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix),
1330ca
-                                        "w9xpopen.exe")
1330ca
-                if not os.path.exists(w9xpopen):
1330ca
-                    raise RuntimeError("Cannot locate w9xpopen.exe, which is "
1330ca
-                                       "needed for Popen to work with your "
1330ca
-                                       "shell or platform.")
1330ca
-            return w9xpopen
1330ca
-
1330ca
-
1330ca
-        def _execute_child(self, args, executable, preexec_fn, close_fds,
1330ca
-                           cwd, env, universal_newlines,
1330ca
-                           startupinfo, creationflags, shell,
1330ca
-                           p2cread, p2cwrite,
1330ca
-                           c2pread, c2pwrite,
1330ca
-                           errread, errwrite):
1330ca
-            """Execute program (MS Windows version)"""
1330ca
-
1330ca
-            if not isinstance(args, types.StringTypes):
1330ca
-                args = list2cmdline(args)
1330ca
-
1330ca
-            # Process startup details
1330ca
-            default_startupinfo = STARTUPINFO()
1330ca
-            if startupinfo == None:
1330ca
-                startupinfo = default_startupinfo
1330ca
-            if not None in (p2cread, c2pwrite, errwrite):
1330ca
-                startupinfo.dwFlags |= STARTF_USESTDHANDLES
1330ca
-                startupinfo.hStdInput = p2cread
1330ca
-                startupinfo.hStdOutput = c2pwrite
1330ca
-                startupinfo.hStdError = errwrite
1330ca
-
1330ca
-            if shell:
1330ca
-                default_startupinfo.dwFlags |= STARTF_USESHOWWINDOW
1330ca
-                default_startupinfo.wShowWindow = SW_HIDE
1330ca
-                comspec = os.environ.get("COMSPEC", "cmd.exe")
1330ca
-                args = comspec + " /c " + args
1330ca
-                if (GetVersion() >= 0x80000000L or
1330ca
-                        os.path.basename(comspec).lower() == "command.com"):
1330ca
-                    # Win9x, or using command.com on NT. We need to
1330ca
-                    # use the w9xpopen intermediate program. For more
1330ca
-                    # information, see KB Q150956
1330ca
-                    # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp)
1330ca
-                    w9xpopen = self._find_w9xpopen()
1330ca
-                    args = '"%s" %s' % (w9xpopen, args)
1330ca
-                    # Not passing CREATE_NEW_CONSOLE has been known to
1330ca
-                    # cause random failures on win9x.  Specifically a
1330ca
-                    # dialog: "Your program accessed mem currently in
1330ca
-                    # use at xxx" and a hopeful warning about the
1330ca
-                    # stability of your system.  Cost is Ctrl+C wont
1330ca
-                    # kill children.
1330ca
-                    creationflags |= CREATE_NEW_CONSOLE
1330ca
-
1330ca
-            # Start the process
1330ca
-            try:
1330ca
-                hp, ht, pid, tid = CreateProcess(executable, args,
1330ca
-                                         # no special security
1330ca
-                                         None, None,
1330ca
-                                         # must inherit handles to pass std
1330ca
-                                         # handles
1330ca
-                                         1,
1330ca
-                                         creationflags,
1330ca
-                                         env,
1330ca
-                                         cwd,
1330ca
-                                         startupinfo)
1330ca
-            except pywintypes.error, e:
1330ca
-                # Translate pywintypes.error to WindowsError, which is
1330ca
-                # a subclass of OSError.  FIXME: We should really
1330ca
-                # translate errno using _sys_errlist (or simliar), but
1330ca
-                # how can this be done from Python?
1330ca
-                raise WindowsError(*e.args)
1330ca
-
1330ca
-            # Retain the process handle, but close the thread handle
1330ca
-            self._handle = hp
1330ca
-            self.pid = pid
1330ca
-            ht.Close()
1330ca
-
1330ca
-            # Child is launched. Close the parent's copy of those pipe
1330ca
-            # handles that only the child should have open.  You need
1330ca
-            # to make sure that no handles to the write end of the
1330ca
-            # output pipe are maintained in this process or else the
1330ca
-            # pipe will not close when the child process exits and the
1330ca
-            # ReadFile will hang.
1330ca
-            if p2cread != None:
1330ca
-                p2cread.Close()
1330ca
-            if c2pwrite != None:
1330ca
-                c2pwrite.Close()
1330ca
-            if errwrite != None:
1330ca
-                errwrite.Close()
1330ca
-
1330ca
-
1330ca
-        def poll(self):
1330ca
-            """Check if child process has terminated.  Returns returncode
1330ca
-            attribute."""
1330ca
-            if self.returncode == None:
1330ca
-                if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0:
1330ca
-                    self.returncode = GetExitCodeProcess(self._handle)
1330ca
-                    _active.remove(self)
1330ca
-            return self.returncode
1330ca
-
1330ca
-
1330ca
-        def wait(self):
1330ca
-            """Wait for child process to terminate.  Returns returncode
1330ca
-            attribute."""
1330ca
-            if self.returncode == None:
1330ca
-                obj = WaitForSingleObject(self._handle, INFINITE)
1330ca
-                self.returncode = GetExitCodeProcess(self._handle)
1330ca
-                _active.remove(self)
1330ca
-            return self.returncode
1330ca
-
1330ca
-
1330ca
-        def _readerthread(self, fh, buffer):
1330ca
-            buffer.append(fh.read())
1330ca
-
1330ca
-
1330ca
-        def communicate(self, input=None):
1330ca
-            """Interact with process: Send data to stdin.  Read data from
1330ca
-            stdout and stderr, until end-of-file is reached.  Wait for
1330ca
-            process to terminate.  The optional input argument should be a
1330ca
-            string to be sent to the child process, or None, if no data
1330ca
-            should be sent to the child.
1330ca
-
1330ca
-            communicate() returns a tuple (stdout, stderr)."""
1330ca
-            stdout = None # Return
1330ca
-            stderr = None # Return
1330ca
-
1330ca
-            if self.stdout:
1330ca
-                stdout = []
1330ca
-                stdout_thread = threading.Thread(target=self._readerthread,
1330ca
-                                                 args=(self.stdout, stdout))
1330ca
-                stdout_thread.setDaemon(True)
1330ca
-                stdout_thread.start()
1330ca
-            if self.stderr:
1330ca
-                stderr = []
1330ca
-                stderr_thread = threading.Thread(target=self._readerthread,
1330ca
-                                                 args=(self.stderr, stderr))
1330ca
-                stderr_thread.setDaemon(True)
1330ca
-                stderr_thread.start()
1330ca
-
1330ca
-            if self.stdin:
1330ca
-                if input != None:
1330ca
-                    self.stdin.write(input)
1330ca
-                self.stdin.close()
1330ca
-
1330ca
-            if self.stdout:
1330ca
-                stdout_thread.join()
1330ca
-            if self.stderr:
1330ca
-                stderr_thread.join()
1330ca
-
1330ca
-            # All data exchanged.  Translate lists into strings.
1330ca
-            if stdout != None:
1330ca
-                stdout = stdout[0]
1330ca
-            if stderr != None:
1330ca
-                stderr = stderr[0]
1330ca
-
1330ca
-            # Translate newlines, if requested.  We cannot let the file
1330ca
-            # object do the translation: It is based on stdio, which is
1330ca
-            # impossible to combine with select (unless forcing no
1330ca
-            # buffering).
1330ca
-            if self.universal_newlines and hasattr(open, 'newlines'):
1330ca
-                if stdout:
1330ca
-                    stdout = self._translate_newlines(stdout)
1330ca
-                if stderr:
1330ca
-                    stderr = self._translate_newlines(stderr)
1330ca
-
1330ca
-            self.wait()
1330ca
-            return (stdout, stderr)
1330ca
-
1330ca
-    else:
1330ca
-        #
1330ca
-        # POSIX methods
1330ca
-        #
1330ca
-        def _get_handles(self, stdin, stdout, stderr):
1330ca
-            """Construct and return tupel with IO objects:
1330ca
-            p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
1330ca
-            """
1330ca
-            p2cread, p2cwrite = None, None
1330ca
-            c2pread, c2pwrite = None, None
1330ca
-            errread, errwrite = None, None
1330ca
-
1330ca
-            if stdin == None:
1330ca
-                pass
1330ca
-            elif stdin == PIPE:
1330ca
-                p2cread, p2cwrite = os.pipe()
1330ca
-            elif type(stdin) == types.IntType:
1330ca
-                p2cread = stdin
1330ca
-            else:
1330ca
-                # Assuming file-like object
1330ca
-                p2cread = stdin.fileno()
1330ca
-
1330ca
-            if stdout == None:
1330ca
-                pass
1330ca
-            elif stdout == PIPE:
1330ca
-                c2pread, c2pwrite = os.pipe()
1330ca
-            elif type(stdout) == types.IntType:
1330ca
-                c2pwrite = stdout
1330ca
-            else:
1330ca
-                # Assuming file-like object
1330ca
-                c2pwrite = stdout.fileno()
1330ca
-
1330ca
-            if stderr == None:
1330ca
-                pass
1330ca
-            elif stderr == PIPE:
1330ca
-                errread, errwrite = os.pipe()
1330ca
-            elif stderr == STDOUT:
1330ca
-                errwrite = c2pwrite
1330ca
-            elif type(stderr) == types.IntType:
1330ca
-                errwrite = stderr
1330ca
-            else:
1330ca
-                # Assuming file-like object
1330ca
-                errwrite = stderr.fileno()
1330ca
-
1330ca
-            return (p2cread, p2cwrite,
1330ca
-                    c2pread, c2pwrite,
1330ca
-                    errread, errwrite)
1330ca
-
1330ca
-
1330ca
-        def _set_cloexec_flag(self, fd):
1330ca
-            try:
1330ca
-                cloexec_flag = fcntl.FD_CLOEXEC
1330ca
-            except AttributeError:
1330ca
-                cloexec_flag = 1
1330ca
-
1330ca
-            old = fcntl.fcntl(fd, fcntl.F_GETFD)
1330ca
-            fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag)
1330ca
-
1330ca
-
1330ca
-        def _close_fds(self, but):
1330ca
-            for i in range(3, MAXFD):
1330ca
-                if i == but:
1330ca
-                    continue
1330ca
-                try:
1330ca
-                    os.close(i)
1330ca
-                except:
1330ca
-                    pass
1330ca
-
1330ca
-
1330ca
-        def _execute_child(self, args, executable, preexec_fn, close_fds,
1330ca
-                           cwd, env, universal_newlines,
1330ca
-                           startupinfo, creationflags, shell,
1330ca
-                           p2cread, p2cwrite,
1330ca
-                           c2pread, c2pwrite,
1330ca
-                           errread, errwrite):
1330ca
-            """Execute program (POSIX version)"""
1330ca
-
1330ca
-            if isinstance(args, types.StringTypes):
1330ca
-                args = [args]
1330ca
-
1330ca
-            if shell:
1330ca
-                args = ["/bin/sh", "-c"] + args
1330ca
-
1330ca
-            if executable == None:
1330ca
-                executable = args[0]
1330ca
-
1330ca
-            # For transferring possible exec failure from child to parent
1330ca
-            # The first char specifies the exception type: 0 means
1330ca
-            # OSError, 1 means some other error.
1330ca
-            errpipe_read, errpipe_write = os.pipe()
1330ca
-            self._set_cloexec_flag(errpipe_write)
1330ca
-
1330ca
-            self.pid = os.fork()
1330ca
-            if self.pid == 0:
1330ca
-                # Child
1330ca
-                try:
1330ca
-                    # Close parent's pipe ends
1330ca
-                    if p2cwrite:
1330ca
-                        os.close(p2cwrite)
1330ca
-                    if c2pread:
1330ca
-                        os.close(c2pread)
1330ca
-                    if errread:
1330ca
-                        os.close(errread)
1330ca
-                    os.close(errpipe_read)
1330ca
-
1330ca
-                    # Dup fds for child
1330ca
-                    if p2cread:
1330ca
-                        os.dup2(p2cread, 0)
1330ca
-                    if c2pwrite:
1330ca
-                        os.dup2(c2pwrite, 1)
1330ca
-                    if errwrite:
1330ca
-                        os.dup2(errwrite, 2)
1330ca
-
1330ca
-                    # Close pipe fds.  Make sure we doesn't close the same
1330ca
-                    # fd more than once.
1330ca
-                    if p2cread:
1330ca
-                        os.close(p2cread)
1330ca
-                    if c2pwrite and c2pwrite not in (p2cread,):
1330ca
-                        os.close(c2pwrite)
1330ca
-                    if errwrite and errwrite not in (p2cread, c2pwrite):
1330ca
-                        os.close(errwrite)
1330ca
-
1330ca
-                    # Close all other fds, if asked for
1330ca
-                    if close_fds:
1330ca
-                        self._close_fds(but=errpipe_write)
1330ca
-
1330ca
-                    if cwd != None:
1330ca
-                        os.chdir(cwd)
1330ca
-
1330ca
-                    if preexec_fn:
1330ca
-                        apply(preexec_fn)
1330ca
-
1330ca
-                    if env == None:
1330ca
-                        os.execvp(executable, args)
1330ca
-                    else:
1330ca
-                        os.execvpe(executable, args, env)
1330ca
-
1330ca
-                except:
1330ca
-                    exc_type, exc_value, tb = sys.exc_info()
1330ca
-                    # Save the traceback and attach it to the exception object
1330ca
-                    exc_lines = traceback.format_exception(exc_type,
1330ca
-                                                           exc_value,
1330ca
-                                                           tb)
1330ca
-                    exc_value.child_traceback = ''.join(exc_lines)
1330ca
-                    os.write(errpipe_write, pickle.dumps(exc_value))
1330ca
-
1330ca
-                # This exitcode won't be reported to applications, so it
1330ca
-                # really doesn't matter what we return.
1330ca
-                os._exit(255)
1330ca
-
1330ca
-            # Parent
1330ca
-            os.close(errpipe_write)
1330ca
-            if p2cread and p2cwrite:
1330ca
-                os.close(p2cread)
1330ca
-            if c2pwrite and c2pread:
1330ca
-                os.close(c2pwrite)
1330ca
-            if errwrite and errread:
1330ca
-                os.close(errwrite)
1330ca
-
1330ca
-            # Wait for exec to fail or succeed; possibly raising exception
1330ca
-            data = os.read(errpipe_read, 1048576) # Exceptions limited to 1 MB
1330ca
-            os.close(errpipe_read)
1330ca
-            if data != "":
1330ca
-                os.waitpid(self.pid, 0)
1330ca
-                child_exception = pickle.loads(data)
1330ca
-                raise child_exception
1330ca
-
1330ca
-
1330ca
-        def _handle_exitstatus(self, sts):
1330ca
-            if os.WIFSIGNALED(sts):
1330ca
-                self.returncode = -os.WTERMSIG(sts)
1330ca
-            elif os.WIFEXITED(sts):
1330ca
-                self.returncode = os.WEXITSTATUS(sts)
1330ca
-            else:
1330ca
-                # Should never happen
1330ca
-                raise RuntimeError("Unknown child exit status!")
1330ca
-
1330ca
-            _active.remove(self)
1330ca
-
1330ca
-
1330ca
-        def poll(self):
1330ca
-            """Check if child process has terminated.  Returns returncode
1330ca
-            attribute."""
1330ca
-            if self.returncode == None:
1330ca
-                try:
1330ca
-                    pid, sts = os.waitpid(self.pid, os.WNOHANG)
1330ca
-                    if pid == self.pid:
1330ca
-                        self._handle_exitstatus(sts)
1330ca
-                except os.error:
1330ca
-                    pass
1330ca
-            return self.returncode
1330ca
-
1330ca
-
1330ca
-        def wait(self):
1330ca
-            """Wait for child process to terminate.  Returns returncode
1330ca
-            attribute."""
1330ca
-            if self.returncode == None:
1330ca
-                pid, sts = os.waitpid(self.pid, 0)
1330ca
-                self._handle_exitstatus(sts)
1330ca
-            return self.returncode
1330ca
-
1330ca
-
1330ca
-        def communicate(self, input=None):
1330ca
-            """Interact with process: Send data to stdin.  Read data from
1330ca
-            stdout and stderr, until end-of-file is reached.  Wait for
1330ca
-            process to terminate.  The optional input argument should be a
1330ca
-            string to be sent to the child process, or None, if no data
1330ca
-            should be sent to the child.
1330ca
-
1330ca
-            communicate() returns a tuple (stdout, stderr)."""
1330ca
-            read_set = []
1330ca
-            write_set = []
1330ca
-            stdout = None # Return
1330ca
-            stderr = None # Return
1330ca
-
1330ca
-            if self.stdin:
1330ca
-                # Flush stdio buffer.  This might block, if the user has
1330ca
-                # been writing to .stdin in an uncontrolled fashion.
1330ca
-                self.stdin.flush()
1330ca
-                if input:
1330ca
-                    write_set.append(self.stdin)
1330ca
-                else:
1330ca
-                    self.stdin.close()
1330ca
-            if self.stdout:
1330ca
-                read_set.append(self.stdout)
1330ca
-                stdout = []
1330ca
-            if self.stderr:
1330ca
-                read_set.append(self.stderr)
1330ca
-                stderr = []
1330ca
-
1330ca
-            while read_set or write_set:
1330ca
-                rlist, wlist, xlist = select.select(read_set, write_set, [])
1330ca
-
1330ca
-                if self.stdin in wlist:
1330ca
-                    # When select has indicated that the file is writable,
1330ca
-                    # we can write up to PIPE_BUF bytes without risk
1330ca
-                    # blocking.  POSIX defines PIPE_BUF >= 512
1330ca
-                    bytes_written = os.write(self.stdin.fileno(), input[:512])
1330ca
-                    input = input[bytes_written:]
1330ca
-                    if not input:
1330ca
-                        self.stdin.close()
1330ca
-                        write_set.remove(self.stdin)
1330ca
-
1330ca
-                if self.stdout in rlist:
1330ca
-                    data = os.read(self.stdout.fileno(), 1024)
1330ca
-                    if data == "":
1330ca
-                        self.stdout.close()
1330ca
-                        read_set.remove(self.stdout)
1330ca
-                    stdout.append(data)
1330ca
-
1330ca
-                if self.stderr in rlist:
1330ca
-                    data = os.read(self.stderr.fileno(), 1024)
1330ca
-                    if data == "":
1330ca
-                        self.stderr.close()
1330ca
-                        read_set.remove(self.stderr)
1330ca
-                    stderr.append(data)
1330ca
-
1330ca
-            # All data exchanged.  Translate lists into strings.
1330ca
-            if stdout != None:
1330ca
-                stdout = ''.join(stdout)
1330ca
-            if stderr != None:
1330ca
-                stderr = ''.join(stderr)
1330ca
-
1330ca
-            # Translate newlines, if requested.  We cannot let the file
1330ca
-            # object do the translation: It is based on stdio, which is
1330ca
-            # impossible to combine with select (unless forcing no
1330ca
-            # buffering).
1330ca
-            if self.universal_newlines and hasattr(open, 'newlines'):
1330ca
-                if stdout:
1330ca
-                    stdout = self._translate_newlines(stdout)
1330ca
-                if stderr:
1330ca
-                    stderr = self._translate_newlines(stderr)
1330ca
-
1330ca
-            self.wait()
1330ca
-            return (stdout, stderr)
1330ca
-
1330ca
-
1330ca
-def _demo_posix():
1330ca
-    #
1330ca
-    # Example 1: Simple redirection: Get process list
1330ca
-    #
1330ca
-    plist = Popen(["ps"], stdout=PIPE).communicate()[0]
1330ca
-    print "Process list:"
1330ca
-    print plist
1330ca
-
1330ca
-    #
1330ca
-    # Example 2: Change uid before executing child
1330ca
-    #
1330ca
-    if os.getuid() == 0:
1330ca
-        p = Popen(["id"], preexec_fn=lambda: os.setuid(100))
1330ca
-        p.wait()
1330ca
-
1330ca
-    #
1330ca
-    # Example 3: Connecting several subprocesses
1330ca
-    #
1330ca
-    print "Looking for 'hda'..."
1330ca
-    p1 = Popen(["dmesg"], stdout=PIPE)
1330ca
-    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
1330ca
-    print repr(p2.communicate()[0])
1330ca
-
1330ca
-    #
1330ca
-    # Example 4: Catch execution error
1330ca
-    #
1330ca
-    print
1330ca
-    print "Trying a weird file..."
1330ca
-    try:
1330ca
-        print Popen(["/this/path/does/not/exist"]).communicate()
1330ca
-    except OSError, e:
1330ca
-        if e.errno == errno.ENOENT:
1330ca
-            print "The file didn't exist.  I thought so..."
1330ca
-            print "Child traceback:"
1330ca
-            print e.child_traceback
1330ca
-        else:
1330ca
-            print "Error", e.errno
1330ca
-    else:
1330ca
-        print >>sys.stderr, "Gosh.  No error."
1330ca
-
1330ca
-
1330ca
-def _demo_windows():
1330ca
-    #
1330ca
-    # Example 1: Connecting several subprocesses
1330ca
-    #
1330ca
-    print "Looking for 'PROMPT' in set output..."
1330ca
-    p1 = Popen("set", stdout=PIPE, shell=True)
1330ca
-    p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE)
1330ca
-    print repr(p2.communicate()[0])
1330ca
-
1330ca
-    #
1330ca
-    # Example 2: Simple execution of program
1330ca
-    #
1330ca
-    print "Executing calc..."
1330ca
-    p = Popen("calc")
1330ca
-    p.wait()
1330ca
-
1330ca
-
1330ca
-if __name__ == "__main__":
1330ca
-    if mswindows:
1330ca
-        _demo_windows()
1330ca
-    else:
1330ca
-        _demo_posix()
1330ca
diff --git a/koan/text_wrap.py b/koan/text_wrap.py
1330ca
deleted file mode 100644
1330ca
index 2035463..0000000
1330ca
--- a/koan/text_wrap.py
1330ca
+++ /dev/null
1330ca
@@ -1,354 +0,0 @@
1330ca
-"""Text wrapping and filling.
1330ca
-(note: repackaged in koan because it's not present in RHEL3)
1330ca
-"""
1330ca
-
1330ca
-# Copyright (C) 1999-2001 Gregory P. Ward.
1330ca
-# Copyright (C) 2002, 2003 Python Software Foundation.
1330ca
-# Written by Greg Ward <gward@python.net>
1330ca
-
1330ca
-__revision__ = "$Id: textwrap.py,v 1.32.8.2 2004/05/13 01:48:15 gward Exp $"
1330ca
-
1330ca
-import string, re
1330ca
-
1330ca
-# Do the right thing with boolean values for all known Python versions
1330ca
-# (so this module can be copied to projects that don't depend on Python
1330ca
-# 2.3, e.g. Optik and Docutils).
1330ca
-try:
1330ca
-    True, False
1330ca
-except NameError:
1330ca
-    (True, False) = (1, 0)
1330ca
-
1330ca
-__all__ = ['TextWrapper', 'wrap', 'fill']
1330ca
-
1330ca
-# Hardcode the recognized whitespace characters to the US-ASCII
1330ca
-# whitespace characters.  The main reason for doing this is that in
1330ca
-# ISO-8859-1, 0xa0 is non-breaking whitespace, so in certain locales
1330ca
-# that character winds up in string.whitespace.  Respecting
1330ca
-# string.whitespace in those cases would 1) make textwrap treat 0xa0 the
1330ca
-# same as any other whitespace char, which is clearly wrong (it's a
1330ca
-# *non-breaking* space), 2) possibly cause problems with Unicode,
1330ca
-# since 0xa0 is not in range(128).
1330ca
-_whitespace = '\t\n\x0b\x0c\r '
1330ca
-
1330ca
-class TextWrapper:
1330ca
-    """
1330ca
-    Object for wrapping/filling text.  The public interface consists of
1330ca
-    the wrap() and fill() methods; the other methods are just there for
1330ca
-    subclasses to override in order to tweak the default behaviour.
1330ca
-    If you want to completely replace the main wrapping algorithm,
1330ca
-    you'll probably have to override _wrap_chunks().
1330ca
-
1330ca
-    Several instance attributes control various aspects of wrapping:
1330ca
-      width (default: 70)
1330ca
-        the maximum width of wrapped lines (unless break_long_words
1330ca
-        is false)
1330ca
-      initial_indent (default: "")
1330ca
-        string that will be prepended to the first line of wrapped
1330ca
-        output.  Counts towards the line's width.
1330ca
-      subsequent_indent (default: "")
1330ca
-        string that will be prepended to all lines save the first
1330ca
-        of wrapped output; also counts towards each line's width.
1330ca
-      expand_tabs (default: true)
1330ca
-        Expand tabs in input text to spaces before further processing.
1330ca
-        Each tab will become 1 .. 8 spaces, depending on its position in
1330ca
-        its line.  If false, each tab is treated as a single character.
1330ca
-      replace_whitespace (default: true)
1330ca
-        Replace all whitespace characters in the input text by spaces
1330ca
-        after tab expansion.  Note that if expand_tabs is false and
1330ca
-        replace_whitespace is true, every tab will be converted to a
1330ca
-        single space!
1330ca
-      fix_sentence_endings (default: false)
1330ca
-        Ensure that sentence-ending punctuation is always followed
1330ca
-        by two spaces.  Off by default because the algorithm is
1330ca
-        (unavoidably) imperfect.
1330ca
-      break_long_words (default: true)
1330ca
-        Break words longer than 'width'.  If false, those words will not
1330ca
-        be broken, and some lines might be longer than 'width'.
1330ca
-    """
1330ca
-
1330ca
-    whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace))
1330ca
-
1330ca
-    unicode_whitespace_trans = {}
1330ca
-    uspace = ord(u' ')
1330ca
-    for x in map(ord, _whitespace):
1330ca
-        unicode_whitespace_trans[x] = uspace
1330ca
-
1330ca
-    # This funky little regex is just the trick for splitting
1330ca
-    # text up into word-wrappable chunks.  E.g.
1330ca
-    #   "Hello there -- you goof-ball, use the -b option!"
1330ca
-    # splits into
1330ca
-    #   Hello/ /there/ /--/ /you/ /goof-/ball,/ /use/ /the/ /-b/ /option!
1330ca
-    # (after stripping out empty strings).
1330ca
-    wordsep_re = re.compile(r'(\s+|'                  # any whitespace
1330ca
-                            r'-*\w{2,}-(?=\w{2,})|'   # hyphenated words
1330ca
-                            r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')   # em-dash
1330ca
-
1330ca
-    # XXX will there be a locale-or-charset-aware version of
1330ca
-    # string.lowercase in 2.3?
1330ca
-    sentence_end_re = re.compile(r'[%s]'              # lowercase letter
1330ca
-                                 r'[\.\!\?]'          # sentence-ending punct.
1330ca
-                                 r'[\"\']?'           # optional end-of-quote
1330ca
-                                 % string.lowercase)
1330ca
-
1330ca
-
1330ca
-    def __init__(self,
1330ca
-                 width=70,
1330ca
-                 initial_indent="",
1330ca
-                 subsequent_indent="",
1330ca
-                 expand_tabs=True,
1330ca
-                 replace_whitespace=True,
1330ca
-                 fix_sentence_endings=False,
1330ca
-                 break_long_words=True):
1330ca
-        self.width = width
1330ca
-        self.initial_indent = initial_indent
1330ca
-        self.subsequent_indent = subsequent_indent
1330ca
-        self.expand_tabs = expand_tabs
1330ca
-        self.replace_whitespace = replace_whitespace
1330ca
-        self.fix_sentence_endings = fix_sentence_endings
1330ca
-        self.break_long_words = break_long_words
1330ca
-
1330ca
-
1330ca
-    # -- Private methods -----------------------------------------------
1330ca
-    # (possibly useful for subclasses to override)
1330ca
-
1330ca
-    def _munge_whitespace(self, text):
1330ca
-        """_munge_whitespace(text : string) -> string
1330ca
-
1330ca
-        Munge whitespace in text: expand tabs and convert all other
1330ca
-        whitespace characters to spaces.  Eg. " foo\tbar\n\nbaz"
1330ca
-        becomes " foo    bar  baz".
1330ca
-        """
1330ca
-        if self.expand_tabs:
1330ca
-            text = text.expandtabs()
1330ca
-        if self.replace_whitespace:
1330ca
-            if isinstance(text, str):
1330ca
-                text = text.translate(self.whitespace_trans)
1330ca
-            elif isinstance(text, unicode):
1330ca
-                text = text.translate(self.unicode_whitespace_trans)
1330ca
-        return text
1330ca
-
1330ca
-
1330ca
-    def _split(self, text):
1330ca
-        """_split(text : string) -> [string]
1330ca
-
1330ca
-        Split the text to wrap into indivisible chunks.  Chunks are
1330ca
-        not quite the same as words; see wrap_chunks() for full
1330ca
-        details.  As an example, the text
1330ca
-          Look, goof-ball -- use the -b option!
1330ca
-        breaks into the following chunks:
1330ca
-          'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
1330ca
-          'use', ' ', 'the', ' ', '-b', ' ', 'option!'
1330ca
-        """
1330ca
-        chunks = self.wordsep_re.split(text)
1330ca
-        chunks = filter(None, chunks)
1330ca
-        return chunks
1330ca
-
1330ca
-    def _fix_sentence_endings(self, chunks):
1330ca
-        """_fix_sentence_endings(chunks : [string])
1330ca
-
1330ca
-        Correct for sentence endings buried in 'chunks'.  Eg. when the
1330ca
-        original text contains "... foo.\nBar ...", munge_whitespace()
1330ca
-        and split() will convert that to [..., "foo.", " ", "Bar", ...]
1330ca
-        which has one too few spaces; this method simply changes the one
1330ca
-        space to two.
1330ca
-        """
1330ca
-        i = 0
1330ca
-        pat = self.sentence_end_re
1330ca
-        while i < len(chunks)-1:
1330ca
-            if chunks[i+1] == " " and pat.search(chunks[i]):
1330ca
-                chunks[i+1] = "  "
1330ca
-                i += 2
1330ca
-            else:
1330ca
-                i += 1
1330ca
-
1330ca
-    def _handle_long_word(self, chunks, cur_line, cur_len, width):
1330ca
-        """_handle_long_word(chunks : [string],
1330ca
-                             cur_line : [string],
1330ca
-                             cur_len : int, width : int)
1330ca
-
1330ca
-        Handle a chunk of text (most likely a word, not whitespace) that
1330ca
-        is too long to fit in any line.
1330ca
-        """
1330ca
-        space_left = max(width - cur_len, 1)
1330ca
-
1330ca
-        # If we're allowed to break long words, then do so: put as much
1330ca
-        # of the next chunk onto the current line as will fit.
1330ca
-        if self.break_long_words:
1330ca
-            cur_line.append(chunks[0][0:space_left])
1330ca
-            chunks[0] = chunks[0][space_left:]
1330ca
-
1330ca
-        # Otherwise, we have to preserve the long word intact.  Only add
1330ca
-        # it to the current line if there's nothing already there --
1330ca
-        # that minimizes how much we violate the width constraint.
1330ca
-        elif not cur_line:
1330ca
-            cur_line.append(chunks.pop(0))
1330ca
-
1330ca
-        # If we're not allowed to break long words, and there's already
1330ca
-        # text on the current line, do nothing.  Next time through the
1330ca
-        # main loop of _wrap_chunks(), we'll wind up here again, but
1330ca
-        # cur_len will be zero, so the next line will be entirely
1330ca
-        # devoted to the long word that we can't handle right now.
1330ca
-
1330ca
-    def _wrap_chunks(self, chunks):
1330ca
-        """_wrap_chunks(chunks : [string]) -> [string]
1330ca
-
1330ca
-        Wrap a sequence of text chunks and return a list of lines of
1330ca
-        length 'self.width' or less.  (If 'break_long_words' is false,
1330ca
-        some lines may be longer than this.)  Chunks correspond roughly
1330ca
-        to words and the whitespace between them: each chunk is
1330ca
-        indivisible (modulo 'break_long_words'), but a line break can
1330ca
-        come between any two chunks.  Chunks should not have internal
1330ca
-        whitespace; ie. a chunk is either all whitespace or a "word".
1330ca
-        Whitespace chunks will be removed from the beginning and end of
1330ca
-        lines, but apart from that whitespace is preserved.
1330ca
-        """
1330ca
-        lines = []
1330ca
-        if self.width <= 0:
1330ca
-            raise ValueError("invalid width %r (must be > 0)" % self.width)
1330ca
-
1330ca
-        while chunks:
1330ca
-
1330ca
-            # Start the list of chunks that will make up the current line.
1330ca
-            # cur_len is just the length of all the chunks in cur_line.
1330ca
-            cur_line = []
1330ca
-            cur_len = 0
1330ca
-
1330ca
-            # Figure out which static string will prefix this line.
1330ca
-            if lines:
1330ca
-                indent = self.subsequent_indent
1330ca
-            else:
1330ca
-                indent = self.initial_indent
1330ca
-
1330ca
-            # Maximum width for this line.
1330ca
-            width = self.width - len(indent)
1330ca
-
1330ca
-            # First chunk on line is whitespace -- drop it, unless this
1330ca
-            # is the very beginning of the text (ie. no lines started yet).
1330ca
-            if chunks[0].strip() == '' and lines:
1330ca
-                del chunks[0]
1330ca
-
1330ca
-            while chunks:
1330ca
-                l = len(chunks[0])
1330ca
-
1330ca
-                # Can at least squeeze this chunk onto the current line.
1330ca
-                if cur_len + l <= width:
1330ca
-                    cur_line.append(chunks.pop(0))
1330ca
-                    cur_len += l
1330ca
-
1330ca
-                # Nope, this line is full.
1330ca
-                else:
1330ca
-                    break
1330ca
-
1330ca
-            # The current line is full, and the next chunk is too big to
1330ca
-            # fit on *any* line (not just this one).
1330ca
-            if chunks and len(chunks[0]) > width:
1330ca
-                self._handle_long_word(chunks, cur_line, cur_len, width)
1330ca
-
1330ca
-            # If the last chunk on this line is all whitespace, drop it.
1330ca
-            if cur_line and cur_line[-1].strip() == '':
1330ca
-                del cur_line[-1]
1330ca
-
1330ca
-            # Convert current line back to a string and store it in list
1330ca
-            # of all lines (return value).
1330ca
-            if cur_line:
1330ca
-                lines.append(indent + ''.join(cur_line))
1330ca
-
1330ca
-        return lines
1330ca
-
1330ca
-
1330ca
-    # -- Public interface ----------------------------------------------
1330ca
-
1330ca
-    def wrap(self, text):
1330ca
-        """wrap(text : string) -> [string]
1330ca
-
1330ca
-        Reformat the single paragraph in 'text' so it fits in lines of
1330ca
-        no more than 'self.width' columns, and return a list of wrapped
1330ca
-        lines.  Tabs in 'text' are expanded with string.expandtabs(),
1330ca
-        and all other whitespace characters (including newline) are
1330ca
-        converted to space.
1330ca
-        """
1330ca
-        text = self._munge_whitespace(text)
1330ca
-        indent = self.initial_indent
1330ca
-        chunks = self._split(text)
1330ca
-        if self.fix_sentence_endings:
1330ca
-            self._fix_sentence_endings(chunks)
1330ca
-        return self._wrap_chunks(chunks)
1330ca
-
1330ca
-    def fill(self, text):
1330ca
-        """fill(text : string) -> string
1330ca
-
1330ca
-        Reformat the single paragraph in 'text' to fit in lines of no
1330ca
-        more than 'self.width' columns, and return a new string
1330ca
-        containing the entire wrapped paragraph.
1330ca
-        """
1330ca
-        return "\n".join(self.wrap(text))
1330ca
-
1330ca
-
1330ca
-# -- Convenience interface ---------------------------------------------
1330ca
-
1330ca
-def wrap(text, width=70, **kwargs):
1330ca
-    """Wrap a single paragraph of text, returning a list of wrapped lines.
1330ca
-
1330ca
-    Reformat the single paragraph in 'text' so it fits in lines of no
1330ca
-    more than 'width' columns, and return a list of wrapped lines.  By
1330ca
-    default, tabs in 'text' are expanded with string.expandtabs(), and
1330ca
-    all other whitespace characters (including newline) are converted to
1330ca
-    space.  See TextWrapper class for available keyword args to customize
1330ca
-    wrapping behaviour.
1330ca
-    """
1330ca
-    w = TextWrapper(width=width, **kwargs)
1330ca
-    return w.wrap(text)
1330ca
-
1330ca
-def fill(text, width=70, **kwargs):
1330ca
-    """Fill a single paragraph of text, returning a new string.
1330ca
-
1330ca
-    Reformat the single paragraph in 'text' to fit in lines of no more
1330ca
-    than 'width' columns, and return a new string containing the entire
1330ca
-    wrapped paragraph.  As with wrap(), tabs are expanded and other
1330ca
-    whitespace characters converted to space.  See TextWrapper class for
1330ca
-    available keyword args to customize wrapping behaviour.
1330ca
-    """
1330ca
-    w = TextWrapper(width=width, **kwargs)
1330ca
-    return w.fill(text)
1330ca
-
1330ca
-
1330ca
-# -- Loosely related functionality -------------------------------------
1330ca
-
1330ca
-def dedent(text):
1330ca
-    """dedent(text : string) -> string
1330ca
-
1330ca
-    Remove any whitespace than can be uniformly removed from the left
1330ca
-    of every line in `text`.
1330ca
-
1330ca
-    This can be used e.g. to make triple-quoted strings line up with
1330ca
-    the left edge of screen/whatever, while still presenting it in the
1330ca
-    source code in indented form.
1330ca
-
1330ca
-    For example:
1330ca
-
1330ca
-        def test():
1330ca
-            # end first line with \ to avoid the empty line!
1330ca
-            s = '''\
1330ca
-            hello
1330ca
-              world
1330ca
-            '''
1330ca
-            print repr(s)          # prints '    hello\n      world\n    '
1330ca
-            print repr(dedent(s))  # prints 'hello\n  world\n'
1330ca
-    """
1330ca
-    lines = text.expandtabs().split('\n')
1330ca
-    margin = None
1330ca
-    for line in lines:
1330ca
-        content = line.lstrip()
1330ca
-        if not content:
1330ca
-            continue
1330ca
-        indent = len(line) - len(content)
1330ca
-        if margin is None:
1330ca
-            margin = indent
1330ca
-        else:
1330ca
-            margin = min(margin, indent)
1330ca
-
1330ca
-    if margin is not None and margin > 0:
1330ca
-        for i in range(len(lines)):
1330ca
-            lines[i] = lines[i][margin:]
1330ca
-
1330ca
-    return '\n'.join(lines)
1330ca
diff --git a/koan/utils.py b/koan/utils.py
1330ca
index 475bcd0..4a3f547 100644
1330ca
--- a/koan/utils.py
1330ca
+++ b/koan/utils.py
1330ca
@@ -21,29 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1330ca
 02110-1301  USA
1330ca
 """
1330ca
 
1330ca
-import random
1330ca
 import os
1330ca
 import traceback
1330ca
-import tempfile
1330ca
-ANCIENT_PYTHON = 0
1330ca
-try:
1330ca
-    try:
1330ca
-        import subprocess as sub_process
1330ca
-    except:
1330ca
-       import sub_process
1330ca
-    import urllib2
1330ca
-except:
1330ca
-    ANCIENT_PYTHON = 1
1330ca
-import time
1330ca
-import shutil
1330ca
-import errno
1330ca
-import re
1330ca
 import sys
1330ca
+import subprocess as sub_process
1330ca
+import urllib2
1330ca
 import xmlrpclib
1330ca
 import string
1330ca
-import re
1330ca
-import glob
1330ca
-import socket
1330ca
 import shutil
1330ca
 import tempfile
1330ca
 import urlgrabber
1330ca
@@ -131,13 +115,6 @@ def urlread(url):
1330ca
             fd.close()
1330ca
             return data
1330ca
         except:
1330ca
-            if ANCIENT_PYTHON:
1330ca
-                # this logic is to support python 1.5 and EL 2
1330ca
-                import urllib
1330ca
-                fd = urllib.urlopen(url)
1330ca
-                data = fd.read()
1330ca
-                fd.close()
1330ca
-                return data
1330ca
             traceback.print_exc()
1330ca
             raise InfoException, "Couldn't download: %s" % url
1330ca
     elif url[0:4] == "file":
1330ca
@@ -167,12 +144,7 @@ def subprocess_call(cmd,ignore_rc=0):
1330ca
     Wrapper around subprocess.call(...)
1330ca
     """
1330ca
     print "- %s" % cmd
1330ca
-    if not ANCIENT_PYTHON:
1330ca
-        rc = sub_process.call(cmd)
1330ca
-    else:
1330ca
-        cmd = string.join(cmd, " ")
1330ca
-        print "cmdstr=(%s)" % cmd
1330ca
-        rc = os.system(cmd)
1330ca
+    rc = sub_process.call(cmd)
1330ca
     if rc != 0 and not ignore_rc:
1330ca
         raise InfoException, "command failed (%s)" % rc
1330ca
     return rc
1330ca
@@ -184,15 +156,10 @@ def subprocess_get_response(cmd, ignore_rc=False):
1330ca
     print "- %s" % cmd
1330ca
     rc = 0
1330ca
     result = ""
1330ca
-    if not ANCIENT_PYTHON:
1330ca
-        p = sub_process.Popen(cmd, stdout=sub_process.PIPE, stderr=sub_process.STDOUT)
1330ca
-        result, stderr = p.communicate()
1330ca
-        result = result.strip()
1330ca
-        rc = p.poll()
1330ca
-    else:
1330ca
-        cmd = string.join(cmd, " ")
1330ca
-        print "cmdstr=(%s)" % cmd
1330ca
-        rc = os.system(cmd)
1330ca
+    p = sub_process.Popen(cmd, stdout=sub_process.PIPE, stderr=sub_process.STDOUT)
1330ca
+    result, stderr = p.communicate()
1330ca
+    result = result.strip()
1330ca
+    rc = p.poll()
1330ca
     if not ignore_rc and rc != 0:
1330ca
         raise InfoException, "command failed (%s)" % rc
1330ca
     return rc, result
1330ca
@@ -347,9 +314,6 @@ def os_release():
1330ca
    This code is borrowed from Cobbler and really shouldn't be repeated.
1330ca
    """
1330ca
 
1330ca
-   if ANCIENT_PYTHON:
1330ca
-      return ("unknown", 0)
1330ca
-
1330ca
    if check_dist() == "redhat":
1330ca
       fh = open("/etc/redhat-release")
1330ca
       data = fh.read().lower()
1330ca
diff --git a/koan/vmwcreate.py b/koan/vmwcreate.py
1330ca
index 1bde891..3fda926 100755
1330ca
--- a/koan/vmwcreate.py
1330ca
+++ b/koan/vmwcreate.py
1330ca
@@ -21,12 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1330ca
 """
1330ca
 
1330ca
 
1330ca
-import os, sys, time, stat
1330ca
-import tempfile
1330ca
+import os
1330ca
 import random
1330ca
-from optparse import OptionParser
1330ca
-import errno
1330ca
-import re
1330ca
 import virtinst
1330ca
 
1330ca
 IMAGE_DIR = "/var/lib/vmware/images"
1330ca
-- 
1330ca
2.5.5
1330ca