Hello community, here is the log from the commit of package python-pexpect for openSUSE:Factory checked in at 2018-02-14 09:45:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pexpect (Old) and /work/SRC/openSUSE:Factory/.python-pexpect.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pexpect" Wed Feb 14 09:45:12 2018 rev:23 rq:575269 version:4.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pexpect/python-pexpect.changes 2017-12-21 11:24:03.970988691 +0100 +++ /work/SRC/openSUSE:Factory/.python-pexpect.new/python-pexpect.changes 2018-02-14 09:45:25.601362343 +0100 @@ -1,0 +2,17 @@ +Sat Feb 10 17:29:45 UTC 2018 - a...@gmx.de + +- specfile: + * update copyright year + +- update to version 4.4.0: + * PopenSpawn now has a preexec_fn parameter, like spawn and + subprocess.Popen, for a function to be called in the child process + before executing the new command. Like in Popen, this works only + in POSIX, and can cause issues if your application also uses + threads (PR #460). + * Significant performance improvements when processing large amounts + of data (PR #464). + * Ensure that spawn.closed gets set by close(), and improve an + example for passing SIGWINCH through to a child process (PR #466). + +------------------------------------------------------------------- Old: ---- pexpect-4.3.1.tar.gz New: ---- pexpect-4.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pexpect.spec ++++++ --- /var/tmp/diff_new_pack.ItHbrk/_old 2018-02-14 09:45:27.749284062 +0100 +++ /var/tmp/diff_new_pack.ItHbrk/_new 2018-02-14 09:45:27.753283916 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pexpect # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,7 +20,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pexpect -Version: 4.3.1 +Version: 4.4.0 Release: 0 Summary: Pure Python Expect-like module License: ISC ++++++ pexpect-4.3.1.tar.gz -> pexpect-4.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/PKG-INFO new/pexpect-4.4.0/PKG-INFO --- old/pexpect-4.3.1/PKG-INFO 2017-12-12 11:51:04.000000000 +0100 +++ new/pexpect-4.4.0/PKG-INFO 2018-02-10 13:45:15.000000000 +0100 @@ -1,10 +1,10 @@ Metadata-Version: 1.1 Name: pexpect -Version: 4.3.1 +Version: 4.4.0 Summary: Pexpect allows easy control of interactive console applications. Home-page: https://pexpect.readthedocs.io/ Author: Noah Spurrier; Thomas Kluyver; Jeff Quast -Author-email: n...@noah.org; tho...@kluyver.me.uk; cont...@jeffquast.com +Author-email: n...@noah.org, tho...@kluyver.me.uk, cont...@jeffquast.com License: ISC license Description: Pexpect is a pure Python module for spawning child applications; controlling diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/doc/conf.py new/pexpect-4.4.0/doc/conf.py --- old/pexpect-4.3.1/doc/conf.py 2017-12-12 11:47:25.000000000 +0100 +++ new/pexpect-4.4.0/doc/conf.py 2018-02-10 13:34:25.000000000 +0100 @@ -52,7 +52,7 @@ # built documents. # # The short X.Y version. -version = '4.3.1' +version = '4.4' # The full version, including alpha/beta/rc tags. release = version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/doc/history.rst new/pexpect-4.4.0/doc/history.rst --- old/pexpect-4.3.1/doc/history.rst 2017-12-12 11:45:08.000000000 +0100 +++ new/pexpect-4.4.0/doc/history.rst 2018-02-10 13:32:20.000000000 +0100 @@ -4,6 +4,19 @@ Releases -------- +Version 4.4 +``````````` + +* :class:`~.PopenSpawn` now has a ``preexec_fn`` parameter, like :class:`~.spawn` + and :class:`subprocess.Popen`, for a function to be called in the child + process before executing the new command. Like in ``Popen``, this works only + in POSIX, and can cause issues if your application also uses threads + (:ghpull:`460`). +* Significant performance improvements when processing large amounts of data + (:ghpull:`464`). +* Ensure that ``spawn.closed`` gets set by :meth:`~.spawn.close`, and improve + an example for passing ``SIGWINCH`` through to a child process (:ghpull:`466`). + Version 4.3.1 ````````````` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/pexpect/__init__.py new/pexpect-4.4.0/pexpect/__init__.py --- old/pexpect-4.3.1/pexpect/__init__.py 2017-12-12 11:47:25.000000000 +0100 +++ new/pexpect-4.4.0/pexpect/__init__.py 2018-02-10 13:34:36.000000000 +0100 @@ -75,7 +75,7 @@ from .pty_spawn import spawn, spawnu from .run import run, runu -__version__ = '4.3.1' +__version__ = '4.4.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.3.1/pexpect/_async.py new/pexpect-4.4.0/pexpect/_async.py --- old/pexpect-4.3.1/pexpect/_async.py 2017-11-09 16:52:00.000000000 +0100 +++ new/pexpect-4.4.0/pexpect/_async.py 2018-02-10 13:16:58.000000000 +0100 @@ -8,7 +8,7 @@ # 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.string_type() + expecter.spawn._buffer = expecter.spawn.buffer_type() idx = expecter.new_data(previously_read) if idx is not None: return idx @@ -55,7 +55,7 @@ spawn._log(s, 'read') if self.fut.done(): - spawn.buffer += s + spawn._buffer.write(s) return try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/pexpect/expect.py new/pexpect-4.4.0/pexpect/expect.py --- old/pexpect-4.3.1/pexpect/expect.py 2017-12-08 11:54:26.000000000 +0100 +++ new/pexpect-4.4.0/pexpect/expect.py 2018-02-10 13:16:58.000000000 +0100 @@ -9,30 +9,42 @@ if searchwindowsize == -1: searchwindowsize = spawn.searchwindowsize self.searchwindowsize = searchwindowsize - + def new_data(self, data): spawn = self.spawn searcher = self.searcher - incoming = spawn.buffer + data - freshlen = len(data) - index = searcher.search(incoming, freshlen, self.searchwindowsize) + pos = spawn._buffer.tell() + spawn._buffer.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 index >= 0: - spawn.buffer = incoming[searcher.end:] - spawn.before = incoming[: searcher.start] - spawn.after = incoming[searcher.start: searcher.end] + value = spawn.buffer + spawn._buffer = spawn.buffer_type() + spawn._buffer.write(value[searcher.end:]) + spawn.before = value[: searcher.start] + spawn.after = value[searcher.start: searcher.end] spawn.match = searcher.match spawn.match_index = index # Found a match return index - - spawn.buffer = incoming - + elif self.searchwindowsize: + spawn._buffer = spawn.buffer_type() + spawn._buffer.write(window) + def eof(self, err=None): spawn = self.spawn spawn.before = spawn.buffer - spawn.buffer = spawn.string_type() + spawn._buffer = spawn.buffer_type() spawn.after = EOF index = self.searcher.eof_index if index >= 0: @@ -83,7 +95,7 @@ try: incoming = spawn.buffer - spawn.buffer = spawn.string_type() # Treat buffer as new data + spawn._buffer = spawn.buffer_type() while True: idx = self.new_data(incoming) # Keep reading until exception or return. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/pexpect/popen_spawn.py new/pexpect-4.4.0/pexpect/popen_spawn.py --- old/pexpect-4.3.1/pexpect/popen_spawn.py 2017-11-09 16:52:00.000000000 +0100 +++ new/pexpect-4.4.0/pexpect/popen_spawn.py 2018-02-10 13:16:58.000000000 +0100 @@ -24,15 +24,15 @@ crlf = '\n' def __init__(self, cmd, timeout=30, maxread=2000, searchwindowsize=None, - logfile=None, cwd=None, env=None, encoding=None, - codec_errors='strict'): + logfile=None, cwd=None, env=None, encoding=None, + codec_errors='strict', preexec_fn=None): super(PopenSpawn, self).__init__(timeout=timeout, maxread=maxread, searchwindowsize=searchwindowsize, logfile=logfile, encoding=encoding, codec_errors=codec_errors) kwargs = dict(bufsize=0, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, - cwd=cwd, env=env) + cwd=cwd, preexec_fn=preexec_fn, env=env) if sys.platform == 'win32': startupinfo = subprocess.STARTUPINFO() @@ -124,7 +124,7 @@ def send(self, s): '''Send data to the subprocess' stdin. - + Returns the number of bytes written. ''' s = self._coerce_send_string(s) @@ -148,7 +148,7 @@ def wait(self): '''Wait for the subprocess to finish. - + Returns the exit code. ''' status = self.proc.wait() @@ -163,7 +163,7 @@ def kill(self, sig): '''Sends a Unix signal to the subprocess. - + Use constants from the :mod:`signal` module to specify which signal. ''' if sys.platform == 'win32': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/pexpect/pty_spawn.py new/pexpect-4.4.0/pexpect/pty_spawn.py --- old/pexpect-4.3.1/pexpect/pty_spawn.py 2017-08-22 15:56:46.000000000 +0200 +++ new/pexpect-4.4.0/pexpect/pty_spawn.py 2018-02-10 13:16:58.000000000 +0100 @@ -205,10 +205,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:] if self.buffer else self.buffer,)) - s.append('before (last 100 chars): %r' % ( - self.before[-100:] if self.before else self.before,)) + 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('after: %r' % (self.after,)) s.append('match: %r' % (self.match,)) s.append('match_index: ' + str(self.match_index)) @@ -322,6 +320,7 @@ self.ptyproc.close(force=force) self.isalive() # Update exit status from ptyproc self.child_fd = -1 + self.closed = True def isatty(self): '''This returns True if the file descriptor is open and connected to a @@ -729,9 +728,10 @@ 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. + if not p.closed: + p.setwinsize(a[0],a[1]) + + # Note this 'p' is global and used in sigwinch_passthrough. p = pexpect.spawn('/bin/bash') signal.signal(signal.SIGWINCH, sigwinch_passthrough) p.interact() @@ -740,7 +740,7 @@ # Flush the buffer. self.write_to_stdout(self.buffer) self.stdout.flush() - self.buffer = self.string_type() + self._buffer = self.buffer_type() mode = tty.tcgetattr(self.STDIN_FILENO) tty.setraw(self.STDIN_FILENO) if escape_character is not None and PY3: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/pexpect/spawnbase.py new/pexpect-4.4.0/pexpect/spawnbase.py --- old/pexpect-4.3.1/pexpect/spawnbase.py 2017-11-09 16:52:00.000000000 +0100 +++ new/pexpect-4.4.0/pexpect/spawnbase.py 2018-02-10 13:16:58.000000000 +0100 @@ -1,3 +1,4 @@ +from io import StringIO, BytesIO import codecs import os import sys @@ -57,8 +58,6 @@ self.logfile_send = None # max bytes to read at one time into buffer self.maxread = maxread - # This is the read buffer. See maxread. - self.buffer = bytes() if (encoding is None) else text_type() # Data before searchwindowsize point is preserved, but not searched. self.searchwindowsize = searchwindowsize # Delay used before sending data to child. Time in seconds. @@ -87,6 +86,7 @@ # bytes mode (accepts some unicode for backwards compatibility) self._encoder = self._decoder = _NullCoder() self.string_type = bytes + self.buffer_type = BytesIO self.crlf = b'\r\n' if PY3: self.allowed_string_types = (bytes, str) @@ -107,6 +107,7 @@ self._encoder = codecs.getincrementalencoder(encoding)(codec_errors) self._decoder = codecs.getincrementaldecoder(encoding)(codec_errors) self.string_type = text_type + self.buffer_type = StringIO self.crlf = u'\r\n' self.allowed_string_types = (text_type, ) if PY3: @@ -117,6 +118,8 @@ self.write_to_stdout = sys.stdout.write # storage for async transport self.async_pw_transport = None + # This is the read buffer. See maxread. + self._buffer = self.buffer_type() def _log(self, s, direction): if self.logfile is not None: @@ -140,6 +143,17 @@ return s.encode('utf-8') return s + def _get_buffer(self): + return self._buffer.getvalue() + + def _set_buffer(self, value): + self._buffer = self.buffer_type() + self._buffer.write(value) + + # This property is provided for backwards compatability (self.buffer used + # to be a string/bytes object) + buffer = property(_get_buffer, _set_buffer) + def read_nonblocking(self, size=1, timeout=None): """This reads data from the file descriptor. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/setup.py new/pexpect-4.4.0/setup.py --- old/pexpect-4.3.1/setup.py 2016-07-11 17:35:42.000000000 +0200 +++ new/pexpect-4.4.0/setup.py 2018-02-10 13:43:58.000000000 +0100 @@ -41,7 +41,7 @@ description='Pexpect allows easy control of interactive console applications.', long_description=long_description, author='Noah Spurrier; Thomas Kluyver; Jeff Quast', - author_email='n...@noah.org; tho...@kluyver.me.uk; cont...@jeffquast.com', + author_email='n...@noah.org, tho...@kluyver.me.uk, cont...@jeffquast.com', url='https://pexpect.readthedocs.io/', license='ISC license', platforms='UNIX', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/tests/log new/pexpect-4.4.0/tests/log --- old/pexpect-4.3.1/tests/log 2017-12-12 11:48:21.000000000 +0100 +++ new/pexpect-4.4.0/tests/log 2016-08-21 22:02:45.000000000 +0200 @@ -18,13 +18,3 @@ P,ESC \,ESC r,SEMICOLON -\,ESC -P,ESC -\,ESC -P,ESC -\,ESC -P,ESC -\,ESC -P,ESC -\,ESC -r,SEMICOLON diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/tests/test_expect.py new/pexpect-4.4.0/tests/test_expect.py --- old/pexpect-4.3.1/tests/test_expect.py 2016-01-27 18:44:29.000000000 +0100 +++ new/pexpect-4.4.0/tests/test_expect.py 2018-02-10 13:16:58.000000000 +0100 @@ -400,6 +400,14 @@ else: self.fail ('Expected an EOF exception.') + def test_buffer_interface(self): + p = pexpect.spawn('cat', timeout=5) + p.sendline (b'Hello') + p.expect (b'Hello') + assert len(p.buffer) + p.buffer = b'Testing' + p.sendeof () + def _before_after(self, p): p.timeout = 5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pexpect-4.3.1/tests/test_performance.py new/pexpect-4.4.0/tests/test_performance.py --- old/pexpect-4.3.1/tests/test_performance.py 2015-12-04 11:07:10.000000000 +0100 +++ new/pexpect-4.4.0/tests/test_performance.py 2018-02-10 13:16:58.000000000 +0100 @@ -23,6 +23,7 @@ import unittest, time, sys import platform import pexpect +import re from . import PexpectTestCase # This isn't exactly a unit test, but it fits in nicely with the rest of the tests. @@ -101,6 +102,11 @@ self.faster_range(100000) print("100000 calls to faster_range:", (time.time() - start_time)) + def test_large_stdout_stream(self): + e = pexpect.spawn('openssl rand -base64 {}'.format(1024*1024*25), searchwindowsize=1000) + resp = e.expect(['Password:', pexpect.EOF, pexpect.TIMEOUT]) + assert resp == 1 # index 1 == EOF + if __name__ == "__main__": unittest.main()