hawq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [07/11] incubator-hawq git commit: HAWQ-838. Replace python module paramiko with pexpect
Date Thu, 18 Aug 2016 02:44:32 GMT
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/pexpect/pty_spawn.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/pexpect-4.2/pexpect/pty_spawn.py b/tools/bin/pythonSrc/pexpect-4.2/pexpect/pty_spawn.py
new file mode 100644
index 0000000..d1c6df7
--- /dev/null
+++ b/tools/bin/pythonSrc/pexpect-4.2/pexpect/pty_spawn.py
@@ -0,0 +1,806 @@
+import os
+import sys
+import time
+import pty
+import tty
+import errno
+import signal
+from contextlib import contextmanager
+
+import ptyprocess
+from ptyprocess.ptyprocess import use_native_pty_fork
+
+from .exceptions import ExceptionPexpect, EOF, TIMEOUT
+from .spawnbase import SpawnBase
+from .utils import which, split_command_line, select_ignore_interrupts
+
+@contextmanager
+def _wrap_ptyprocess_err():
+    """Turn ptyprocess errors into our own ExceptionPexpect errors"""
+    try:
+        yield
+    except ptyprocess.PtyProcessError as e:
+        raise ExceptionPexpect(*e.args)
+
+PY3 = (sys.version_info[0] >= 3)
+
+class spawn(SpawnBase):
+    '''This is the main class interface for Pexpect. Use this class to start
+    and control child applications. '''
+
+    # This is purely informational now - changing it has no effect
+    use_native_pty_fork = use_native_pty_fork
+
+    def __init__(self, command, args=[], timeout=30, maxread=2000,
+                 searchwindowsize=None, logfile=None, cwd=None, env=None,
+                 ignore_sighup=False, echo=True, preexec_fn=None,
+                 encoding=None, codec_errors='strict', dimensions=None):
+        '''This is the constructor. The command parameter may be a string that
+        includes a command and any arguments to the command. For example::
+
+            child = pexpect.spawn('/usr/bin/ftp')
+            child = pexpect.spawn('/usr/bin/ssh user@example.com')
+            child = pexpect.spawn('ls -latr /tmp')
+
+        You may also construct it with a list of arguments like so::
+
+            child = pexpect.spawn('/usr/bin/ftp', [])
+            child = pexpect.spawn('/usr/bin/ssh', ['user@example.com'])
+            child = pexpect.spawn('ls', ['-latr', '/tmp'])
+
+        After this the child application will be created and will be ready to
+        talk to. For normal use, see expect() and send() and sendline().
+
+        Remember that Pexpect does NOT interpret shell meta characters such as
+        redirect, pipe, or wild cards (``>``, ``|``, or ``*``). This is a
+        common mistake.  If you want to run a command and pipe it through
+        another command then you must also start a shell. For example::
+
+            child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"')
+            child.expect(pexpect.EOF)
+
+        The second form of spawn (where you pass a list of arguments) is useful
+        in situations where you wish to spawn a command and pass it its own
+        argument list. This can make syntax more clear. For example, the
+        following is equivalent to the previous example::
+
+            shell_cmd = 'ls -l | grep LOG > logs.txt'
+            child = pexpect.spawn('/bin/bash', ['-c', shell_cmd])
+            child.expect(pexpect.EOF)
+
+        The maxread attribute sets the read buffer size. This is maximum number
+        of bytes that Pexpect will try to read from a TTY at one time. Setting
+        the maxread size to 1 will turn off buffering. Setting the maxread
+        value higher may help performance in cases where large amounts of
+        output are read back from the child. This feature is useful in
+        conjunction with searchwindowsize.
+
+        When the keyword argument *searchwindowsize* is None (default), the
+        full buffer is searched at each iteration of receiving incoming data.
+        The default number of bytes scanned at each iteration is very large
+        and may be reduced to collaterally reduce search cost.  After
+        :meth:`~.expect` returns, the full buffer attribute remains up to
+        size *maxread* irrespective of *searchwindowsize* value.
+
+        When the keyword argument ``timeout`` is specified as a number,
+        (default: *30*), then :class:`TIMEOUT` will be raised after the value
+        specified has elapsed, in seconds, for any of the :meth:`~.expect`
+        family of method calls.  When None, TIMEOUT will not be raised, and
+        :meth:`~.expect` may block indefinitely until match.
+
+
+        The logfile member turns on or off logging. All input and output will
+        be copied to the given file object. Set logfile to None to stop
+        logging. This is the default. Set logfile to sys.stdout to echo
+        everything to standard output. The logfile is flushed after each write.
+
+        Example log input and output to a file::
+
+            child = pexpect.spawn('some_command')
+            fout = open('mylog.txt','wb')
+            child.logfile = fout
+
+        Example log to stdout::
+
+            # In Python 2:
+            child = pexpect.spawn('some_command')
+            child.logfile = sys.stdout
+
+            # In Python 3, spawnu should be used to give str to stdout:
+            child = pexpect.spawnu('some_command')
+            child.logfile = sys.stdout
+
+        The logfile_read and logfile_send members can be used to separately log
+        the input from the child and output sent to the child. Sometimes you
+        don't want to see everything you write to the child. You only want to
+        log what the child sends back. For example::
+
+            child = pexpect.spawn('some_command')
+            child.logfile_read = sys.stdout
+
+        You will need to pass an encoding to spawn in the above code if you are
+        using Python 3.
+
+        To separately log output sent to the child use logfile_send::
+
+            child.logfile_send = fout
+
+        If ``ignore_sighup`` is True, the child process will ignore SIGHUP
+        signals. The default is False from Pexpect 4.0, meaning that SIGHUP
+        will be handled normally by the child.
+
+        The delaybeforesend helps overcome a weird behavior that many users
+        were experiencing. The typical problem was that a user would expect() a
+        "Password:" prompt and then immediately call sendline() to send the
+        password. The user would then see that their password was echoed back
+        to them. Passwords don't normally echo. The problem is caused by the
+        fact that most applications print out the "Password" prompt and then
+        turn off stdin echo, but if you send your password before the
+        application turned off echo, then you get your password echoed.
+        Normally this wouldn't be a problem when interacting with a human at a
+        real keyboard. If you introduce a slight delay just before writing then
+        this seems to clear up the problem. This was such a common problem for
+        many users that I decided that the default pexpect behavior should be
+        to sleep just before writing to the child application. 1/20th of a
+        second (50 ms) seems to be enough to clear up the problem. You can set
+        delaybeforesend to None to return to the old behavior.
+
+        Note that spawn is clever about finding commands on your path.
+        It uses the same logic that "which" uses to find executables.
+
+        If you wish to get the exit status of the child you must call the
+        close() method. The exit or signal status of the child will be stored
+        in self.exitstatus or self.signalstatus. If the child exited normally
+        then exitstatus will store the exit return code and signalstatus will
+        be None. If the child was terminated abnormally with a signal then
+        signalstatus will store the signal value and exitstatus will be None::
+
+            child = pexpect.spawn('some_command')
+            child.close()
+            print(child.exitstatus, child.signalstatus)
+
+        If you need more detail you can also read the self.status member which
+        stores the status returned by os.waitpid. You can interpret this using
+        os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG.
+
+        The echo attribute may be set to False to disable echoing of input.
+        As a pseudo-terminal, all input echoed by the "keyboard" (send()
+        or sendline()) will be repeated to output.  For many cases, it is
+        not desirable to have echo enabled, and it may be later disabled
+        using setecho(False) followed by waitnoecho().  However, for some
+        platforms such as Solaris, this is not possible, and should be
+        disabled immediately on spawn.
+        
+        If preexec_fn is given, it will be called in the child process before
+        launching the given command. This is useful to e.g. reset inherited
+        signal handlers.
+
+        The dimensions attribute specifies the size of the pseudo-terminal as
+        seen by the subprocess, and is specified as a two-entry tuple (rows,
+        columns). If this is unspecified, the defaults in ptyprocess will apply.
+        '''
+        super(spawn, self).__init__(timeout=timeout, maxread=maxread, searchwindowsize=searchwindowsize,
+                                    logfile=logfile, encoding=encoding, codec_errors=codec_errors)
+        self.STDIN_FILENO = pty.STDIN_FILENO
+        self.STDOUT_FILENO = pty.STDOUT_FILENO
+        self.STDERR_FILENO = pty.STDERR_FILENO
+        self.cwd = cwd
+        self.env = env
+        self.echo = echo
+        self.ignore_sighup = ignore_sighup
+        self.__irix_hack = sys.platform.lower().startswith('irix')
+        if command is None:
+            self.command = None
+            self.args = None
+            self.name = '<pexpect factory incomplete>'
+        else:
+            self._spawn(command, args, preexec_fn, dimensions)
+
+    def __str__(self):
+        '''This returns a human-readable string that represents the state of
+        the object. '''
+
+        s = []
+        s.append(repr(self))
+        s.append('command: ' + str(self.command))
+        s.append('args: %r' % (self.args,))
+        s.append('buffer (last 100 chars): %r' % (
+                self.buffer[-100:] if self.buffer else self.buffer,))
+        s.append('before (last 100 chars): %r' % (
+                self.before[-100:] if self.before else self.before,))
+        s.append('after: %r' % (self.after,))
+        s.append('match: %r' % (self.match,))
+        s.append('match_index: ' + str(self.match_index))
+        s.append('exitstatus: ' + str(self.exitstatus))
+        if hasattr(self, 'ptyproc'):
+            s.append('flag_eof: ' + str(self.flag_eof))
+        s.append('pid: ' + str(self.pid))
+        s.append('child_fd: ' + str(self.child_fd))
+        s.append('closed: ' + str(self.closed))
+        s.append('timeout: ' + str(self.timeout))
+        s.append('delimiter: ' + str(self.delimiter))
+        s.append('logfile: ' + str(self.logfile))
+        s.append('logfile_read: ' + str(self.logfile_read))
+        s.append('logfile_send: ' + str(self.logfile_send))
+        s.append('maxread: ' + str(self.maxread))
+        s.append('ignorecase: ' + str(self.ignorecase))
+        s.append('searchwindowsize: ' + str(self.searchwindowsize))
+        s.append('delaybeforesend: ' + str(self.delaybeforesend))
+        s.append('delayafterclose: ' + str(self.delayafterclose))
+        s.append('delayafterterminate: ' + str(self.delayafterterminate))
+        return '\n'.join(s)
+
+    def _spawn(self, command, args=[], preexec_fn=None, dimensions=None):
+        '''This starts the given command in a child process. This does all the
+        fork/exec type of stuff for a pty. This is called by __init__. If args
+        is empty then command will be parsed (split on spaces) and args will be
+        set to parsed arguments. '''
+
+        # The pid and child_fd of this object get set by this method.
+        # Note that it is difficult for this method to fail.
+        # You cannot detect if the child process cannot start.
+        # So the only way you can tell if the child process started
+        # or not is to try to read from the file descriptor. If you get
+        # EOF immediately then it means that the child is already dead.
+        # That may not necessarily be bad because you may have spawned a child
+        # that performs some task; creates no stdout output; and then dies.
+
+        # If command is an int type then it may represent a file descriptor.
+        if isinstance(command, type(0)):
+            raise ExceptionPexpect('Command is an int type. ' +
+                    'If this is a file descriptor then maybe you want to ' +
+                    'use fdpexpect.fdspawn which takes an existing ' +
+                    'file descriptor instead of a command string.')
+
+        if not isinstance(args, type([])):
+            raise TypeError('The argument, args, must be a list.')
+
+        if args == []:
+            self.args = split_command_line(command)
+            self.command = self.args[0]
+        else:
+            # Make a shallow copy of the args list.
+            self.args = args[:]
+            self.args.insert(0, command)
+            self.command = command
+
+        command_with_path = which(self.command, env=self.env)
+        if command_with_path is None:
+            raise ExceptionPexpect('The command was not found or was not ' +
+                    'executable: %s.' % self.command)
+        self.command = command_with_path
+        self.args[0] = self.command
+
+        self.name = '<' + ' '.join(self.args) + '>'
+
+        assert self.pid is None, 'The pid member must be None.'
+        assert self.command is not None, 'The command member must not be None.'
+
+        kwargs = {'echo': self.echo, 'preexec_fn': preexec_fn}
+        if self.ignore_sighup:
+            def preexec_wrapper():
+                "Set SIGHUP to be ignored, then call the real preexec_fn"
+                signal.signal(signal.SIGHUP, signal.SIG_IGN)
+                if preexec_fn is not None:
+                    preexec_fn()
+            kwargs['preexec_fn'] = preexec_wrapper
+
+        if dimensions is not None:
+            kwargs['dimensions'] = dimensions
+
+        if self.encoding is not None:
+            # Encode command line using the specified encoding
+            self.args = [a if isinstance(a, bytes) else a.encode(self.encoding)
+                         for a in self.args]
+
+        self.ptyproc = self._spawnpty(self.args, env=self.env,
+                                     cwd=self.cwd, **kwargs)
+
+        self.pid = self.ptyproc.pid
+        self.child_fd = self.ptyproc.fd
+
+
+        self.terminated = False
+        self.closed = False
+
+    def _spawnpty(self, args, **kwargs):
+        '''Spawn a pty and return an instance of PtyProcess.'''
+        return ptyprocess.PtyProcess.spawn(args, **kwargs)
+
+    def close(self, force=True):
+        '''This closes the connection with the child application. Note that
+        calling close() more than once is valid. This emulates standard Python
+        behavior with files. Set force to True if you want to make sure that
+        the child is terminated (SIGKILL is sent if the child ignores SIGHUP
+        and SIGINT). '''
+
+        self.flush()
+        self.ptyproc.close(force=force)
+        self.isalive()  # Update exit status from ptyproc
+        self.child_fd = -1
+
+    def isatty(self):
+        '''This returns True if the file descriptor is open and connected to a
+        tty(-like) device, else False.
+
+        On SVR4-style platforms implementing streams, such as SunOS and HP-UX,
+        the child pty may not appear as a terminal device.  This means
+        methods such as setecho(), setwinsize(), getwinsize() may raise an
+        IOError. '''
+
+        return os.isatty(self.child_fd)
+
+    def waitnoecho(self, timeout=-1):
+        '''This waits until the terminal ECHO flag is set False. This returns
+        True if the echo mode is off. This returns False if the ECHO flag was
+        not set False before the timeout. This can be used to detect when the
+        child is waiting for a password. Usually a child application will turn
+        off echo mode when it is waiting for the user to enter a password. For
+        example, instead of expecting the "password:" prompt you can wait for
+        the child to set ECHO off::
+
+            p = pexpect.spawn('ssh user@example.com')
+            p.waitnoecho()
+            p.sendline(mypassword)
+
+        If timeout==-1 then this method will use the value in self.timeout.
+        If timeout==None then this method to block until ECHO flag is False.
+        '''
+
+        if timeout == -1:
+            timeout = self.timeout
+        if timeout is not None:
+            end_time = time.time() + timeout
+        while True:
+            if not self.getecho():
+                return True
+            if timeout < 0 and timeout is not None:
+                return False
+            if timeout is not None:
+                timeout = end_time - time.time()
+            time.sleep(0.1)
+
+    def getecho(self):
+        '''This returns the terminal echo mode. This returns True if echo is
+        on or False if echo is off. Child applications that are expecting you
+        to enter a password often set ECHO False. See waitnoecho().
+
+        Not supported on platforms where ``isatty()`` returns False.  '''
+        return self.ptyproc.getecho()
+
+    def setecho(self, state):
+        '''This sets the terminal echo mode on or off. Note that anything the
+        child sent before the echo will be lost, so you should be sure that
+        your input buffer is empty before you call setecho(). For example, the
+        following will work as expected::
+
+            p = pexpect.spawn('cat') # Echo is on by default.
+            p.sendline('1234') # We expect see this twice from the child...
+            p.expect(['1234']) # ... once from the tty echo...
+            p.expect(['1234']) # ... and again from cat itself.
+            p.setecho(False) # Turn off tty echo
+            p.sendline('abcd') # We will set this only once (echoed by cat).
+            p.sendline('wxyz') # We will set this only once (echoed by cat)
+            p.expect(['abcd'])
+            p.expect(['wxyz'])
+
+        The following WILL NOT WORK because the lines sent before the setecho
+        will be lost::
+
+            p = pexpect.spawn('cat')
+            p.sendline('1234')
+            p.setecho(False) # Turn off tty echo
+            p.sendline('abcd') # We will set this only once (echoed by cat).
+            p.sendline('wxyz') # We will set this only once (echoed by cat)
+            p.expect(['1234'])
+            p.expect(['1234'])
+            p.expect(['abcd'])
+            p.expect(['wxyz'])
+
+
+        Not supported on platforms where ``isatty()`` returns False.
+        '''
+        return self.ptyproc.setecho(state)
+
+    def read_nonblocking(self, size=1, timeout=-1):
+        '''This reads at most size characters from the child application. It
+        includes a timeout. If the read does not complete within the timeout
+        period then a TIMEOUT exception is raised. If the end of file is read
+        then an EOF exception will be raised.  If a logfile is specified, a
+        copy is written to that log.
+
+        If timeout is None then the read may block indefinitely.
+        If timeout is -1 then the self.timeout value is used. If timeout is 0
+        then the child is polled and if there is no data immediately ready
+        then this will raise a TIMEOUT exception.
+
+        The timeout refers only to the amount of time to read at least one
+        character. This is not affected by the 'size' parameter, so if you call
+        read_nonblocking(size=100, timeout=30) and only one character is
+        available right away then one character will be returned immediately.
+        It will not wait for 30 seconds for another 99 characters to come in.
+
+        This is a wrapper around os.read(). It uses select.select() to
+        implement the timeout. '''
+
+        if self.closed:
+            raise ValueError('I/O operation on closed file.')
+
+        if timeout == -1:
+            timeout = self.timeout
+
+        # Note that some systems such as Solaris do not give an EOF when
+        # the child dies. In fact, you can still try to read
+        # from the child_fd -- it will block forever or until TIMEOUT.
+        # For this case, I test isalive() before doing any reading.
+        # If isalive() is false, then I pretend that this is the same as EOF.
+        if not self.isalive():
+            # timeout of 0 means "poll"
+            r, w, e = select_ignore_interrupts([self.child_fd], [], [], 0)
+            if not r:
+                self.flag_eof = True
+                raise EOF('End Of File (EOF). Braindead platform.')
+        elif self.__irix_hack:
+            # Irix takes a long time before it realizes a child was terminated.
+            # FIXME So does this mean Irix systems are forced to always have
+            # FIXME a 2 second delay when calling read_nonblocking? That sucks.
+            r, w, e = select_ignore_interrupts([self.child_fd], [], [], 2)
+            if not r and not self.isalive():
+                self.flag_eof = True
+                raise EOF('End Of File (EOF). Slow platform.')
+
+        r, w, e = select_ignore_interrupts([self.child_fd], [], [], timeout)
+
+        if not r:
+            if not self.isalive():
+                # Some platforms, such as Irix, will claim that their
+                # processes are alive; timeout on the select; and
+                # then finally admit that they are not alive.
+                self.flag_eof = True
+                raise EOF('End of File (EOF). Very slow platform.')
+            else:
+                raise TIMEOUT('Timeout exceeded.')
+
+        if self.child_fd in r:
+            return super(spawn, self).read_nonblocking(size)
+
+        raise ExceptionPexpect('Reached an unexpected state.')  # pragma: no cover
+
+    def write(self, s):
+        '''This is similar to send() except that there is no return value.
+        '''
+
+        self.send(s)
+
+    def writelines(self, sequence):
+        '''This calls write() for each element in the sequence. The sequence
+        can be any iterable object producing strings, typically a list of
+        strings. This does not add line separators. There is no return value.
+        '''
+
+        for s in sequence:
+            self.write(s)
+
+    def send(self, s):
+        '''Sends string ``s`` to the child process, returning the number of
+        bytes written. If a logfile is specified, a copy is written to that
+        log.
+
+        The default terminal input mode is canonical processing unless set
+        otherwise by the child process. This allows backspace and other line
+        processing to be performed prior to transmitting to the receiving
+        program. As this is buffered, there is a limited size of such buffer.
+
+        On Linux systems, this is 4096 (defined by N_TTY_BUF_SIZE). All
+        other systems honor the POSIX.1 definition PC_MAX_CANON -- 1024
+        on OSX, 256 on OpenSolaris, and 1920 on FreeBSD.
+
+        This value may be discovered using fpathconf(3)::
+
+            >>> from os import fpathconf
+            >>> print(fpathconf(0, 'PC_MAX_CANON'))
+            256
+
+        On such a system, only 256 bytes may be received per line. Any
+        subsequent bytes received will be discarded. BEL (``'\a'``) is then
+        sent to output if IMAXBEL (termios.h) is set by the tty driver.
+        This is usually enabled by default.  Linux does not honor this as
+        an option -- it behaves as though it is always set on.
+
+        Canonical input processing may be disabled altogether by executing
+        a shell, then stty(1), before executing the final program::
+
+            >>> bash = pexpect.spawn('/bin/bash', echo=False)
+            >>> bash.sendline('stty -icanon')
+            >>> bash.sendline('base64')
+            >>> bash.sendline('x' * 5000)
+        '''
+
+        if self.delaybeforesend is not None:
+            time.sleep(self.delaybeforesend)
+
+        s = self._coerce_send_string(s)
+        self._log(s, 'send')
+
+        b = self._encoder.encode(s, final=False)
+        return os.write(self.child_fd, b)
+
+    def sendline(self, s=''):
+        '''Wraps send(), sending string ``s`` to child process, with
+        ``os.linesep`` automatically appended. Returns number of bytes
+        written.  Only a limited number of bytes may be sent for each
+        line in the default terminal mode, see docstring of :meth:`send`.
+        '''
+        s = self._coerce_send_string(s)
+        return self.send(s + self.linesep)
+
+    def _log_control(self, s):
+        """Write control characters to the appropriate log files"""
+        if self.encoding is not None:
+            s = s.decode(self.encoding, 'replace')
+        self._log(s, 'send')
+
+    def sendcontrol(self, char):
+        '''Helper method that wraps send() with mnemonic access for sending control
+        character to the child (such as Ctrl-C or Ctrl-D).  For example, to send
+        Ctrl-G (ASCII 7, bell, '\a')::
+
+            child.sendcontrol('g')
+
+        See also, sendintr() and sendeof().
+        '''
+        n, byte = self.ptyproc.sendcontrol(char)
+        self._log_control(byte)
+        return n
+
+    def sendeof(self):
+        '''This sends an EOF to the child. This sends a character which causes
+        the pending parent output buffer to be sent to the waiting child
+        program without waiting for end-of-line. If it is the first character
+        of the line, the read() in the user program returns 0, which signifies
+        end-of-file. This means to work as expected a sendeof() has to be
+        called at the beginning of a line. This method does not send a newline.
+        It is the responsibility of the caller to ensure the eof is sent at the
+        beginning of a line. '''
+
+        n, byte = self.ptyproc.sendeof()
+        self._log_control(byte)
+
+    def sendintr(self):
+        '''This sends a SIGINT to the child. It does not require
+        the SIGINT to be the first character on a line. '''
+
+        n, byte = self.ptyproc.sendintr()
+        self._log_control(byte)
+
+    @property
+    def flag_eof(self):
+        return self.ptyproc.flag_eof
+
+    @flag_eof.setter
+    def flag_eof(self, value):
+        self.ptyproc.flag_eof = value
+
+    def eof(self):
+        '''This returns True if the EOF exception was ever raised.
+        '''
+        return self.flag_eof
+
+    def terminate(self, force=False):
+        '''This forces a child process to terminate. It starts nicely with
+        SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This
+        returns True if the child was terminated. This returns False if the
+        child could not be terminated. '''
+
+        if not self.isalive():
+            return True
+        try:
+            self.kill(signal.SIGHUP)
+            time.sleep(self.delayafterterminate)
+            if not self.isalive():
+                return True
+            self.kill(signal.SIGCONT)
+            time.sleep(self.delayafterterminate)
+            if not self.isalive():
+                return True
+            self.kill(signal.SIGINT)
+            time.sleep(self.delayafterterminate)
+            if not self.isalive():
+                return True
+            if force:
+                self.kill(signal.SIGKILL)
+                time.sleep(self.delayafterterminate)
+                if not self.isalive():
+                    return True
+                else:
+                    return False
+            return False
+        except OSError:
+            # I think there are kernel timing issues that sometimes cause
+            # this to happen. I think isalive() reports True, but the
+            # process is dead to the kernel.
+            # Make one last attempt to see if the kernel is up to date.
+            time.sleep(self.delayafterterminate)
+            if not self.isalive():
+                return True
+            else:
+                return False
+
+    def wait(self):
+        '''This waits until the child exits. This is a blocking call. This will
+        not read any data from the child, so this will block forever if the
+        child has unread output and has terminated. In other words, the child
+        may have printed output then called exit(), but, the child is
+        technically still alive until its output is read by the parent.
+
+        This method is non-blocking if :meth:`wait` has already been called
+        previously or :meth:`isalive` method returns False.  It simply returns
+        the previously determined exit status.
+        '''
+
+        ptyproc = self.ptyproc
+        with _wrap_ptyprocess_err():
+            # exception may occur if "Is some other process attempting
+            # "job control with our child pid?"
+            exitstatus = ptyproc.wait()
+        self.status = ptyproc.status
+        self.exitstatus = ptyproc.exitstatus
+        self.signalstatus = ptyproc.signalstatus
+        self.terminated = True
+
+        return exitstatus
+
+    def isalive(self):
+        '''This tests if the child process is running or not. This is
+        non-blocking. If the child was terminated then this will read the
+        exitstatus or signalstatus of the child. This returns True if the child
+        process appears to be running or False if not. It can take literally
+        SECONDS for Solaris to return the right status. '''
+
+        ptyproc = self.ptyproc
+        with _wrap_ptyprocess_err():
+            alive = ptyproc.isalive()
+
+        if not alive:
+            self.status = ptyproc.status
+            self.exitstatus = ptyproc.exitstatus
+            self.signalstatus = ptyproc.signalstatus
+            self.terminated = True
+
+        return alive
+
+    def kill(self, sig):
+
+        '''This sends the given signal to the child application. In keeping
+        with UNIX tradition it has a misleading name. It does not necessarily
+        kill the child unless you send the right signal. '''
+
+        # Same as os.kill, but the pid is given for you.
+        if self.isalive():
+            os.kill(self.pid, sig)
+
+    def getwinsize(self):
+        '''This returns the terminal window size of the child tty. The return
+        value is a tuple of (rows, cols). '''
+        return self.ptyproc.getwinsize()
+
+    def setwinsize(self, rows, cols):
+        '''This sets the terminal window size of the child tty. This will cause
+        a SIGWINCH signal to be sent to the child. This does not change the
+        physical window size. It changes the size reported to TTY-aware
+        applications like vi or curses -- applications that respond to the
+        SIGWINCH signal. '''
+        return self.ptyproc.setwinsize(rows, cols)
+
+
+    def interact(self, escape_character=chr(29),
+            input_filter=None, output_filter=None):
+
+        '''This gives control of the child process to the interactive user (the
+        human at the keyboard). Keystrokes are sent to the child process, and
+        the stdout and stderr output of the child process is printed. This
+        simply echos the child stdout and child stderr to the real stdout and
+        it echos the real stdin to the child stdin. When the user types the
+        escape_character this method will return None. The escape_character
+        will not be transmitted.  The default for escape_character is
+        entered as ``Ctrl - ]``, the very same as BSD telnet. To prevent
+        escaping, escape_character may be set to None.
+
+        If a logfile is specified, then the data sent and received from the
+        child process in interact mode is duplicated to the given log.
+
+        You may pass in optional input and output filter functions. These
+        functions should take a string and return a string. The output_filter
+        will be passed all the output from the child process. The input_filter
+        will be passed all the keyboard input from the user. The input_filter
+        is run BEFORE the check for the escape_character.
+
+        Note that if you change the window size of the parent the SIGWINCH
+        signal will not be passed through to the child. If you want the child
+        window size to change when the parent's window size changes then do
+        something like the following example::
+
+            import pexpect, struct, fcntl, termios, signal, sys
+            def sigwinch_passthrough (sig, data):
+                s = struct.pack("HHHH", 0, 0, 0, 0)
+                a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(),
+                    termios.TIOCGWINSZ , s))
+                global p
+                p.setwinsize(a[0],a[1])
+            # Note this 'p' global and used in sigwinch_passthrough.
+            p = pexpect.spawn('/bin/bash')
+            signal.signal(signal.SIGWINCH, sigwinch_passthrough)
+            p.interact()
+        '''
+
+        # Flush the buffer.
+        self.write_to_stdout(self.buffer)
+        self.stdout.flush()
+        self.buffer = self.string_type()
+        mode = tty.tcgetattr(self.STDIN_FILENO)
+        tty.setraw(self.STDIN_FILENO)
+        if escape_character is not None and PY3:
+            escape_character = escape_character.encode('latin-1')
+        try:
+            self.__interact_copy(escape_character, input_filter, output_filter)
+        finally:
+            tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode)
+
+    def __interact_writen(self, fd, data):
+        '''This is used by the interact() method.
+        '''
+
+        while data != b'' and self.isalive():
+            n = os.write(fd, data)
+            data = data[n:]
+
+    def __interact_read(self, fd):
+        '''This is used by the interact() method.
+        '''
+
+        return os.read(fd, 1000)
+
+    def __interact_copy(self, escape_character=None,
+            input_filter=None, output_filter=None):
+
+        '''This is used by the interact() method.
+        '''
+
+        while self.isalive():
+            r, w, e = select_ignore_interrupts([self.child_fd, self.STDIN_FILENO], [], [])
+            if self.child_fd in r:
+                try:
+                    data = self.__interact_read(self.child_fd)
+                except OSError as err:
+                    if err.args[0] == errno.EIO:
+                        # Linux-style EOF
+                        break
+                    raise
+                if data == b'':
+                    # BSD-style EOF
+                    break
+                if output_filter:
+                    data = output_filter(data)
+                self._log(data, 'read')
+                os.write(self.STDOUT_FILENO, data)
+            if self.STDIN_FILENO in r:
+                data = self.__interact_read(self.STDIN_FILENO)
+                if input_filter:
+                    data = input_filter(data)
+                i = -1
+                if escape_character is not None:
+                    i = data.rfind(escape_character)
+                if i != -1:
+                    data = data[:i]
+                    if data:
+                        self._log(data, 'send')
+                    self.__interact_writen(self.child_fd, data)
+                    break
+                self._log(data, 'send')
+                self.__interact_writen(self.child_fd, data)
+
+
+def spawnu(*args, **kwargs):
+    """Deprecated: pass encoding to spawn() instead."""
+    kwargs.setdefault('encoding', 'utf-8')
+    return spawn(*args, **kwargs)

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/pexpect/pxssh.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/pexpect-4.2/pexpect/pxssh.py b/tools/bin/pythonSrc/pexpect-4.2/pexpect/pxssh.py
new file mode 100644
index 0000000..d5aec8a
--- /dev/null
+++ b/tools/bin/pythonSrc/pexpect-4.2/pexpect/pxssh.py
@@ -0,0 +1,406 @@
+'''This class extends pexpect.spawn to specialize setting up SSH connections.
+This adds methods for login, logout, and expecting the shell prompt.
+
+PEXPECT LICENSE
+
+    This license is approved by the OSI and FSF as GPL-compatible.
+        http://opensource.org/licenses/isc-license.txt
+
+    Copyright (c) 2012, Noah Spurrier <noah@noah.org>
+    PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
+    PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
+    COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
+    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+'''
+
+from pexpect import ExceptionPexpect, TIMEOUT, EOF, spawn
+import time
+import os
+
+__all__ = ['ExceptionPxssh', 'pxssh']
+
+# Exception classes used by this module.
+class ExceptionPxssh(ExceptionPexpect):
+    '''Raised for pxssh exceptions.
+    '''
+
+class pxssh (spawn):
+    '''This class extends pexpect.spawn to specialize setting up SSH
+    connections. This adds methods for login, logout, and expecting the shell
+    prompt. It does various tricky things to handle many situations in the SSH
+    login process. For example, if the session is your first login, then pxssh
+    automatically accepts the remote certificate; or if you have public key
+    authentication setup then pxssh won't wait for the password prompt.
+
+    pxssh uses the shell prompt to synchronize output from the remote host. In
+    order to make this more robust it sets the shell prompt to something more
+    unique than just $ or #. This should work on most Borne/Bash or Csh style
+    shells.
+
+    Example that runs a few commands on a remote server and prints the result::
+
+        from pexpect import pxssh
+        import getpass
+        try:
+            s = pxssh.pxssh()
+            hostname = raw_input('hostname: ')
+            username = raw_input('username: ')
+            password = getpass.getpass('password: ')
+            s.login(hostname, username, password)
+            s.sendline('uptime')   # run a command
+            s.prompt()             # match the prompt
+            print(s.before)        # print everything before the prompt.
+            s.sendline('ls -l')
+            s.prompt()
+            print(s.before)
+            s.sendline('df')
+            s.prompt()
+            print(s.before)
+            s.logout()
+        except pxssh.ExceptionPxssh as e:
+            print("pxssh failed on login.")
+            print(e)
+
+    Example showing how to specify SSH options::
+
+        from pexpect import pxssh
+        s = pxssh.pxssh(options={
+                            "StrictHostKeyChecking": "no",
+                            "UserKnownHostsFile": "/dev/null"})
+        ...
+
+    Note that if you have ssh-agent running while doing development with pxssh
+    then this can lead to a lot of confusion. Many X display managers (xdm,
+    gdm, kdm, etc.) will automatically start a GUI agent. You may see a GUI
+    dialog box popup asking for a password during development. You should turn
+    off any key agents during testing. The 'force_password' attribute will turn
+    off public key authentication. This will only work if the remote SSH server
+    is configured to allow password logins. Example of using 'force_password'
+    attribute::
+
+            s = pxssh.pxssh()
+            s.force_password = True
+            hostname = raw_input('hostname: ')
+            username = raw_input('username: ')
+            password = getpass.getpass('password: ')
+            s.login (hostname, username, password)
+    '''
+
+    def __init__ (self, timeout=30, maxread=2000, searchwindowsize=None,
+                    logfile=None, cwd=None, env=None, ignore_sighup=True, echo=True,
+                    options={}, encoding=None, codec_errors='strict'):
+
+        spawn.__init__(self, None, timeout=timeout, maxread=maxread,
+                       searchwindowsize=searchwindowsize, logfile=logfile,
+                       cwd=cwd, env=env, ignore_sighup=ignore_sighup, echo=echo,
+                       encoding=encoding, codec_errors=codec_errors)
+
+        self.name = '<pxssh>'
+
+        #SUBTLE HACK ALERT! Note that the command that SETS the prompt uses a
+        #slightly different string than the regular expression to match it. This
+        #is because when you set the prompt the command will echo back, but we
+        #don't want to match the echoed command. So if we make the set command
+        #slightly different than the regex we eliminate the problem. To make the
+        #set command different we add a backslash in front of $. The $ doesn't
+        #need to be escaped, but it doesn't hurt and serves to make the set
+        #prompt command different than the regex.
+
+        # used to match the command-line prompt
+        self.UNIQUE_PROMPT = "\[PEXPECT\][\$\#] "
+        self.PROMPT = self.UNIQUE_PROMPT
+
+        # used to set shell command-line prompt to UNIQUE_PROMPT.
+        self.PROMPT_SET_SH = "PS1='[PEXPECT]\$ '"
+        self.PROMPT_SET_CSH = "set prompt='[PEXPECT]\$ '"
+        self.SSH_OPTS = ("-o'RSAAuthentication=no'"
+                + " -o 'PubkeyAuthentication=no'")
+# Disabling host key checking, makes you vulnerable to MITM attacks.
+#                + " -o 'StrictHostKeyChecking=no'"
+#                + " -o 'UserKnownHostsFile /dev/null' ")
+        # Disabling X11 forwarding gets rid of the annoying SSH_ASKPASS from
+        # displaying a GUI password dialog. I have not figured out how to
+        # disable only SSH_ASKPASS without also disabling X11 forwarding.
+        # Unsetting SSH_ASKPASS on the remote side doesn't disable it! Annoying!
+        #self.SSH_OPTS = "-x -o'RSAAuthentication=no' -o 'PubkeyAuthentication=no'"
+        self.force_password = False
+
+        # User defined SSH options, eg,
+        # ssh.otions = dict(StrictHostKeyChecking="no",UserKnownHostsFile="/dev/null")
+        self.options = options
+
+    def levenshtein_distance(self, a, b):
+        '''This calculates the Levenshtein distance between a and b.
+        '''
+
+        n, m = len(a), len(b)
+        if n > m:
+            a,b = b,a
+            n,m = m,n
+        current = range(n+1)
+        for i in range(1,m+1):
+            previous, current = current, [i]+[0]*n
+            for j in range(1,n+1):
+                add, delete = previous[j]+1, current[j-1]+1
+                change = previous[j-1]
+                if a[j-1] != b[i-1]:
+                    change = change + 1
+                current[j] = min(add, delete, change)
+        return current[n]
+
+    def try_read_prompt(self, timeout_multiplier):
+        '''This facilitates using communication timeouts to perform
+        synchronization as quickly as possible, while supporting high latency
+        connections with a tunable worst case performance. Fast connections
+        should be read almost immediately. Worst case performance for this
+        method is timeout_multiplier * 3 seconds.
+        '''
+
+        # maximum time allowed to read the first response
+        first_char_timeout = timeout_multiplier * 0.5
+
+        # maximum time allowed between subsequent characters
+        inter_char_timeout = timeout_multiplier * 0.1
+
+        # maximum time for reading the entire prompt
+        total_timeout = timeout_multiplier * 3.0
+
+        prompt = self.string_type()
+        begin = time.time()
+        expired = 0.0
+        timeout = first_char_timeout
+
+        while expired < total_timeout:
+            try:
+                prompt += self.read_nonblocking(size=1, timeout=timeout)
+                expired = time.time() - begin # updated total time expired
+                timeout = inter_char_timeout
+            except TIMEOUT:
+                break
+
+        return prompt
+
+    def sync_original_prompt (self, sync_multiplier=1.0):
+        '''This attempts to find the prompt. Basically, press enter and record
+        the response; press enter again and record the response; if the two
+        responses are similar then assume we are at the original prompt.
+        This can be a slow function. Worst case with the default sync_multiplier
+        can take 12 seconds. Low latency connections are more likely to fail
+        with a low sync_multiplier. Best case sync time gets worse with a
+        high sync multiplier (500 ms with default). '''
+
+        # All of these timing pace values are magic.
+        # I came up with these based on what seemed reliable for
+        # connecting to a heavily loaded machine I have.
+        self.sendline()
+        time.sleep(0.1)
+
+        try:
+            # Clear the buffer before getting the prompt.
+            self.try_read_prompt(sync_multiplier)
+        except TIMEOUT:
+            pass
+
+        self.sendline()
+        x = self.try_read_prompt(sync_multiplier)
+
+        self.sendline()
+        a = self.try_read_prompt(sync_multiplier)
+
+        self.sendline()
+        b = self.try_read_prompt(sync_multiplier)
+
+        ld = self.levenshtein_distance(a,b)
+        len_a = len(a)
+        if len_a == 0:
+            return False
+        if float(ld)/len_a < 0.4:
+            return True
+        return False
+
+    ### TODO: This is getting messy and I'm pretty sure this isn't perfect.
+    ### TODO: I need to draw a flow chart for this.
+    def login (self, server, username, password='', terminal_type='ansi',
+                original_prompt=r"[#$]", login_timeout=10, port=None,
+                auto_prompt_reset=True, ssh_key=None, quiet=True,
+                sync_multiplier=1, check_local_ip=True):
+        '''This logs the user into the given server.
+
+        It uses
+        'original_prompt' to try to find the prompt right after login. When it
+        finds the prompt it immediately tries to reset the prompt to something
+        more easily matched. The default 'original_prompt' is very optimistic
+        and is easily fooled. It's more reliable to try to match the original
+        prompt as exactly as possible to prevent false matches by server
+        strings such as the "Message Of The Day". On many systems you can
+        disable the MOTD on the remote server by creating a zero-length file
+        called :file:`~/.hushlogin` on the remote server. If a prompt cannot be found
+        then this will not necessarily cause the login to fail. In the case of
+        a timeout when looking for the prompt we assume that the original
+        prompt was so weird that we could not match it, so we use a few tricks
+        to guess when we have reached the prompt. Then we hope for the best and
+        blindly try to reset the prompt to something more unique. If that fails
+        then login() raises an :class:`ExceptionPxssh` exception.
+
+        In some situations it is not possible or desirable to reset the
+        original prompt. In this case, pass ``auto_prompt_reset=False`` to
+        inhibit setting the prompt to the UNIQUE_PROMPT. Remember that pxssh
+        uses a unique prompt in the :meth:`prompt` method. If the original prompt is
+        not reset then this will disable the :meth:`prompt` method unless you
+        manually set the :attr:`PROMPT` attribute.
+        '''
+
+        ssh_options = ''.join([" -o '%s=%s'" % (o, v) for (o, v) in self.options.items()])
+        if quiet:
+            ssh_options = ssh_options + ' -q'
+        if not check_local_ip:
+            ssh_options = ssh_options + " -o'NoHostAuthenticationForLocalhost=yes'"
+        if self.force_password:
+            ssh_options = ssh_options + ' ' + self.SSH_OPTS
+        if port is not None:
+            ssh_options = ssh_options + ' -p %s'%(str(port))
+        if ssh_key is not None:
+            try:
+                os.path.isfile(ssh_key)
+            except:
+                raise ExceptionPxssh('private ssh key does not exist')
+            ssh_options = ssh_options + ' -i %s' % (ssh_key)
+        cmd = "ssh %s -l %s %s" % (ssh_options, username, server)
+
+        # This does not distinguish between a remote server 'password' prompt
+        # and a local ssh 'passphrase' prompt (for unlocking a private key).
+        spawn._spawn(self, cmd)
+        i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT, "(?i)connection closed by remote host"], timeout=login_timeout)
+
+        # First phase
+        if i==0:
+            # New certificate -- always accept it.
+            # This is what you get if SSH does not have the remote host's
+            # public key stored in the 'known_hosts' cache.
+            self.sendline("yes")
+            i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT])
+        if i==2: # password or passphrase
+            self.sendline(password)
+            i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT])
+        if i==4:
+            self.sendline(terminal_type)
+            i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT])
+
+        # Second phase
+        if i==0:
+            # This is weird. This should not happen twice in a row.
+            self.close()
+            raise ExceptionPxssh('Weird error. Got "are you sure" prompt twice.')
+        elif i==1: # can occur if you have a public key pair set to authenticate.
+            ### TODO: May NOT be OK if expect() got tricked and matched a false prompt.
+            pass
+        elif i==2: # password prompt again
+            # For incorrect passwords, some ssh servers will
+            # ask for the password again, others return 'denied' right away.
+            # If we get the password prompt again then this means
+            # we didn't get the password right the first time.
+            self.close()
+            raise ExceptionPxssh('password refused')
+        elif i==3: # permission denied -- password was bad.
+            self.close()
+            raise ExceptionPxssh('permission denied')
+        elif i==4: # terminal type again? WTF?
+            self.close()
+            raise ExceptionPxssh('Weird error. Got "terminal type" prompt twice.')
+        elif i==5: # Timeout
+            #This is tricky... I presume that we are at the command-line prompt.
+            #It may be that the shell prompt was so weird that we couldn't match
+            #it. Or it may be that we couldn't log in for some other reason. I
+            #can't be sure, but it's safe to guess that we did login because if
+            #I presume wrong and we are not logged in then this should be caught
+            #later when I try to set the shell prompt.
+            pass
+        elif i==6: # Connection closed by remote host
+            self.close()
+            raise ExceptionPxssh('connection closed')
+        else: # Unexpected
+            self.close()
+            raise ExceptionPxssh('unexpected login response')
+        if not self.sync_original_prompt(sync_multiplier):
+            self.close()
+            raise ExceptionPxssh('could not synchronize with original prompt')
+        # We appear to be in.
+        # set shell prompt to something unique.
+        if auto_prompt_reset:
+            if not self.set_unique_prompt():
+                self.close()
+                raise ExceptionPxssh('could not set shell prompt '
+                                     '(received: %r, expected: %r).' % (
+                                         self.before, self.PROMPT,))
+        return True
+
+    def logout (self):
+        '''Sends exit to the remote shell.
+
+        If there are stopped jobs then this automatically sends exit twice.
+        '''
+        self.sendline("exit")
+        index = self.expect([EOF, "(?i)there are stopped jobs"])
+        if index==1:
+            self.sendline("exit")
+            self.expect(EOF)
+        self.close()
+
+    def prompt(self, timeout=-1):
+        '''Match the next shell prompt.
+
+        This is little more than a short-cut to the :meth:`~pexpect.spawn.expect`
+        method. Note that if you called :meth:`login` with
+        ``auto_prompt_reset=False``, then before calling :meth:`prompt` you must
+        set the :attr:`PROMPT` attribute to a regex that it will use for
+        matching the prompt.
+
+        Calling :meth:`prompt` will erase the contents of the :attr:`before`
+        attribute even if no prompt is ever matched. If timeout is not given or
+        it is set to -1 then self.timeout is used.
+
+        :return: True if the shell prompt was matched, False if the timeout was
+                 reached.
+        '''
+
+        if timeout == -1:
+            timeout = self.timeout
+        i = self.expect([self.PROMPT, TIMEOUT], timeout=timeout)
+        if i==1:
+            return False
+        return True
+
+    def set_unique_prompt(self):
+        '''This sets the remote prompt to something more unique than ``#`` or ``$``.
+        This makes it easier for the :meth:`prompt` method to match the shell prompt
+        unambiguously. This method is called automatically by the :meth:`login`
+        method, but you may want to call it manually if you somehow reset the
+        shell prompt. For example, if you 'su' to a different user then you
+        will need to manually reset the prompt. This sends shell commands to
+        the remote host to set the prompt, so this assumes the remote host is
+        ready to receive commands.
+
+        Alternatively, you may use your own prompt pattern. In this case you
+        should call :meth:`login` with ``auto_prompt_reset=False``; then set the
+        :attr:`PROMPT` attribute to a regular expression. After that, the
+        :meth:`prompt` method will try to match your prompt pattern.
+        '''
+
+        self.sendline("unset PROMPT_COMMAND")
+        self.sendline(self.PROMPT_SET_SH) # sh-style
+        i = self.expect ([TIMEOUT, self.PROMPT], timeout=10)
+        if i == 0: # csh-style
+            self.sendline(self.PROMPT_SET_CSH)
+            i = self.expect([TIMEOUT, self.PROMPT], timeout=10)
+            if i == 0:
+                return False
+        return True
+
+# vi:ts=4:sw=4:expandtab:ft=python:

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/pexpect/replwrap.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/pexpect-4.2/pexpect/replwrap.py b/tools/bin/pythonSrc/pexpect-4.2/pexpect/replwrap.py
new file mode 100644
index 0000000..6439b35
--- /dev/null
+++ b/tools/bin/pythonSrc/pexpect-4.2/pexpect/replwrap.py
@@ -0,0 +1,113 @@
+"""Generic wrapper for read-eval-print-loops, a.k.a. interactive shells
+"""
+import os.path
+import signal
+import sys
+
+import pexpect
+
+PY3 = (sys.version_info[0] >= 3)
+
+if PY3:
+    basestring = str
+
+PEXPECT_PROMPT = u'[PEXPECT_PROMPT>'
+PEXPECT_CONTINUATION_PROMPT = u'[PEXPECT_PROMPT+'
+
+class REPLWrapper(object):
+    """Wrapper for a REPL.
+
+    :param cmd_or_spawn: This can either be an instance of :class:`pexpect.spawn`
+      in which a REPL has already been started, or a str command to start a new
+      REPL process.
+    :param str orig_prompt: The prompt to expect at first.
+    :param str prompt_change: A command to change the prompt to something more
+      unique. If this is ``None``, the prompt will not be changed. This will
+      be formatted with the new and continuation prompts as positional
+      parameters, so you can use ``{}`` style formatting to insert them into
+      the command.
+    :param str new_prompt: The more unique prompt to expect after the change.
+    :param str extra_init_cmd: Commands to do extra initialisation, such as
+      disabling pagers.
+    """
+    def __init__(self, cmd_or_spawn, orig_prompt, prompt_change,
+                 new_prompt=PEXPECT_PROMPT,
+                 continuation_prompt=PEXPECT_CONTINUATION_PROMPT,
+                 extra_init_cmd=None):
+        if isinstance(cmd_or_spawn, basestring):
+            self.child = pexpect.spawn(cmd_or_spawn, echo=False, encoding='utf-8')
+        else:
+            self.child = cmd_or_spawn
+        if self.child.echo:
+            # Existing spawn instance has echo enabled, disable it
+            # to prevent our input from being repeated to output.
+            self.child.setecho(False)
+            self.child.waitnoecho()
+
+        if prompt_change is None:
+            self.prompt = orig_prompt
+        else:
+            self.set_prompt(orig_prompt,
+                        prompt_change.format(new_prompt, continuation_prompt))
+            self.prompt = new_prompt
+        self.continuation_prompt = continuation_prompt
+
+        self._expect_prompt()
+
+        if extra_init_cmd is not None:
+            self.run_command(extra_init_cmd)
+
+    def set_prompt(self, orig_prompt, prompt_change):
+        self.child.expect(orig_prompt)
+        self.child.sendline(prompt_change)
+
+    def _expect_prompt(self, timeout=-1):
+        return self.child.expect_exact([self.prompt, self.continuation_prompt],
+                                       timeout=timeout)
+
+    def run_command(self, command, timeout=-1):
+        """Send a command to the REPL, wait for and return output.
+
+        :param str command: The command to send. Trailing newlines are not needed.
+          This should be a complete block of input that will trigger execution;
+          if a continuation prompt is found after sending input, :exc:`ValueError`
+          will be raised.
+        :param int timeout: How long to wait for the next prompt. -1 means the
+          default from the :class:`pexpect.spawn` object (default 30 seconds).
+          None means to wait indefinitely.
+        """
+        # Split up multiline commands and feed them in bit-by-bit
+        cmdlines = command.splitlines()
+        # splitlines ignores trailing newlines - add it back in manually
+        if command.endswith('\n'):
+            cmdlines.append('')
+        if not cmdlines:
+            raise ValueError("No command was given")
+
+        res = []
+        self.child.sendline(cmdlines[0])
+        for line in cmdlines[1:]:
+            self._expect_prompt(timeout=timeout)
+            res.append(self.child.before)
+            self.child.sendline(line)
+
+        # Command was fully submitted, now wait for the next prompt
+        if self._expect_prompt(timeout=timeout) == 1:
+            # We got the continuation prompt - command was incomplete
+            self.child.kill(signal.SIGINT)
+            self._expect_prompt(timeout=1)
+            raise ValueError("Continuation prompt found - input was incomplete:\n"
+                             + command)
+        return u''.join(res + [self.child.before])
+
+def python(command="python"):
+    """Start a Python shell and return a :class:`REPLWrapper` object."""
+    return REPLWrapper(command, u">>> ", u"import sys; sys.ps1={0!r}; sys.ps2={1!r}")
+
+def bash(command="bash"):
+    """Start a bash shell and return a :class:`REPLWrapper` object."""
+    bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
+    child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
+                          encoding='utf-8')
+    return REPLWrapper(child, u'\$', u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''",
+                       extra_init_cmd="export PAGER=cat")

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/pexpect/run.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/pexpect-4.2/pexpect/run.py b/tools/bin/pythonSrc/pexpect-4.2/pexpect/run.py
new file mode 100644
index 0000000..d9dfe76
--- /dev/null
+++ b/tools/bin/pythonSrc/pexpect-4.2/pexpect/run.py
@@ -0,0 +1,157 @@
+import sys
+import types
+
+from .exceptions import EOF, TIMEOUT
+from .pty_spawn import spawn
+
+def run(command, timeout=30, withexitstatus=False, events=None,
+        extra_args=None, logfile=None, cwd=None, env=None, **kwargs):
+
+    '''
+    This function runs the given command; waits for it to finish; then
+    returns all output as a string. STDERR is included in output. If the full
+    path to the command is not given then the path is searched.
+
+    Note that lines are terminated by CR/LF (\\r\\n) combination even on
+    UNIX-like systems because this is the standard for pseudottys. If you set
+    'withexitstatus' to true, then run will return a tuple of (command_output,
+    exitstatus). If 'withexitstatus' is false then this returns just
+    command_output.
+
+    The run() function can often be used instead of creating a spawn instance.
+    For example, the following code uses spawn::
+
+        from pexpect import *
+        child = spawn('scp foo user@example.com:.')
+        child.expect('(?i)password')
+        child.sendline(mypassword)
+
+    The previous code can be replace with the following::
+
+        from pexpect import *
+        run('scp foo user@example.com:.', events={'(?i)password': mypassword})
+
+    **Examples**
+
+    Start the apache daemon on the local machine::
+
+        from pexpect import *
+        run("/usr/local/apache/bin/apachectl start")
+
+    Check in a file using SVN::
+
+        from pexpect import *
+        run("svn ci -m 'automatic commit' my_file.py")
+
+    Run a command and capture exit status::
+
+        from pexpect import *
+        (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1)
+
+    The following will run SSH and execute 'ls -l' on the remote machine. The
+    password 'secret' will be sent if the '(?i)password' pattern is ever seen::
+
+        run("ssh username@machine.example.com 'ls -l'",
+            events={'(?i)password':'secret\\n'})
+
+    This will start mencoder to rip a video from DVD. This will also display
+    progress ticks every 5 seconds as it runs. For example::
+
+        from pexpect import *
+        def print_ticks(d):
+            print d['event_count'],
+        run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
+            events={TIMEOUT:print_ticks}, timeout=5)
+
+    The 'events' argument should be either a dictionary or a tuple list that
+    contains patterns and responses. Whenever one of the patterns is seen
+    in the command output, run() will send the associated response string.
+    So, run() in the above example can be also written as:
+    
+        run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
+            events=[(TIMEOUT,print_ticks)], timeout=5)
+
+    Use a tuple list for events if the command output requires a delicate
+    control over what pattern should be matched, since the tuple list is passed
+    to pexpect() as its pattern list, with the order of patterns preserved.
+
+    Note that you should put newlines in your string if Enter is necessary.
+
+    Like the example above, the responses may also contain a callback, either
+    a function or method.  It should accept a dictionary value as an argument.
+    The dictionary contains all the locals from the run() function, so you can
+    access the child spawn object or any other variable defined in run()
+    (event_count, child, and extra_args are the most useful). A callback may
+    return True to stop the current run process.  Otherwise run() continues
+    until the next event. A callback may also return a string which will be
+    sent to the child. 'extra_args' is not used by directly run(). It provides
+    a way to pass data to a callback function through run() through the locals
+    dictionary passed to a callback.
+
+    Like :class:`spawn`, passing *encoding* will make it work with unicode
+    instead of bytes. You can pass *codec_errors* to control how errors in
+    encoding and decoding are handled.
+    '''
+    if timeout == -1:
+        child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env,
+                        **kwargs)
+    else:
+        child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile,
+                cwd=cwd, env=env, **kwargs)
+    if isinstance(events, list):
+        patterns= [x for x,y in events]
+        responses = [y for x,y in events]
+    elif isinstance(events, dict):
+        patterns = list(events.keys())
+        responses = list(events.values())
+    else:
+        # This assumes EOF or TIMEOUT will eventually cause run to terminate.
+        patterns = None
+        responses = None
+    child_result_list = []
+    event_count = 0
+    while True:
+        try:
+            index = child.expect(patterns)
+            if isinstance(child.after, child.allowed_string_types):
+                child_result_list.append(child.before + child.after)
+            else:
+                # child.after may have been a TIMEOUT or EOF,
+                # which we don't want appended to the list.
+                child_result_list.append(child.before)
+            if isinstance(responses[index], child.allowed_string_types):
+                child.send(responses[index])
+            elif (isinstance(responses[index], types.FunctionType) or
+                  isinstance(responses[index], types.MethodType)):
+                callback_result = responses[index](locals())
+                sys.stdout.flush()
+                if isinstance(callback_result, child.allowed_string_types):
+                    child.send(callback_result)
+                elif callback_result:
+                    break
+            else:
+                raise TypeError("parameter `event' at index {index} must be "
+                                "a string, method, or function: {value!r}"
+                                .format(index=index, value=responses[index]))
+            event_count = event_count + 1
+        except TIMEOUT:
+            child_result_list.append(child.before)
+            break
+        except EOF:
+            child_result_list.append(child.before)
+            break
+    child_result = child.string_type().join(child_result_list)
+    if withexitstatus:
+        child.close()
+        return (child_result, child.exitstatus)
+    else:
+        return child_result
+
+def runu(command, timeout=30, withexitstatus=False, events=None,
+        extra_args=None, logfile=None, cwd=None, env=None, **kwargs):
+    """Deprecated: pass encoding to run() instead.
+    """
+    kwargs.setdefault('encoding', 'utf-8')
+    return run(command, timeout=timeout, withexitstatus=withexitstatus,
+                events=events, extra_args=extra_args, logfile=logfile, cwd=cwd,
+                env=env, **kwargs)

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/pexpect/screen.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/pexpect-4.2/pexpect/screen.py b/tools/bin/pythonSrc/pexpect-4.2/pexpect/screen.py
new file mode 100644
index 0000000..0bced89
--- /dev/null
+++ b/tools/bin/pythonSrc/pexpect-4.2/pexpect/screen.py
@@ -0,0 +1,431 @@
+'''This implements a virtual screen. This is used to support ANSI terminal
+emulation. The screen representation and state is implemented in this class.
+Most of the methods are inspired by ANSI screen control codes. The
+:class:`~pexpect.ANSI.ANSI` class extends this class to add parsing of ANSI
+escape codes.
+
+PEXPECT LICENSE
+
+    This license is approved by the OSI and FSF as GPL-compatible.
+        http://opensource.org/licenses/isc-license.txt
+
+    Copyright (c) 2012, Noah Spurrier <noah@noah.org>
+    PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
+    PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
+    COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
+    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+'''
+
+import codecs
+import copy
+import sys
+
+import warnings
+
+warnings.warn(("pexpect.screen and pexpect.ANSI are deprecated. "
+               "We recommend using pyte to emulate a terminal screen: "
+               "https://pypi.python.org/pypi/pyte"),
+               stacklevel=2)
+
+NUL = 0    # Fill character; ignored on input.
+ENQ = 5    # Transmit answerback message.
+BEL = 7    # Ring the bell.
+BS  = 8    # Move cursor left.
+HT  = 9    # Move cursor to next tab stop.
+LF = 10    # Line feed.
+VT = 11    # Same as LF.
+FF = 12    # Same as LF.
+CR = 13    # Move cursor to left margin or newline.
+SO = 14    # Invoke G1 character set.
+SI = 15    # Invoke G0 character set.
+XON = 17   # Resume transmission.
+XOFF = 19  # Halt transmission.
+CAN = 24   # Cancel escape sequence.
+SUB = 26   # Same as CAN.
+ESC = 27   # Introduce a control sequence.
+DEL = 127  # Fill character; ignored on input.
+SPACE = u' ' # Space or blank character.
+
+PY3 = (sys.version_info[0] >= 3)
+if PY3:
+    unicode = str
+
+def constrain (n, min, max):
+
+    '''This returns a number, n constrained to the min and max bounds. '''
+
+    if n < min:
+        return min
+    if n > max:
+        return max
+    return n
+
+class screen:
+    '''This object maintains the state of a virtual text screen as a
+    rectangluar array. This maintains a virtual cursor position and handles
+    scrolling as characters are added. This supports most of the methods needed
+    by an ANSI text screen. Row and column indexes are 1-based (not zero-based,
+    like arrays).
+
+    Characters are represented internally using unicode. Methods that accept
+    input characters, when passed 'bytes' (which in Python 2 is equivalent to
+    'str'), convert them from the encoding specified in the 'encoding'
+    parameter to the constructor. Methods that return screen contents return
+    unicode strings, with the exception of __str__() under Python 2. Passing
+    ``encoding=None`` limits the API to only accept unicode input, so passing
+    bytes in will raise :exc:`TypeError`.
+    '''
+    def __init__(self, r=24, c=80, encoding='latin-1', encoding_errors='replace'):
+        '''This initializes a blank screen of the given dimensions.'''
+
+        self.rows = r
+        self.cols = c
+        self.encoding = encoding
+        self.encoding_errors = encoding_errors
+        if encoding is not None:
+            self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors)            
+        else:
+            self.decoder = None
+        self.cur_r = 1
+        self.cur_c = 1
+        self.cur_saved_r = 1
+        self.cur_saved_c = 1
+        self.scroll_row_start = 1
+        self.scroll_row_end = self.rows
+        self.w = [ [SPACE] * self.cols for _ in range(self.rows)]
+
+    def _decode(self, s):
+        '''This converts from the external coding system (as passed to
+        the constructor) to the internal one (unicode). '''
+        if self.decoder is not None:
+            return self.decoder.decode(s)
+        else:
+            raise TypeError("This screen was constructed with encoding=None, "
+                            "so it does not handle bytes.")
+
+    def _unicode(self):
+        '''This returns a printable representation of the screen as a unicode
+        string (which, under Python 3.x, is the same as 'str'). The end of each
+        screen line is terminated by a newline.'''
+
+        return u'\n'.join ([ u''.join(c) for c in self.w ])
+
+    if PY3:
+        __str__ = _unicode
+    else:
+        __unicode__ = _unicode
+
+        def __str__(self):
+            '''This returns a printable representation of the screen. The end of
+            each screen line is terminated by a newline. '''
+            encoding = self.encoding or 'ascii'
+            return self._unicode().encode(encoding, 'replace')
+
+    def dump (self):
+        '''This returns a copy of the screen as a unicode string. This is similar to
+        __str__/__unicode__ except that lines are not terminated with line
+        feeds.'''
+
+        return u''.join ([ u''.join(c) for c in self.w ])
+
+    def pretty (self):
+        '''This returns a copy of the screen as a unicode string with an ASCII
+        text box around the screen border. This is similar to
+        __str__/__unicode__ except that it adds a box.'''
+
+        top_bot = u'+' + u'-'*self.cols + u'+\n'
+        return top_bot + u'\n'.join([u'|'+line+u'|' for line in unicode(self).split(u'\n')]) + u'\n' + top_bot
+
+    def fill (self, ch=SPACE):
+
+        if isinstance(ch, bytes):
+            ch = self._decode(ch)
+
+        self.fill_region (1,1,self.rows,self.cols, ch)
+
+    def fill_region (self, rs,cs, re,ce, ch=SPACE):
+
+        if isinstance(ch, bytes):
+            ch = self._decode(ch)
+
+        rs = constrain (rs, 1, self.rows)
+        re = constrain (re, 1, self.rows)
+        cs = constrain (cs, 1, self.cols)
+        ce = constrain (ce, 1, self.cols)
+        if rs > re:
+            rs, re = re, rs
+        if cs > ce:
+            cs, ce = ce, cs
+        for r in range (rs, re+1):
+            for c in range (cs, ce + 1):
+                self.put_abs (r,c,ch)
+
+    def cr (self):
+        '''This moves the cursor to the beginning (col 1) of the current row.
+        '''
+
+        self.cursor_home (self.cur_r, 1)
+
+    def lf (self):
+        '''This moves the cursor down with scrolling.
+        '''
+
+        old_r = self.cur_r
+        self.cursor_down()
+        if old_r == self.cur_r:
+            self.scroll_up ()
+            self.erase_line()
+
+    def crlf (self):
+        '''This advances the cursor with CRLF properties.
+        The cursor will line wrap and the screen may scroll.
+        '''
+
+        self.cr ()
+        self.lf ()
+
+    def newline (self):
+        '''This is an alias for crlf().
+        '''
+
+        self.crlf()
+
+    def put_abs (self, r, c, ch):
+        '''Screen array starts at 1 index.'''
+
+        r = constrain (r, 1, self.rows)
+        c = constrain (c, 1, self.cols)
+        if isinstance(ch, bytes):
+            ch = self._decode(ch)[0]
+        else:
+            ch = ch[0]
+        self.w[r-1][c-1] = ch
+
+    def put (self, ch):
+        '''This puts a characters at the current cursor position.
+        '''
+
+        if isinstance(ch, bytes):
+            ch = self._decode(ch)
+
+        self.put_abs (self.cur_r, self.cur_c, ch)
+
+    def insert_abs (self, r, c, ch):
+        '''This inserts a character at (r,c). Everything under
+        and to the right is shifted right one character.
+        The last character of the line is lost.
+        '''
+
+        if isinstance(ch, bytes):
+            ch = self._decode(ch)
+
+        r = constrain (r, 1, self.rows)
+        c = constrain (c, 1, self.cols)
+        for ci in range (self.cols, c, -1):
+            self.put_abs (r,ci, self.get_abs(r,ci-1))
+        self.put_abs (r,c,ch)
+
+    def insert (self, ch):
+
+        if isinstance(ch, bytes):
+            ch = self._decode(ch)
+
+        self.insert_abs (self.cur_r, self.cur_c, ch)
+
+    def get_abs (self, r, c):
+
+        r = constrain (r, 1, self.rows)
+        c = constrain (c, 1, self.cols)
+        return self.w[r-1][c-1]
+
+    def get (self):
+
+        self.get_abs (self.cur_r, self.cur_c)
+
+    def get_region (self, rs,cs, re,ce):
+        '''This returns a list of lines representing the region.
+        '''
+
+        rs = constrain (rs, 1, self.rows)
+        re = constrain (re, 1, self.rows)
+        cs = constrain (cs, 1, self.cols)
+        ce = constrain (ce, 1, self.cols)
+        if rs > re:
+            rs, re = re, rs
+        if cs > ce:
+            cs, ce = ce, cs
+        sc = []
+        for r in range (rs, re+1):
+            line = u''
+            for c in range (cs, ce + 1):
+                ch = self.get_abs (r,c)
+                line = line + ch
+            sc.append (line)
+        return sc
+
+    def cursor_constrain (self):
+        '''This keeps the cursor within the screen area.
+        '''
+
+        self.cur_r = constrain (self.cur_r, 1, self.rows)
+        self.cur_c = constrain (self.cur_c, 1, self.cols)
+
+    def cursor_home (self, r=1, c=1): # <ESC>[{ROW};{COLUMN}H
+
+        self.cur_r = r
+        self.cur_c = c
+        self.cursor_constrain ()
+
+    def cursor_back (self,count=1): # <ESC>[{COUNT}D (not confused with down)
+
+        self.cur_c = self.cur_c - count
+        self.cursor_constrain ()
+
+    def cursor_down (self,count=1): # <ESC>[{COUNT}B (not confused with back)
+
+        self.cur_r = self.cur_r + count
+        self.cursor_constrain ()
+
+    def cursor_forward (self,count=1): # <ESC>[{COUNT}C
+
+        self.cur_c = self.cur_c + count
+        self.cursor_constrain ()
+
+    def cursor_up (self,count=1): # <ESC>[{COUNT}A
+
+        self.cur_r = self.cur_r - count
+        self.cursor_constrain ()
+
+    def cursor_up_reverse (self): # <ESC> M   (called RI -- Reverse Index)
+
+        old_r = self.cur_r
+        self.cursor_up()
+        if old_r == self.cur_r:
+            self.scroll_up()
+
+    def cursor_force_position (self, r, c): # <ESC>[{ROW};{COLUMN}f
+        '''Identical to Cursor Home.'''
+
+        self.cursor_home (r, c)
+
+    def cursor_save (self): # <ESC>[s
+        '''Save current cursor position.'''
+
+        self.cursor_save_attrs()
+
+    def cursor_unsave (self): # <ESC>[u
+        '''Restores cursor position after a Save Cursor.'''
+
+        self.cursor_restore_attrs()
+
+    def cursor_save_attrs (self): # <ESC>7
+        '''Save current cursor position.'''
+
+        self.cur_saved_r = self.cur_r
+        self.cur_saved_c = self.cur_c
+
+    def cursor_restore_attrs (self): # <ESC>8
+        '''Restores cursor position after a Save Cursor.'''
+
+        self.cursor_home (self.cur_saved_r, self.cur_saved_c)
+
+    def scroll_constrain (self):
+        '''This keeps the scroll region within the screen region.'''
+
+        if self.scroll_row_start <= 0:
+            self.scroll_row_start = 1
+        if self.scroll_row_end > self.rows:
+            self.scroll_row_end = self.rows
+
+    def scroll_screen (self): # <ESC>[r
+        '''Enable scrolling for entire display.'''
+
+        self.scroll_row_start = 1
+        self.scroll_row_end = self.rows
+
+    def scroll_screen_rows (self, rs, re): # <ESC>[{start};{end}r
+        '''Enable scrolling from row {start} to row {end}.'''
+
+        self.scroll_row_start = rs
+        self.scroll_row_end = re
+        self.scroll_constrain()
+
+    def scroll_down (self): # <ESC>D
+        '''Scroll display down one line.'''
+
+        # Screen is indexed from 1, but arrays are indexed from 0.
+        s = self.scroll_row_start - 1
+        e = self.scroll_row_end - 1
+        self.w[s+1:e+1] = copy.deepcopy(self.w[s:e])
+
+    def scroll_up (self): # <ESC>M
+        '''Scroll display up one line.'''
+
+        # Screen is indexed from 1, but arrays are indexed from 0.
+        s = self.scroll_row_start - 1
+        e = self.scroll_row_end - 1
+        self.w[s:e] = copy.deepcopy(self.w[s+1:e+1])
+
+    def erase_end_of_line (self): # <ESC>[0K -or- <ESC>[K
+        '''Erases from the current cursor position to the end of the current
+        line.'''
+
+        self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols)
+
+    def erase_start_of_line (self): # <ESC>[1K
+        '''Erases from the current cursor position to the start of the current
+        line.'''
+
+        self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c)
+
+    def erase_line (self): # <ESC>[2K
+        '''Erases the entire current line.'''
+
+        self.fill_region (self.cur_r, 1, self.cur_r, self.cols)
+
+    def erase_down (self): # <ESC>[0J -or- <ESC>[J
+        '''Erases the screen from the current line down to the bottom of the
+        screen.'''
+
+        self.erase_end_of_line ()
+        self.fill_region (self.cur_r + 1, 1, self.rows, self.cols)
+
+    def erase_up (self): # <ESC>[1J
+        '''Erases the screen from the current line up to the top of the
+        screen.'''
+
+        self.erase_start_of_line ()
+        self.fill_region (self.cur_r-1, 1, 1, self.cols)
+
+    def erase_screen (self): # <ESC>[2J
+        '''Erases the screen with the background color.'''
+
+        self.fill ()
+
+    def set_tab (self): # <ESC>H
+        '''Sets a tab at the current position.'''
+
+        pass
+
+    def clear_tab (self): # <ESC>[g
+        '''Clears tab at the current position.'''
+
+        pass
+
+    def clear_all_tabs (self): # <ESC>[3g
+        '''Clears all tabs.'''
+
+        pass
+
+#        Insert line             Esc [ Pn L
+#        Delete line             Esc [ Pn M
+#        Delete character        Esc [ Pn P
+#        Scrolling region        Esc [ Pn(top);Pn(bot) r
+


Mime
View raw message