Hello community, here is the log from the commit of package python-pexpect for openSUSE:Factory checked in at 2020-02-19 12:40:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pexpect (Old) and /work/SRC/openSUSE:Factory/.python-pexpect.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pexpect" Wed Feb 19 12:40:04 2020 rev:32 rq:774361 version:4.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pexpect/python-pexpect.changes 2020-02-13 10:10:57.552320615 +0100 +++ /work/SRC/openSUSE:Factory/.python-pexpect.new.26092/python-pexpect.changes 2020-02-19 12:40:09.507580493 +0100 @@ -1,0 +2,12 @@ +Fri Feb 14 12:44:51 UTC 2020 - Ondřej Súkup <[email protected]> + +- update to 4.8.0 + * Returned behavior of searchwindowsize to that in 4.3 and earlier + * Fixed a bug truncating before attribute after a timeout + * Fixed a bug where a search could be less than searchwindowsize + if it was increased between calls + * Minor test cleanups to improve portability + * Disable chaining of timeout and EOF exceptions + * Several doc updates. + +------------------------------------------------------------------- Old: ---- pexpect-4.7.0.tar.gz New: ---- pexpect-4.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pexpect.spec ++++++ --- /var/tmp/diff_new_pack.z4nFju/_old 2020-02-19 12:40:12.891587009 +0100 +++ /var/tmp/diff_new_pack.z4nFju/_new 2020-02-19 12:40:12.891587009 +0100 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pexpect -Version: 4.7.0 +Version: 4.8.0 Release: 0 Summary: Pure Python Expect-like module License: ISC ++++++ pexpect-4.7.0.tar.gz -> pexpect-4.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/.coveragerc new/pexpect-4.8.0/.coveragerc --- old/pexpect-4.7.0/.coveragerc 1970-01-01 01:00:00.000000000 +0100 +++ new/pexpect-4.8.0/.coveragerc 2020-01-17 18:08:15.000000000 +0100 @@ -0,0 +1,3 @@ +[run] +source = pexpect +parallel = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/PKG-INFO new/pexpect-4.8.0/PKG-INFO --- old/pexpect-4.7.0/PKG-INFO 2019-04-07 03:54:58.000000000 +0200 +++ new/pexpect-4.8.0/PKG-INFO 2020-01-21 17:29:55.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pexpect -Version: 4.7.0 +Version: 4.8.0 Summary: Pexpect allows easy control of interactive console applications. Home-page: https://pexpect.readthedocs.io/ Author: Noah Spurrier; Thomas Kluyver; Jeff Quast diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/README.rst new/pexpect-4.8.0/README.rst --- old/pexpect-4.7.0/README.rst 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/README.rst 2020-01-17 18:08:15.000000000 +0100 @@ -13,7 +13,7 @@ control it as if a human were typing commands. Pexpect can be used for automating interactive applications such as ssh, ftp, -passwd, telnet, etc. It can be used to a automate setup scripts for duplicating +passwd, telnet, etc. It can be used to automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/doc/api/pxssh.rst new/pexpect-4.8.0/doc/api/pxssh.rst --- old/pexpect-4.7.0/doc/api/pxssh.rst 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/doc/api/pxssh.rst 2020-01-17 18:08:15.000000000 +0100 @@ -5,9 +5,16 @@ *pxssh* is a screen-scraping wrapper around the SSH command on your system. In many cases, you should consider using - `Paramiko <https://github.com/paramiko/paramiko>`_ instead. + `Paramiko <https://github.com/paramiko/paramiko>`_ or + `RedExpect <https://github.com/Red-M/RedExpect>`_ instead. Paramiko is a Python module which speaks the SSH protocol directly, so it doesn't have the extra complexity of running a local subprocess. + RedExpect is very similar to pxssh except that it reads and writes directly + into an SSH session all done via Python with all the SSH protocol in C, + additionally it is written for communicating to SSH servers that are not just + Linux machines. Meaning that it is extremely fast in comparison to Paramiko + and already has the familiar expect API. In most cases RedExpect and pxssh + code should be fairly interchangeable. .. automodule:: pexpect.pxssh @@ -27,7 +34,7 @@ .. attribute:: force_password - If this is set to True, public key authentication is disabled, forcing the + If this is set to ``True``, public key authentication is disabled, forcing the server to ask for a password. Note that the sysadmin can disable password logins, in which case this won't work. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/doc/commonissues.rst new/pexpect-4.8.0/doc/commonissues.rst --- old/pexpect-4.7.0/doc/commonissues.rst 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/doc/commonissues.rst 2020-01-17 18:08:15.000000000 +0100 @@ -41,10 +41,10 @@ Pexpect now automatically adds a short delay before sending data to a child process. This more closely mimics what happens in the usual human-to-app -interaction. The delay can be tuned with the ``delaybeforesend`` attribute of the -spawn class. In general, this fixes the problem for everyone and so this should -not be an issue for most users. For some applications you might with to turn it -off:: +interaction. The delay can be tuned with the ``delaybeforesend`` attribute of +objects of the spawn class. In general, this fixes the problem for everyone and so +this should not be an issue for most users. For some applications you might with +to turn it off:: child = pexpect.spawn ("ssh [email protected]") child.delaybeforesend = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/doc/conf.py new/pexpect-4.8.0/doc/conf.py --- old/pexpect-4.7.0/doc/conf.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/doc/conf.py 2020-01-17 18:08:15.000000000 +0100 @@ -52,7 +52,7 @@ # built documents. # # The short X.Y version. -version = '4.7' +version = '4.8' # The full version, including alpha/beta/rc tags. release = version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/doc/examples.rst new/pexpect-4.8.0/doc/examples.rst --- old/pexpect-4.7.0/doc/examples.rst 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/doc/examples.rst 2020-01-17 18:08:15.000000000 +0100 @@ -48,7 +48,7 @@ `python.py <https://github.com/pexpect/pexpect/blob/master/examples/python.py>`_ This starts the python interpreter and prints the greeting message - backwards. It then gives the user iteractive control of Python. It's + backwards. It then gives the user interactive control of Python. It's pretty useless! `ssh_tunnel.py <https://github.com/pexpect/pexpect/blob/master/examples/ssh_tunnel.py>`_ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/doc/history.rst new/pexpect-4.8.0/doc/history.rst --- old/pexpect-4.7.0/doc/history.rst 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/doc/history.rst 2020-01-17 18:08:15.000000000 +0100 @@ -4,6 +4,22 @@ Releases -------- +Version 4.8 +``````````` + +* Returned behavior of searchwindowsize to that in 4.3 and earlier (searches + are only done within the search window) (:ghpull:`579`). +* Fixed a bug truncating ``before`` attribute after a timeout (:ghpull:`579`). +* Fixed a bug where a search could be less than ``searchwindowsize`` if it + was increased between calls (:ghpull:`579`). +* Minor test cleanups to improve portability (:ghpull:`580`) (:ghpull:`581`) + (:ghpull:`582`) (:ghpull:`583`) (:ghpull:`584`) (:ghpull:`585`). +* Disable chaining of timeout and EOF exceptions (:gphull:`606`). +* Allow traceback included snippet length to be configured via + ``str_last_chars`` rather than always 100 (:ghpull:`598`). +* Python 3 warning added to interact.py (:ghpull:`537`). +* Several doc updates. + Version 4.7 ``````````` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/examples/astat.py new/pexpect-4.8.0/examples/astat.py --- old/pexpect-4.7.0/examples/astat.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/examples/astat.py 2020-01-17 18:08:15.000000000 +0100 @@ -38,7 +38,7 @@ import sys import getopt import getpass -import pxssh +from pexpect import pxssh try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/examples/chess.py new/pexpect-4.8.0/examples/chess.py --- old/pexpect-4.7.0/examples/chess.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/examples/chess.py 2020-01-17 18:08:15.000000000 +0100 @@ -27,7 +27,7 @@ from __future__ import absolute_import import pexpect -import ANSI +from pexpect import ANSI REGEX_MOVE = r'(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' REGEX_MOVE_PART = r'(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/examples/chess2.py new/pexpect-4.8.0/examples/chess2.py --- old/pexpect-4.7.0/examples/chess2.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/examples/chess2.py 2020-01-17 18:08:15.000000000 +0100 @@ -27,7 +27,7 @@ from __future__ import absolute_import import pexpect -import ANSI +from pexpect import ANSI import sys import time diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/examples/chess3.py new/pexpect-4.8.0/examples/chess3.py --- old/pexpect-4.7.0/examples/chess3.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/examples/chess3.py 2020-01-17 18:08:15.000000000 +0100 @@ -27,7 +27,7 @@ from __future__ import absolute_import import pexpect -import ANSI +from pexpect import ANSI REGEX_MOVE = r'(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' REGEX_MOVE_PART = r'(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/examples/hive.py new/pexpect-4.8.0/examples/hive.py --- old/pexpect-4.7.0/examples/hive.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/examples/hive.py 2020-01-17 18:08:15.000000000 +0100 @@ -94,7 +94,7 @@ import atexit try: import pexpect - import pxssh + from pexpect import pxssh except ImportError: sys.stderr.write("You do not have 'pexpect' installed.\n") sys.stderr.write("On Ubuntu you need the 'python-pexpect' package.\n") @@ -436,7 +436,7 @@ def parse_host_connect_string (hcs): '''This parses a host connection string in the form - username:password@hostname:port. All fields are options expcet hostname. A + username:password@hostname:port. All fields are optional except hostname. A dictionary is returned with all four keys. Keys that were not included are set to empty strings ''. Note that if your password has the '@' character then you must backslash escape it. ''' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/examples/topip.py new/pexpect-4.8.0/examples/topip.py --- old/pexpect-4.7.0/examples/topip.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/examples/topip.py 2020-01-17 18:08:15.000000000 +0100 @@ -70,7 +70,7 @@ # See http://pexpect.sourceforge.net/ import pexpect -import pxssh +from pexpect import pxssh import os import sys import time diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/__init__.py new/pexpect-4.8.0/pexpect/__init__.py --- old/pexpect-4.7.0/pexpect/__init__.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/__init__.py 2020-01-17 18:08:15.000000000 +0100 @@ -75,7 +75,7 @@ from .pty_spawn import spawn, spawnu from .run import run, runu -__version__ = '4.7.0' +__version__ = '4.8.0' __revision__ = '' __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnu', 'run', 'runu', 'which', 'split_command_line', '__version__', '__revision__'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/_async.py new/pexpect-4.8.0/pexpect/_async.py --- old/pexpect-4.7.0/pexpect/_async.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/_async.py 2020-01-17 18:08:15.000000000 +0100 @@ -8,10 +8,7 @@ def expect_async(expecter, timeout=None): # First process data that was previously read - if it maches, we don't need # async stuff. - previously_read = expecter.spawn.buffer - expecter.spawn._buffer = expecter.spawn.buffer_type() - expecter.spawn._before = expecter.spawn.buffer_type() - idx = expecter.new_data(previously_read) + idx = expecter.existing_data() if idx is not None: return idx if not expecter.spawn.async_pw_transport: @@ -74,6 +71,7 @@ spawn._log(s, 'read') if self.fut.done(): + spawn._before.write(s) spawn._buffer.write(s) return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/expect.py new/pexpect-4.8.0/pexpect/expect.py --- old/pexpect-4.7.0/pexpect/expect.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/expect.py 2020-01-17 18:08:15.000000000 +0100 @@ -6,45 +6,101 @@ def __init__(self, spawn, searcher, searchwindowsize=-1): self.spawn = spawn self.searcher = searcher + # A value of -1 means to use the figure from spawn, which should + # be None or a positive number. if searchwindowsize == -1: searchwindowsize = spawn.searchwindowsize self.searchwindowsize = searchwindowsize + self.lookback = None + if hasattr(searcher, 'longest_string'): + self.lookback = searcher.longest_string - def new_data(self, data): + def do_search(self, window, freshlen): spawn = self.spawn searcher = self.searcher - - pos = spawn._buffer.tell() - spawn._buffer.write(data) - spawn._before.write(data) - - # determine which chunk of data to search; if a windowsize is - # specified, this is the *new* data + the preceding <windowsize> bytes - if self.searchwindowsize: - spawn._buffer.seek(max(0, pos - self.searchwindowsize)) - window = spawn._buffer.read(self.searchwindowsize + len(data)) - else: - # otherwise, search the whole buffer (really slow for large datasets) - window = spawn.buffer - index = searcher.search(window, len(data)) + if freshlen > len(window): + freshlen = len(window) + index = searcher.search(window, freshlen, self.searchwindowsize) if index >= 0: spawn._buffer = spawn.buffer_type() spawn._buffer.write(window[searcher.end:]) - spawn.before = spawn._before.getvalue()[0:-(len(window) - searcher.start)] + spawn.before = spawn._before.getvalue()[ + 0:-(len(window) - searcher.start)] spawn._before = spawn.buffer_type() - spawn.after = window[searcher.start: searcher.end] + spawn._before.write(window[searcher.end:]) + spawn.after = window[searcher.start:searcher.end] spawn.match = searcher.match spawn.match_index = index # Found a match return index - elif self.searchwindowsize: - spawn._buffer = spawn.buffer_type() - spawn._buffer.write(window) + elif self.searchwindowsize or self.lookback: + maintain = self.searchwindowsize or self.lookback + if spawn._buffer.tell() > maintain: + spawn._buffer = spawn.buffer_type() + spawn._buffer.write(window[-maintain:]) + + def existing_data(self): + # First call from a new call to expect_loop or expect_async. + # self.searchwindowsize may have changed. + # Treat all data as fresh. + spawn = self.spawn + before_len = spawn._before.tell() + buf_len = spawn._buffer.tell() + freshlen = before_len + if before_len > buf_len: + if not self.searchwindowsize: + spawn._buffer = spawn.buffer_type() + window = spawn._before.getvalue() + spawn._buffer.write(window) + elif buf_len < self.searchwindowsize: + spawn._buffer = spawn.buffer_type() + spawn._before.seek( + max(0, before_len - self.searchwindowsize)) + window = spawn._before.read() + spawn._buffer.write(window) + else: + spawn._buffer.seek(max(0, buf_len - self.searchwindowsize)) + window = spawn._buffer.read() + else: + if self.searchwindowsize: + spawn._buffer.seek(max(0, buf_len - self.searchwindowsize)) + window = spawn._buffer.read() + else: + window = spawn._buffer.getvalue() + return self.do_search(window, freshlen) + + def new_data(self, data): + # A subsequent call, after a call to existing_data. + spawn = self.spawn + freshlen = len(data) + spawn._before.write(data) + if not self.searchwindowsize: + if self.lookback: + # search lookback + new data. + old_len = spawn._buffer.tell() + spawn._buffer.write(data) + spawn._buffer.seek(max(0, old_len - self.lookback)) + window = spawn._buffer.read() + else: + # copy the whole buffer (really slow for large datasets). + spawn._buffer.write(data) + window = spawn.buffer + else: + if len(data) >= self.searchwindowsize or not spawn._buffer.tell(): + window = data[-self.searchwindowsize:] + spawn._buffer = spawn.buffer_type() + spawn._buffer.write(window[-self.searchwindowsize:]) + else: + spawn._buffer.write(data) + new_len = spawn._buffer.tell() + spawn._buffer.seek(max(0, new_len - self.searchwindowsize)) + window = spawn._buffer.read() + return self.do_search(window, freshlen) def eof(self, err=None): spawn = self.spawn - spawn.before = spawn.buffer + spawn.before = spawn._before.getvalue() spawn._buffer = spawn.buffer_type() spawn._before = spawn.buffer_type() spawn.after = EOF @@ -60,12 +116,15 @@ msg += '\nsearcher: %s' % self.searcher if err is not None: msg = str(err) + '\n' + msg - raise EOF(msg) - + + exc = EOF(msg) + exc.__cause__ = None # in Python 3.x we can use "raise exc from None" + raise exc + def timeout(self, err=None): spawn = self.spawn - spawn.before = spawn.buffer + spawn.before = spawn._before.getvalue() spawn.after = TIMEOUT index = self.searcher.timeout_index if index >= 0: @@ -79,15 +138,18 @@ msg += '\nsearcher: %s' % self.searcher if err is not None: msg = str(err) + '\n' + msg - raise TIMEOUT(msg) + + exc = TIMEOUT(msg) + exc.__cause__ = None # in Python 3.x we can use "raise exc from None" + raise exc def errored(self): spawn = self.spawn - spawn.before = spawn.buffer + spawn.before = spawn._before.getvalue() spawn.after = None spawn.match = None spawn.match_index = None - + def expect_loop(self, timeout=-1): """Blocking expect""" spawn = self.spawn @@ -96,14 +158,10 @@ end_time = time.time() + timeout try: - incoming = spawn.buffer - spawn._buffer = spawn.buffer_type() - spawn._before = spawn.buffer_type() + idx = self.existing_data() + if idx is not None: + return idx while True: - idx = self.new_data(incoming) - # Keep reading until exception or return. - if idx is not None: - return idx # No match at this point if (timeout is not None) and (timeout < 0): return self.timeout() @@ -111,6 +169,10 @@ incoming = spawn.read_nonblocking(spawn.maxread, timeout) if self.spawn.delayafterread is not None: time.sleep(self.spawn.delayafterread) + idx = self.new_data(incoming) + # Keep reading until exception or return. + if idx is not None: + return idx if timeout is not None: timeout = end_time - time.time() except EOF as e: @@ -148,6 +210,7 @@ self.eof_index = -1 self.timeout_index = -1 self._strings = [] + self.longest_string = 0 for n, s in enumerate(strings): if s is EOF: self.eof_index = n @@ -156,6 +219,8 @@ self.timeout_index = n continue self._strings.append((n, s)) + if len(s) > self.longest_string: + self.longest_string = len(s) def __str__(self): '''This returns a human-readable string that represents the state of diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/pty_spawn.py new/pexpect-4.8.0/pexpect/pty_spawn.py --- old/pexpect-4.7.0/pexpect/pty_spawn.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/pty_spawn.py 2020-01-17 18:08:15.000000000 +0100 @@ -191,6 +191,7 @@ self.STDIN_FILENO = pty.STDIN_FILENO self.STDOUT_FILENO = pty.STDOUT_FILENO self.STDERR_FILENO = pty.STDERR_FILENO + self.str_last_chars = 100 self.cwd = cwd self.env = env self.echo = echo @@ -212,8 +213,8 @@ 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:]) - s.append('before (last 100 chars): %r' % self.before[-100:] if self.before else '') + s.append('buffer (last %s chars): %r' % (self.str_last_chars,self.buffer[-self.str_last_chars:])) + s.append('before (last %s chars): %r' % (self.str_last_chars,self.before[-self.str_last_chars:] if self.before else '')) s.append('after: %r' % (self.after,)) s.append('match: %r' % (self.match,)) s.append('match_index: ' + str(self.match_index)) @@ -752,10 +753,14 @@ 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. + functions should take bytes array and return bytes array too. Even + with ``encoding='utf-8'`` support, meth:`interact` will always pass + input_filter and output_filter bytes. You may need to wrap your + function to decode and encode back to UTF-8. + + 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/run.py new/pexpect-4.8.0/pexpect/run.py --- old/pexpect-4.7.0/pexpect/run.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/run.py 2020-01-17 18:08:15.000000000 +0100 @@ -67,7 +67,7 @@ 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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/screen.py new/pexpect-4.8.0/pexpect/screen.py --- old/pexpect-4.7.0/pexpect/screen.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/screen.py 2020-01-17 18:08:15.000000000 +0100 @@ -90,7 +90,7 @@ self.encoding = encoding self.encoding_errors = encoding_errors if encoding is not None: - self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors) + self.decoder = codecs.getincrementaldecoder(encoding)(encoding_errors) else: self.decoder = None self.cur_r = 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect/spawnbase.py new/pexpect-4.8.0/pexpect/spawnbase.py --- old/pexpect-4.7.0/pexpect/spawnbase.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/pexpect/spawnbase.py 2020-01-17 18:08:15.000000000 +0100 @@ -120,6 +120,9 @@ self.async_pw_transport = None # This is the read buffer. See maxread. self._buffer = self.buffer_type() + # The buffer may be trimmed for efficiency reasons. This is the + # untrimmed buffer, used to create the before attribute. + self._before = self.buffer_type() def _log(self, s, direction): if self.logfile is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect.egg-info/PKG-INFO new/pexpect-4.8.0/pexpect.egg-info/PKG-INFO --- old/pexpect-4.7.0/pexpect.egg-info/PKG-INFO 2019-04-07 03:54:58.000000000 +0200 +++ new/pexpect-4.8.0/pexpect.egg-info/PKG-INFO 2020-01-21 17:29:55.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: pexpect -Version: 4.7.0 +Version: 4.8.0 Summary: Pexpect allows easy control of interactive console applications. Home-page: https://pexpect.readthedocs.io/ Author: Noah Spurrier; Thomas Kluyver; Jeff Quast diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/pexpect.egg-info/SOURCES.txt new/pexpect-4.8.0/pexpect.egg-info/SOURCES.txt --- old/pexpect-4.7.0/pexpect.egg-info/SOURCES.txt 2019-04-07 03:54:58.000000000 +0200 +++ new/pexpect-4.8.0/pexpect.egg-info/SOURCES.txt 2020-01-21 17:29:55.000000000 +0100 @@ -1,3 +1,4 @@ +.coveragerc LICENSE MANIFEST.in README.rst @@ -67,7 +68,8 @@ tests/adhoc.py tests/alarm_die.py tests/bambi.vt -tests/depricated_test_filedescriptor.py +tests/deprecated_test_filedescriptor.py +tests/deprecated_test_run_out_of_pty.py tests/echo_w_prompt.py tests/echo_wait.py tests/exit1.py @@ -106,7 +108,6 @@ tests/test_replwrap.py tests/test_repr.py tests/test_run.py -tests/test_run_out_of_pty.py tests/test_screen.py tests/test_socket.py tests/test_timeout_pattern.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/deprecated_test_filedescriptor.py new/pexpect-4.8.0/tests/deprecated_test_filedescriptor.py --- old/pexpect-4.7.0/tests/deprecated_test_filedescriptor.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pexpect-4.8.0/tests/deprecated_test_filedescriptor.py 2020-01-17 18:08:15.000000000 +0100 @@ -0,0 +1,82 @@ +#!/usr/bin/env python +''' +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 <[email protected]> + 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 pexpect +import unittest +import PexpectTestCase +import os + +class ExpectTestCase(PexpectTestCase.PexpectTestCase): + def setUp(self): + print(self.id()) + PexpectTestCase.PexpectTestCase.setUp(self) + + def test_fd (self): + fd = os.open ('TESTDATA.txt', os.O_RDONLY) + s = pexpect.spawn (fd) + s.expect ('This is the end of test data:') + s.expect (pexpect.EOF) + assert s.before == ' END\n' + + def test_maxread (self): + fd = os.open ('TESTDATA.txt', os.O_RDONLY) + s = pexpect.spawn (fd) + s.maxread = 100 + s.expect('2') + s.expect ('This is the end of test data:') + s.expect (pexpect.EOF) + assert s.before == ' END\n' + + def test_fd_isalive (self): + fd = os.open ('TESTDATA.txt', os.O_RDONLY) + s = pexpect.spawn (fd) + assert s.isalive() + os.close (fd) + assert not s.isalive() + + def test_fd_isatty (self): + fd = os.open ('TESTDATA.txt', os.O_RDONLY) + s = pexpect.spawn (fd) + assert not s.isatty() + os.close(fd) + +### def test_close_does_not_close_fd (self): +### '''Calling close() on a pexpect.spawn object should not +### close the underlying file descriptor. +### ''' +### fd = os.open ('TESTDATA.txt', os.O_RDONLY) +### s = pexpect.spawn (fd) +### try: +### s.close() +### self.fail('Expected an Exception.') +### except pexpect.ExceptionPexpect, e: +### pass + +if __name__ == '__main__': + unittest.main() + +suite = unittest.makeSuite(ExpectTestCase, 'test') + +#fout = open('delete_me_1','wb') +#fout.write(the_old_way) +#fout.close +#fout = open('delete_me_2', 'wb') +#fout.write(the_new_way) +#fout.close diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/deprecated_test_run_out_of_pty.py new/pexpect-4.8.0/tests/deprecated_test_run_out_of_pty.py --- old/pexpect-4.7.0/tests/deprecated_test_run_out_of_pty.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pexpect-4.8.0/tests/deprecated_test_run_out_of_pty.py 2020-01-17 18:08:15.000000000 +0100 @@ -0,0 +1,51 @@ +#!/usr/bin/env python +''' +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 <[email protected]> + 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 pexpect +import unittest +from . import PexpectTestCase + +class ExpectTestCase(PexpectTestCase.PexpectTestCase): + # This takes too long to run and isn't all that interesting of a test. + def OFF_test_run_out_of_pty (self): + '''This assumes that the tested platform has < 10000 pty devices. + This test currently does not work under Solaris. + Under Solaris it runs out of file descriptors first and + ld.so starts to barf: + ld.so.1: pt_chmod: fatal: /usr/lib/libc.so.1: Too many open files + ''' + plist=[] + for count in range (0,10000): + try: + plist.append (pexpect.spawn('ls -l')) + except pexpect.ExceptionPexpect: + for c in range (0, count): + plist[c].close() + return + except Exception: + err = sys.exc_info()[1] + self.fail ('Expected ExceptionPexpect. ' + str(err)) + self.fail ('Could not run out of pty devices. This may be OK.') + +if __name__ == '__main__': + unittest.main() + +suite = unittest.makeSuite(ExpectTestCase,'test') + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/depricated_test_filedescriptor.py new/pexpect-4.8.0/tests/depricated_test_filedescriptor.py --- old/pexpect-4.7.0/tests/depricated_test_filedescriptor.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/depricated_test_filedescriptor.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,82 +0,0 @@ -#!/usr/bin/env python -''' -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 <[email protected]> - 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 pexpect -import unittest -import PexpectTestCase -import os - -class ExpectTestCase(PexpectTestCase.PexpectTestCase): - def setUp(self): - print(self.id()) - PexpectTestCase.PexpectTestCase.setUp(self) - - def test_fd (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - s.expect ('This is the end of test data:') - s.expect (pexpect.EOF) - assert s.before == ' END\n' - - def test_maxread (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - s.maxread = 100 - s.expect('2') - s.expect ('This is the end of test data:') - s.expect (pexpect.EOF) - assert s.before == ' END\n' - - def test_fd_isalive (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - assert s.isalive() - os.close (fd) - assert not s.isalive() - - def test_fd_isatty (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - assert not s.isatty() - os.close(fd) - -### def test_close_does_not_close_fd (self): -### '''Calling close() on a pexpect.spawn object should not -### close the underlying file descriptor. -### ''' -### fd = os.open ('TESTDATA.txt', os.O_RDONLY) -### s = pexpect.spawn (fd) -### try: -### s.close() -### self.fail('Expected an Exception.') -### except pexpect.ExceptionPexpect, e: -### pass - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase, 'test') - -#fout = open('delete_me_1','wb') -#fout.write(the_old_way) -#fout.close -#fout = open('delete_me_2', 'wb') -#fout.write(the_new_way) -#fout.close diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_ansi.py new/pexpect-4.8.0/tests/test_ansi.py --- old/pexpect-4.7.0/tests/test_ansi.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_ansi.py 2020-01-17 18:08:15.000000000 +0100 @@ -21,7 +21,10 @@ from pexpect import ANSI import unittest from . import PexpectTestCase +import os +import shutil import sys +import tempfile PY3 = (sys.version_info[0] >= 3) @@ -120,8 +123,17 @@ s = ANSI.ANSI (24,80) with open('torturet.vt') as f: sample_text = f.read() - for c in sample_text: - s.process (c) + # This causes ANSI.py's DoLog to write in the cwd. Make sure we're in a + # writeable directory. + d = tempfile.mkdtemp() + old_cwd = os.getcwd() + os.chdir(d) + try: + for c in sample_text: + s.process (c) + finally: + os.chdir(old_cwd) + shutil.rmtree(d) assert s.pretty() == torture_target, 'processed: \n' + s.pretty() + '\nexpected:\n' + torture_target def test_tetris (self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_async.py new/pexpect-4.8.0/tests/test_async.py --- old/pexpect-4.7.0/tests/test_async.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_async.py 2020-01-17 18:08:15.000000000 +0100 @@ -47,19 +47,19 @@ run(coro) def test_expect_exact(self): - p = pexpect.spawn('%s list100.py' % sys.executable) + p = pexpect.spawn('%s list100.py' % self.PYTHONBIN) assert run(p.expect_exact(b'5', async_=True)) == 0 assert run(p.expect_exact(['wpeok', b'11'], async_=True)) == 1 assert run(p.expect_exact([b'foo', pexpect.EOF], async_=True)) == 1 def test_async_utf8(self): - p = pexpect.spawn('%s list100.py' % sys.executable, encoding='utf8') + p = pexpect.spawn('%s list100.py' % self.PYTHONBIN, encoding='utf8') assert run(p.expect_exact(u'5', async_=True)) == 0 assert run(p.expect_exact([u'wpeok', u'11'], async_=True)) == 1 assert run(p.expect_exact([u'foo', pexpect.EOF], async_=True)) == 1 def test_async_and_gc(self): - p = pexpect.spawn('%s sleep_for.py 1' % sys.executable, encoding='utf8') + p = pexpect.spawn('%s sleep_for.py 1' % self.PYTHONBIN, encoding='utf8') assert run(p.expect_exact(u'READY', async_=True)) == 0 gc.collect() assert run(p.expect_exact(u'END', async_=True)) == 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_ctrl_chars.py new/pexpect-4.8.0/tests/test_ctrl_chars.py --- old/pexpect-4.7.0/tests/test_ctrl_chars.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_ctrl_chars.py 2020-01-17 18:08:15.000000000 +0100 @@ -36,11 +36,14 @@ byte = chr class TestCtrlChars(PexpectTestCase.PexpectTestCase): + def setUp(self): + super(TestCtrlChars, self).setUp() + self.getch_cmd = self.PYTHONBIN + ' getch.py' def test_control_chars(self): '''This tests that we can send all 256 8-bit characters to a child process.''' - child = pexpect.spawn('python getch.py', echo=False, timeout=5) + child = pexpect.spawn(self.getch_cmd, echo=False, timeout=5) child.expect('READY') for i in range(1, 256): child.send(byte(i)) @@ -54,7 +57,7 @@ assert child.exitstatus == 0 def test_sendintr (self): - child = pexpect.spawn('python getch.py', echo=False, timeout=5) + child = pexpect.spawn(self.getch_cmd, echo=False, timeout=5) child.expect('READY') child.sendintr() child.expect(str(ord(ptyprocess._INTR)) + '<STOP>') @@ -66,7 +69,7 @@ assert child.exitstatus == 0 def test_sendeof(self): - child = pexpect.spawn('python getch.py', echo=False, timeout=5) + child = pexpect.spawn(self.getch_cmd, echo=False, timeout=5) child.expect('READY') child.sendeof() child.expect(str(ord(ptyprocess._EOF)) + '<STOP>') @@ -80,14 +83,14 @@ def test_bad_sendcontrol_chars (self): '''This tests that sendcontrol will return 0 for an unknown char. ''' - child = pexpect.spawn('python getch.py', echo=False, timeout=5) + child = pexpect.spawn(self.getch_cmd, echo=False, timeout=5) child.expect('READY') assert 0 == child.sendcontrol('1') def test_sendcontrol(self): '''This tests that we can send all special control codes by name. ''' - child = pexpect.spawn('python getch.py', echo=False, timeout=5) + child = pexpect.spawn(self.getch_cmd, echo=False, timeout=5) child.expect('READY') for ctrl in 'abcdefghijklmnopqrstuvwxyz': assert child.sendcontrol(ctrl) == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_expect.py new/pexpect-4.8.0/tests/test_expect.py --- old/pexpect-4.7.0/tests/test_expect.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_expect.py 2020-01-17 18:08:15.000000000 +0100 @@ -38,7 +38,7 @@ FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) def hex_dump(src, length=16): result=[] - for i in xrange(0, len(src), length): + for i in range(0, len(src), length): s = src[i:i+length] hexa = ' '.join(["%02X"%ord(x) for x in s]) printable = s.translate(FILTER) @@ -451,6 +451,47 @@ p.expect = p.expect_exact self._before_after(p) + def test_before_after_timeout(self): + '''Tests that timeouts do not truncate before, a bug in 4.4-4.7.''' + child = pexpect.spawn('cat', echo=False) + child.sendline('BEGIN') + for i in range(100): + child.sendline('foo' * 100) + e = child.expect([b'xyzzy', pexpect.TIMEOUT], + searchwindowsize=10, timeout=0.001) + self.assertEqual(e, 1) + child.sendline('xyzzy') + e = child.expect([b'xyzzy', pexpect.TIMEOUT], + searchwindowsize=10, timeout=30) + self.assertEqual(e, 0) + self.assertEqual(child.before[0:5], b'BEGIN') + child.sendeof() + child.expect(pexpect.EOF) + + def test_increasing_searchwindowsize(self): + '''Tests that the search window can be expanded, a bug in 4.4-4.7.''' + child = pexpect.spawn('cat', echo=False) + child.sendline('BEGIN') + for i in range(100): + child.sendline('foo' * 100) + e = child.expect([b'xyzzy', pexpect.TIMEOUT], + searchwindowsize=10, timeout=0.5) + self.assertEqual(e, 1) + e = child.expect([b'BEGIN', pexpect.TIMEOUT], + searchwindowsize=10, timeout=0.5) + self.assertEqual(e, 1) + e = child.expect([b'BEGIN', pexpect.TIMEOUT], + searchwindowsize=40000, timeout=30.0) + self.assertEqual(e, 0) + child.sendeof() + child.expect(pexpect.EOF) + + def test_searchwindowsize(self): + '''Tests that we don't match outside the window, a bug in 4.4-4.7.''' + p = pexpect.spawn('echo foobarbazbop') + e = p.expect([b'bar', b'bop'], searchwindowsize=6) + self.assertEqual(e, 1) + def _ordering(self, p): p.timeout = 20 p.expect(b'>>> ') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_interact.py new/pexpect-4.8.0/tests/test_interact.py --- old/pexpect-4.7.0/tests/test_interact.py 2019-04-07 03:54:52.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_interact.py 2020-01-17 18:08:15.000000000 +0100 @@ -41,7 +41,7 @@ else: env['PYTHONPATH'] = self.project_dir - self.interact_py = ('{sys.executable} interact.py'.format(sys=sys)) + self.interact_py = ('{self.PYTHONBIN} interact.py'.format(self=self)) def test_interact_escape(self): " Ensure `escape_character' value exits interactive mode. " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_isalive.py new/pexpect-4.8.0/tests/test_isalive.py --- old/pexpect-4.7.0/tests/test_isalive.py 2019-04-07 03:54:52.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_isalive.py 2020-01-17 18:08:15.000000000 +0100 @@ -57,7 +57,7 @@ '''Test calling wait with a process terminated by a signal.''' if not hasattr(signal, 'SIGALRM'): return 'SKIP' - p = pexpect.spawn(sys.executable, ['alarm_die.py']) + p = pexpect.spawn(self.PYTHONBIN, ['alarm_die.py']) p.wait() assert p.exitstatus is None self.assertEqual(p.signalstatus, signal.SIGALRM) @@ -99,7 +99,7 @@ assert not p.isalive() def test_forced_terminate(self): - p = pexpect.spawn(sys.executable, ['needs_kill.py']) + p = pexpect.spawn(self.PYTHONBIN, ['needs_kill.py']) p.expect('READY') assert p.terminate(force=True) == True p.expect(pexpect.EOF) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_misc.py new/pexpect-4.8.0/tests/test_misc.py --- old/pexpect-4.7.0/tests/test_misc.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_misc.py 2020-01-17 18:08:15.000000000 +0100 @@ -171,7 +171,7 @@ def test_with(self): "spawn can be used as a context manager" - with pexpect.spawn(sys.executable + ' echo_w_prompt.py') as p: + with pexpect.spawn(self.PYTHONBIN + ' echo_w_prompt.py') as p: p.expect('<in >') p.sendline(b'alpha') p.expect(b'<out>alpha') @@ -187,7 +187,7 @@ def test_sighup(self): " validate argument `ignore_sighup=True` and `ignore_sighup=False`. " - getch = sys.executable + ' getch.py' + getch = self.PYTHONBIN + ' getch.py' child = pexpect.spawn(getch, ignore_sighup=True) child.expect('READY') child.kill(signal.SIGHUP) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_pxssh.py new/pexpect-4.8.0/tests/test_pxssh.py --- old/pexpect-4.7.0/tests/test_pxssh.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_pxssh.py 2020-01-17 18:08:15.000000000 +0100 @@ -1,18 +1,24 @@ #!/usr/bin/env python import os +import shutil import tempfile import unittest from pexpect import pxssh +from .PexpectTestCase import PexpectTestCase -class SSHTestBase(unittest.TestCase): +class SSHTestBase(PexpectTestCase): def setUp(self): + super(SSHTestBase, self).setUp() + self.tempdir = tempfile.mkdtemp() self.orig_path = os.environ.get('PATH') + os.symlink(self.PYTHONBIN, os.path.join(self.tempdir, 'python')) fakessh_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'fakessh')) - os.environ['PATH'] = fakessh_dir + \ + os.environ['PATH'] = self.tempdir + os.pathsep + fakessh_dir + \ ((os.pathsep + self.orig_path) if self.orig_path else '') def tearDown(self): + shutil.rmtree(self.tempdir) if self.orig_path: os.environ['PATH'] = self.orig_path else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_run.py new/pexpect-4.8.0/tests/test_run.py --- old/pexpect-4.7.0/tests/test_run.py 2019-04-07 03:54:52.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_run.py 2020-01-17 18:08:15.000000000 +0100 @@ -181,7 +181,7 @@ else: return True # Stop the child process - output = pexpect.runu(sys.executable + ' echo_w_prompt.py', + output = pexpect.runu(self.PYTHONBIN + ' echo_w_prompt.py', env={'PYTHONIOENCODING': 'utf-8'}, events={pattern: callback}) assert isinstance(output, unicode_type), type(output) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_run_out_of_pty.py new/pexpect-4.8.0/tests/test_run_out_of_pty.py --- old/pexpect-4.7.0/tests/test_run_out_of_pty.py 2019-04-07 03:54:52.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_run_out_of_pty.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,51 +0,0 @@ -#!/usr/bin/env python -''' -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 <[email protected]> - 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 pexpect -import unittest -from . import PexpectTestCase - -class ExpectTestCase(PexpectTestCase.PexpectTestCase): - # This takes too long to run and isn't all that interesting of a test. - def OFF_test_run_out_of_pty (self): - '''This assumes that the tested platform has < 10000 pty devices. - This test currently does not work under Solaris. - Under Solaris it runs out of file descriptors first and - ld.so starts to barf: - ld.so.1: pt_chmod: fatal: /usr/lib/libc.so.1: Too many open files - ''' - plist=[] - for count in range (0,10000): - try: - plist.append (pexpect.spawn('ls -l')) - except pexpect.ExceptionPexpect: - for c in range (0, count): - plist[c].close() - return - except Exception: - err = sys.exc_info()[1] - self.fail ('Expected ExceptionPexpect. ' + str(err)) - self.fail ('Could not run out of pty devices. This may be OK.') - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase,'test') - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_socket.py new/pexpect-4.8.0/tests/test_socket.py --- old/pexpect-4.7.0/tests/test_socket.py 2019-04-07 03:54:51.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_socket.py 2020-01-17 18:08:15.000000000 +0100 @@ -39,7 +39,17 @@ def setUp(self): print(self.id()) PexpectTestCase.PexpectTestCase.setUp(self) + self.af = socket.AF_INET self.host = '127.0.0.1' + try: + socket.socket(socket.AF_INET, socket.SOCK_STREAM) + except socket.error: + try: + socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + self.af = socket.AF_INET6 + self.host = '::1' + except socket.error: + pass self.port = 49152 + 10000 self.motd = b"""\ ------------------------------------------------------------------------------ @@ -92,7 +102,7 @@ def socket_server(self, server_up): sock = None try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((self.host, self.port)) sock.listen(5) @@ -126,7 +136,7 @@ def socket_fn(self, timed_out, all_read): result = 0 try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock, timeout=10) # Get all data from server @@ -140,7 +150,7 @@ exit(result) def test_socket(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10) session.expect(self.prompt1) @@ -154,7 +164,7 @@ self.assertEqual(session.before, b'') def test_socket_with_write(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10) session.expect(self.prompt1) @@ -177,7 +187,7 @@ def test_timeout(self): with self.assertRaises(pexpect.TIMEOUT): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock, timeout=10) session.expect(b'Bogus response') @@ -211,7 +221,7 @@ self.assertEqual(test_proc.exitcode, errno.ETIMEDOUT) def test_maxread(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10) session.maxread = 1100 @@ -226,7 +236,7 @@ self.assertEqual(session.before, b'') def test_fd_isalive(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10) assert session.isalive() @@ -234,7 +244,7 @@ assert not session.isalive(), "Should not be alive after close()" def test_fd_isalive_poll(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10, use_poll=True) assert session.isalive() @@ -242,21 +252,21 @@ assert not session.isalive(), "Should not be alive after close()" def test_fd_isatty(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10) assert not session.isatty() session.close() def test_fd_isatty_poll(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock.fileno(), timeout=10, use_poll=True) assert not session.isatty() session.close() def test_fileobj(self): - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock = socket.socket(self.af, socket.SOCK_STREAM) sock.connect((self.host, self.port)) session = fdpexpect.fdspawn(sock, timeout=10) # Should get the fileno from the socket session.expect(self.prompt1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.7.0/tests/test_which.py new/pexpect-4.8.0/tests/test_which.py --- old/pexpect-4.7.0/tests/test_which.py 2019-04-07 03:54:52.000000000 +0200 +++ new/pexpect-4.8.0/tests/test_which.py 2020-01-17 18:08:15.000000000 +0100 @@ -2,6 +2,7 @@ import subprocess import tempfile import shutil +import sys import errno import os @@ -41,8 +42,12 @@ " which() finds an executable in $PATH and returns its abspath. " bin_dir = tempfile.mkdtemp() + if sys.getfilesystemencoding() in ('ascii', 'ANSI_X3.4-1968'): + prefix = 'ascii-' + else: + prefix = u'ǝpoɔıun-' temp_obj = tempfile.NamedTemporaryFile( - suffix=u'.sh', prefix=u'ǝpoɔıun-', + suffix=u'.sh', prefix=prefix, dir=bin_dir, delete=False) bin_path = temp_obj.name fname = os.path.basename(temp_obj.name)
