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()
 


Reply via email to