Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-paramiko-expect for 
openSUSE:Factory checked in at 2022-04-08 00:28:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-paramiko-expect (Old)
 and      /work/SRC/openSUSE:Factory/.python-paramiko-expect.new.1900 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-paramiko-expect"

Fri Apr  8 00:28:25 2022 rev:3 rq:967527 version:0.3.2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-paramiko-expect/python-paramiko-expect.changes
    2020-04-21 13:10:26.216784721 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-paramiko-expect.new.1900/python-paramiko-expect.changes
  2022-04-08 00:29:03.893413972 +0200
@@ -1,0 +2,6 @@
+Thu Apr  7 11:55:05 UTC 2022 - pgaj...@suse.com
+
+- version update to 0.3.2
+  * no upstream changelog file found
+
+-------------------------------------------------------------------

Old:
----
  paramiko-expect-0.2.8.tar.gz

New:
----
  paramiko-expect-0.3.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-paramiko-expect.spec ++++++
--- /var/tmp/diff_new_pack.4S0XTe/_old  2022-04-08 00:29:04.481407343 +0200
+++ /var/tmp/diff_new_pack.4S0XTe/_new  2022-04-08 00:29:04.489407252 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-paramiko-expect
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without python2
 Name:           python-paramiko-expect
-Version:        0.2.8
+Version:        0.3.2
 Release:        0
 Summary:        An expect-like extension for the Paramiko SSH library
 License:        MIT

++++++ paramiko-expect-0.2.8.tar.gz -> paramiko-expect-0.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/paramiko-expect-0.2.8/PKG-INFO 
new/paramiko-expect-0.3.2/PKG-INFO
--- old/paramiko-expect-0.2.8/PKG-INFO  2017-05-15 23:02:20.000000000 +0200
+++ new/paramiko-expect-0.3.2/PKG-INFO  2022-01-13 13:07:35.973393200 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: paramiko-expect
-Version: 0.2.8
+Version: 0.3.2
 Summary: An expect-like extension for the Paramiko SSH library
 Home-page: https://github.com/fgimian/paramiko-expect
 Author: Fotis Gimian
@@ -12,16 +12,16 @@
         .. image:: https://img.shields.io/pypi/l/paramiko-expect.svg
            :target: 
https://github.com/fgimian/paramiko-expect/blob/master/LICENSE
         
-        .. image:: 
https://coveralls.io/repos/github/fgimian/paramiko-expect/badge.svg?branch=master
-           :target: 
https://coveralls.io/github/fgimian/paramiko-expect?branch=master
+        .. image:: 
https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg
+           :target: https://codecov.io/gh/fgimian/paramiko-expect
         
-        .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg   
+        .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
            :target: https://travis-ci.org/fruch/paramiko-expect/
         
-        .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg   
+        .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
            :target: https://pypi.python.org/pypi/paramiko-expect/
         
-        .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg  
 
+        .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
            :target:  https://pypi.python.org/pypi/paramiko-expect/
         
         
@@ -49,7 +49,7 @@
         .. code:: bash
         
             # from pypi
-            pip insall paramiko-expect
+            pip install paramiko-expect
         
             # from source
             pip install git+https://github.com/fgimian/paramiko-expect.git
@@ -183,7 +183,7 @@
         .. code:: bash
         
             pip install -r requirements-test.txt
-            docker run -d -p 2222:22 -v `pwd`/examples:/examples -v 
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  macropin/sshd
+            docker run -d -p 2222:22 -v `pwd`/examples:/examples -v 
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  docker.io/panubo/sshd
             pytest -s --cov paramiko_expect --cov-report term-missing
         
         
@@ -204,11 +204,10 @@
 Platform: Posix
 Classifier: Development Status :: 4 - Beta
 Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Intended Audience :: Developers
+Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/paramiko-expect-0.2.8/README.rst 
new/paramiko-expect-0.3.2/README.rst
--- old/paramiko-expect-0.2.8/README.rst        2017-05-15 23:01:24.000000000 
+0200
+++ new/paramiko-expect-0.3.2/README.rst        2021-01-24 21:23:29.000000000 
+0100
@@ -4,16 +4,16 @@
 .. image:: https://img.shields.io/pypi/l/paramiko-expect.svg
    :target: https://github.com/fgimian/paramiko-expect/blob/master/LICENSE
 
-.. image:: 
https://coveralls.io/repos/github/fgimian/paramiko-expect/badge.svg?branch=master
-   :target: https://coveralls.io/github/fgimian/paramiko-expect?branch=master
+.. image:: 
https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg
+   :target: https://codecov.io/gh/fgimian/paramiko-expect
 
-.. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg   
+.. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
    :target: https://travis-ci.org/fruch/paramiko-expect/
 
-.. image:: https://img.shields.io/pypi/v/paramiko-expect.svg   
+.. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
    :target: https://pypi.python.org/pypi/paramiko-expect/
 
-.. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg   
+.. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
    :target:  https://pypi.python.org/pypi/paramiko-expect/
 
 
@@ -41,7 +41,7 @@
 .. code:: bash
 
     # from pypi
-    pip insall paramiko-expect
+    pip install paramiko-expect
 
     # from source
     pip install git+https://github.com/fgimian/paramiko-expect.git
@@ -175,7 +175,7 @@
 .. code:: bash
 
     pip install -r requirements-test.txt
-    docker run -d -p 2222:22 -v `pwd`/examples:/examples -v 
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  macropin/sshd
+    docker run -d -p 2222:22 -v `pwd`/examples:/examples -v 
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  docker.io/panubo/sshd
     pytest -s --cov paramiko_expect --cov-report term-missing
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/paramiko-expect-0.2.8/paramiko_expect.egg-info/PKG-INFO 
new/paramiko-expect-0.3.2/paramiko_expect.egg-info/PKG-INFO
--- old/paramiko-expect-0.2.8/paramiko_expect.egg-info/PKG-INFO 2017-05-15 
23:02:20.000000000 +0200
+++ new/paramiko-expect-0.3.2/paramiko_expect.egg-info/PKG-INFO 2022-01-13 
13:07:35.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: paramiko-expect
-Version: 0.2.8
+Version: 0.3.2
 Summary: An expect-like extension for the Paramiko SSH library
 Home-page: https://github.com/fgimian/paramiko-expect
 Author: Fotis Gimian
@@ -12,16 +12,16 @@
         .. image:: https://img.shields.io/pypi/l/paramiko-expect.svg
            :target: 
https://github.com/fgimian/paramiko-expect/blob/master/LICENSE
         
-        .. image:: 
https://coveralls.io/repos/github/fgimian/paramiko-expect/badge.svg?branch=master
-           :target: 
https://coveralls.io/github/fgimian/paramiko-expect?branch=master
+        .. image:: 
https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg
+           :target: https://codecov.io/gh/fgimian/paramiko-expect
         
-        .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg   
+        .. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg
            :target: https://travis-ci.org/fruch/paramiko-expect/
         
-        .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg   
+        .. image:: https://img.shields.io/pypi/v/paramiko-expect.svg
            :target: https://pypi.python.org/pypi/paramiko-expect/
         
-        .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg  
 
+        .. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg
            :target:  https://pypi.python.org/pypi/paramiko-expect/
         
         
@@ -49,7 +49,7 @@
         .. code:: bash
         
             # from pypi
-            pip insall paramiko-expect
+            pip install paramiko-expect
         
             # from source
             pip install git+https://github.com/fgimian/paramiko-expect.git
@@ -183,7 +183,7 @@
         .. code:: bash
         
             pip install -r requirements-test.txt
-            docker run -d -p 2222:22 -v `pwd`/examples:/examples -v 
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  macropin/sshd
+            docker run -d -p 2222:22 -v `pwd`/examples:/examples -v 
`pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  docker.io/panubo/sshd
             pytest -s --cov paramiko_expect --cov-report term-missing
         
         
@@ -204,11 +204,10 @@
 Platform: Posix
 Classifier: Development Status :: 4 - Beta
 Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Intended Audience :: Developers
+Description-Content-Type: text/x-rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/paramiko-expect-0.2.8/paramiko_expect.py 
new/paramiko-expect-0.3.2/paramiko_expect.py
--- old/paramiko-expect-0.2.8/paramiko_expect.py        2017-05-15 
23:01:24.000000000 +0200
+++ new/paramiko-expect-0.3.2/paramiko_expect.py        2021-12-14 
15:03:04.000000000 +0100
@@ -13,25 +13,31 @@
 #
 from __future__ import unicode_literals
 
+import codecs
 import sys
 import re
 import socket
 import struct
+import time
 
 # Windows does not have termios
 try:
     import termios
     import tty
     has_termios = True
-except ImportError: # pragma: no cover
+    MAX_TIMEOUT = 2 ** (struct.Struct(str('i')).size * 8 - 1) - 1
+except ImportError:  # pragma: no cover
     import threading
     has_termios = False
+    MAX_TIMEOUT = threading.TIMEOUT_MAX
 
 import select
 
+
 def strip_ansi_codes(s):
     return re.sub(r'\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?', 
'', s)
 
+
 def default_output_func(msg):
     sys.stdout.write(msg)
     sys.stdout.flush()
@@ -52,12 +58,14 @@
                     real-time as it is being performed (especially useful
                     when debugging)
     :param encoding: The character encoding to use.
+    :param lines_to_check: The number of last few lines of the output to
+                           look at, while matching regular expression(s)
     """
 
     def __init__(
         self, client, timeout=60, newline='\r', buffer_size=1024,
         display=False, encoding='utf-8', output_callback=default_output_func,
-        tty_width=80, tty_height=24
+        tty_width=80, tty_height=24, lines_to_check=1
     ):
         self.channel = client.invoke_shell(width=tty_width, height=tty_height)
         self.timeout = timeout
@@ -66,12 +74,17 @@
         self.display = display
         self.encoding = encoding
         self.output_callback = output_callback
+        self.lines_to_check = lines_to_check
 
         self.current_output = ''
         self.current_output_clean = ''
         self.current_send_string = ''
         self.last_match = ''
 
+        # If the output is long, multi-byte encoded characters may be split
+        # across calls to recv, so decode incrementally.
+        self.decoder = codecs.getincrementaldecoder(self.encoding)()
+
     def __del__(self):
         self.close()
 
@@ -85,10 +98,13 @@
         """Attempts to close the channel for clean completion."""
         try:
             self.channel.close()
-        except:
+        except Exception:
             pass
 
-    def expect(self, re_strings='', timeout=None, output_callback=None, 
default_match_prefix='.*\n', strip_ansi=True):
+    def expect(
+        self, re_strings='', timeout=None, output_callback=None, 
default_match_prefix='.*\n',
+        strip_ansi=True, ignore_decode_error=True, lines_to_check=None
+    ):
         """
         This function takes in a regular expression (or regular expressions)
         that represent the last line of output from the server.  The function
@@ -111,6 +127,10 @@
                                      or the command has no output.
         :param strip_ansi: If True, will strip ansi control chars befores 
regex matching
                            default to True.
+        :param ignore_decode_error: If True, will ignore decode errors if any.
+                           default to True.
+        :param lines_to_check: The number of last few lines of the output to
+                               look at, while matching regular expression(s)
         :return: An EOF returns -1, a regex metch returns 0 and a match in a
                  list of regexes returns the index of the matched string in
                  the list.
@@ -122,15 +142,21 @@
         timeout = timeout if timeout else self.timeout
         self.channel.settimeout(timeout)
 
+        lines_to_check = lines_to_check if lines_to_check else 
self.lines_to_check
+
+        if ignore_decode_error:
+            self.decoder = 
codecs.getincrementaldecoder(self.encoding)('ignore')
         # Create an empty output buffer
         self.current_output = ''
-
+        # saves the current buffer to check for re_strings pattern
+        current_buffer_output_decoded = ''
         # This function needs all regular expressions to be in the form of a
         # list, so if the user provided a string, let's convert it to a 1
         # item list.
         if isinstance(re_strings, str) and len(re_strings) != 0:
             re_strings = [re_strings]
-
+        # to avoid looping in recv_ready()
+        base_time = time.time()
         # Loop until one of the expressions is matched or loop forever if
         # nothing is expected (usually used for exit)
         while (
@@ -138,8 +164,15 @@
             not [re_string
                  for re_string in re_strings
                  if re.match(default_match_prefix + re_string + '$',
-                             self.current_output, re.DOTALL)]
+                             current_buffer_output_decoded, re.DOTALL)]
         ):
+            current_buffer_output_decoded = ''
+            # avoids paramiko hang when recv is not ready yet
+            while not self.channel.recv_ready():
+                time.sleep(.009)
+                if time.time() >= (base_time + timeout):
+                    print('EXCESS TIME RECV_READY TIMEOUT, did you expect() 
before a send()')
+                    return -1
             # Read some of the output
             current_buffer = self.channel.recv(self.buffer_size)
 
@@ -148,7 +181,7 @@
                 break
 
             # Convert the buffer to our chosen encoding
-            current_buffer_decoded = current_buffer.decode(self.encoding)
+            current_buffer_decoded = self.decoder.decode(current_buffer)
 
             # Strip all ugly \r (Ctrl-M making) characters from the current
             # read
@@ -156,14 +189,18 @@
 
             # Display the current buffer in realtime if requested to do so
             # (good for debugging purposes)
-            if self.display:
-                output_callback(current_buffer_decoded)
-
             if strip_ansi:
                 current_buffer_decoded = 
strip_ansi_codes(current_buffer_decoded)
 
+            if not current_buffer_decoded:
+                continue
+
+            if self.display:
+                output_callback(current_buffer_decoded)
+
             # Add the currently read buffer to the output
             self.current_output += current_buffer_decoded
+            current_buffer_output_decoded = '\n' + 
'\n'.join(self.current_output.splitlines()[-lines_to_check:])
 
         # Grab the first pattern that was matched
         if len(re_strings) != 0:
@@ -177,7 +214,7 @@
         if len(self.current_send_string) != 0:
             self.current_output_clean = (
                 self.current_output_clean.replace(
-                    self.current_send_string + '\n', ''
+                    self.current_send_string + self.newline, ''
                 )
             )
 
@@ -200,12 +237,21 @@
             # measure, let's send back a -1
             return -1
 
-    def send(self, send_string):
+    def send(self, send_string, newline=None):
         """Saves and sends the send string provided."""
         self.current_send_string = send_string
-        self.channel.send(send_string + self.newline)
-
-    def tail(self, line_prefix=None, callback=None, output_callback=None, 
stop_callback=lambda x: False, timeout=None):
+        # send_string, _ = codecs.getdecoder(self.encoding)(send_string)
+        newline = newline if newline is not None else self.newline
+        # don't send till send_ready
+        while not self.channel.send_ready():
+            time.sleep(.009)
+        self.channel.send(send_string)
+        self.channel.send(newline)
+
+    def tail(
+        self, line_prefix=None, callback=None, output_callback=None, 
stop_callback=lambda x: False,
+        timeout=None
+    ):
         """
         This function takes control of an SSH channel and displays line
         by line of output as \n is recieved.  This function is specifically
@@ -225,18 +271,18 @@
         :param output_callback: A function used to print ssh output. Printed 
to stdout
                         by default. A user-defined logger may be passed like
                         output_callback=lambda m: mylog.debug(m)
-        :param stop_callback: A function usesd to stop the tail, when function 
retruns 
+        :param stop_callback: A function usesd to stop the tail, when function 
retruns
                         True tail will stop, by default stop_callback=lambda 
x: False
-        :param timeout: how much time to wait for data, default to None which 
+        :param timeout: how much time to wait for data, default to None which
                         mean almost forever.
         """
 
         output_callback = output_callback if output_callback else 
self.output_callback
 
-        # Set the channel timeout to the maximum integer the server allows,
+        # Set the channel timeout to the maximum allowed value,
         # setting this to None breaks the KeyboardInterrupt exception and
-        # won't allow us to Ctrl+C out of teh script
-        timeout = timeout if timeout else  2 ** (struct.Struct(str('i')).size 
* 8 - 1) - 1
+        # won't allow us to Ctrl+C out of the script
+        timeout = timeout if timeout else MAX_TIMEOUT
         self.channel.settimeout(timeout)
 
         # Create an empty line buffer and a line counter
@@ -260,7 +306,7 @@
             # Display the last read line in realtime when we reach a \n
             # character
             if buffer == line_feed_byte:
-                current_line_decoded = current_line.decode(self.encoding)
+                current_line_decoded = self.decoder.decode(current_line)
                 if line_counter:
                     if callback:
                         output_callback(callback(line_prefix, 
current_line_decoded))
@@ -307,7 +353,7 @@
                             buffer = self.channel.recv(self.buffer_size)
                             if len(buffer) == 0:
                                 break
-                            sys.stdout.write(buffer.decode(self.encoding))
+                            sys.stdout.write(self.decoder.decode(buffer))
                             sys.stdout.flush()
                         except socket.timeout:
                             pass
@@ -327,7 +373,7 @@
                     buffer = sock.recv(self.buffer_size)
                     if len(buffer) == 0:
                         break
-                    sys.stdout.write(buffer.decode(self.encoding))
+                    sys.stdout.write(self.decoder.decode(buffer))
                     sys.stdout.flush()
 
             writer = threading.Thread(target=writeall, args=(self.channel,))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/paramiko-expect-0.2.8/setup.cfg 
new/paramiko-expect-0.3.2/setup.cfg
--- old/paramiko-expect-0.2.8/setup.cfg 2017-05-15 23:02:20.000000000 +0200
+++ new/paramiko-expect-0.3.2/setup.cfg 2022-01-13 13:07:35.973393200 +0100
@@ -4,5 +4,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/paramiko-expect-0.2.8/setup.py 
new/paramiko-expect-0.3.2/setup.py
--- old/paramiko-expect-0.2.8/setup.py  2017-05-15 23:01:24.000000000 +0200
+++ new/paramiko-expect-0.3.2/setup.py  2022-01-13 13:07:25.000000000 +0100
@@ -8,13 +8,14 @@
 
 setup(
     name='paramiko-expect',
-    version='0.2.8',
+    version='0.3.2',
     url='https://github.com/fgimian/paramiko-expect',
     license='MIT',
     author='Fotis Gimian',
     author_email='fgimiansoftw...@gmail.com',
     description='An expect-like extension for the Paramiko SSH library',
     long_description=long_description,
+    long_description_content_type='text/x-rst',
     platforms='Posix',
     py_modules=['paramiko_expect'],
     install_requires=[
@@ -23,9 +24,7 @@
     classifiers=[
         'Development Status :: 4 - Beta',
         'License :: OSI Approved :: MIT License',
-        'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3.3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/paramiko-expect-0.2.8/test/test_paramiko_expect.py 
new/paramiko-expect-0.3.2/test/test_paramiko_expect.py
--- old/paramiko-expect-0.2.8/test/test_paramiko_expect.py      2017-05-15 
23:01:24.000000000 +0200
+++ new/paramiko-expect-0.3.2/test/test_paramiko_expect.py      2022-01-13 
13:07:25.000000000 +0100
@@ -1,5 +1,5 @@
-import io
-import sys
+# -*- coding: utf-8 -*-
+
 import socket
 
 import pytest
@@ -13,15 +13,15 @@
 from paramiko_expect import SSHClientInteraction
 
 try:
-    from contextlib import ExitStack, contextmanager
+    from contextlib import ExitStack
 except ImportError:
-    from contextlib2 import ExitStack, contextmanager
+    from contextlib2 import ExitStack
+
+prompt = ".*:~#.*"
 
-prompt=".*:~#.*"
 
 @pytest.fixture(scope="module")
 def interact(request):
-
     # Create a new SSH client object
     client = paramiko.SSHClient()
     # Set SSH key parameters to auto accept unknown hosts
@@ -30,11 +30,11 @@
     client.connect(hostname="localhost", username="root", port=2222, 
key_filename='./test/id_rsa')
     # Create a client interaction class which will interact with the host
     interact = SSHClientInteraction(client, timeout=10, display=True)
-    
+
     def fin():
         interact.send('exit')
         interact.expect()
-        
+
         interact.close()
 
     request.addfinalizer(fin)
@@ -42,23 +42,24 @@
 
 
 def test_01_install_python(interact):
-
     interact.send('apk update')
     interact.expect(prompt, timeout=120)
 
-    interact.send('apk add python')
+    interact.send('apk add python3')
     interact.expect(prompt, timeout=120)
 
     interact.send('apk add curl')
     interact.expect(prompt, timeout=120)
 
+
 def test_02_test_other_commnads(interact):
     interact.send('ls -l /')
     interact.expect(prompt, timeout=5)
 
+
 def test_03_test_demo_helper(interact):
     interact.expect(prompt)
-    interact.send('python /examples/paramiko_expect-demo-helper.py')
+    interact.send('python3 /examples/paramiko_expect-demo-helper.py')
     found_index = interact.expect([prompt, '.*Please enter your name:.*'])
     assert interact.last_match == '.*Please enter your name:.*'
     assert found_index == 1
@@ -68,38 +69,41 @@
 
 
 def test_04_tail(interact):
-
     interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
     def stop_callback(msg):
-       return "Connection #0 to host httpbin.org left intact" in msg
+        return "Connection #0 to host httpbin.org left intact" in msg
     interact.tail(stop_callback=stop_callback)
 
-def test_04_tail_line_prefix(interact):
 
+def test_04_tail_line_prefix(interact):
     interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
     def stop_callback(msg):
-       return "Connection #0 to host httpbin.org left intact" in msg
+        return "Connection #0 to host httpbin.org left intact" in msg
     interact.tail(line_prefix="test:",  stop_callback=stop_callback)
 
-def test_04_tail_callback(interact):
 
+def test_04_tail_callback(interact):
     interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
     def stop_callback(msg):
-       return "Connection #0 to host httpbin.org left intact" in msg
-    interact.tail(line_prefix="test:", callback=lambda p, m: "" 
,stop_callback=stop_callback)
+        return "Connection #0 to host httpbin.org left intact" in msg
+    interact.tail(line_prefix="test:", callback=lambda p, m: "", 
stop_callback=stop_callback)
 
-def test_04_tail_empty_response(interact):
 
+def test_04_tail_empty_response(interact):
     interact.send('sleep 1; curl -v https://httpbin.org/stream/100')
+
     def stop_callback(msg):
-       return "Connection #0 to host httpbin.org left intact" in msg
+        return "Connection #0 to host httpbin.org left intact" in msg
 
     with mock.patch.object(interact, 'channel') as channel_mock:
-        channel_mock.recv.side_effect = [ b"" ]        
-        interact.tail(line_prefix="test:", callback=lambda p, m: "" 
,stop_callback=stop_callback)
+        channel_mock.recv.side_effect = [b""]
+        interact.tail(line_prefix="test:", callback=lambda p, m: "", 
stop_callback=stop_callback)
 
-def test_05_context():
 
+def test_05_context():
     client = paramiko.SSHClient()
     client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
     client.connect(hostname="localhost", username="root", port=2222, 
key_filename='./test/id_rsa')
@@ -107,58 +111,71 @@
         interact.send('ls -all /')
         interact.expect(prompt, timeout=120)
 
-def test_06_take_control_01(interact):
 
+def test_06_take_control_01(interact):
     with ExitStack() as stack:
-        mocks = [ mock.patch('termios.tcsetattr'), 
mock.patch('termios.tcgetattr'),
-            mock.patch('tty.setraw'), mock.patch('tty.setcbreak') ]
-        [ stack.enter_context(m) for m in mocks ]
+        mocks = [
+            mock.patch('termios.tcsetattr'), mock.patch('termios.tcgetattr'),
+            mock.patch('tty.setraw'), mock.patch('tty.setcbreak')
+        ]
+        [stack.enter_context(m) for m in mocks]
 
         select_mock = stack.enter_context(mock.patch('select.select'))
         channel_mock = stack.enter_context(mock.patch.object(interact, 
'channel'))
         stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
 
-        channel_mock.recv.side_effect = [ b"test", b"test" ]
+        channel_mock.recv.side_effect = [b"test", b"test"]
         stdin_mock.read.side_effect = [b"ls -all\n", b""]
-        select_mock.side_effect = [ [[stdin_mock,], [], []], [[stdin_mock, 
channel_mock], [], []] ]
+        select_mock.side_effect = [
+            [[stdin_mock], [], []],
+            [[stdin_mock, channel_mock], [], []]
+        ]
         interact.take_control()
 
 
 def test_06_take_control_02(interact):
-
     with ExitStack() as stack:
-        mocks = [ mock.patch('termios.tcsetattr'), 
mock.patch('termios.tcgetattr'),
-            mock.patch('tty.setraw'), mock.patch('tty.setcbreak') ]
-        [ stack.enter_context(m) for m in mocks ]
+        mocks = [
+            mock.patch('termios.tcsetattr'), mock.patch('termios.tcgetattr'),
+            mock.patch('tty.setraw'), mock.patch('tty.setcbreak')
+        ]
+        [stack.enter_context(m) for m in mocks]
 
         select_mock = stack.enter_context(mock.patch('select.select'))
         channel_mock = stack.enter_context(mock.patch.object(interact, 
'channel'))
         stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
 
-        channel_mock.recv.side_effect = [ socket.timeout() ] 
+        channel_mock.recv.side_effect = [socket.timeout()]
         stdin_mock.read.side_effect = [b"ls -all\n", b""]
-        select_mock.side_effect = [ [[stdin_mock,], [], []], [[stdin_mock, 
channel_mock], [], []] ]
+        select_mock.side_effect = [
+            [[stdin_mock], [], []],
+            [[stdin_mock, channel_mock], [], []]
+        ]
         interact.take_control()
 
 
 def test_06_take_control_03(interact):
-
     with ExitStack() as stack:
-        mocks = [ mock.patch('termios.tcsetattr'), 
mock.patch('termios.tcgetattr'), 
-            mock.patch('tty.setraw'), mock.patch('tty.setcbreak') ]
-        [ stack.enter_context(m) for m in mocks ]
+        mocks = [
+            mock.patch('termios.tcsetattr'), mock.patch('termios.tcgetattr'),
+            mock.patch('tty.setraw'), mock.patch('tty.setcbreak')
+        ]
+        [stack.enter_context(m) for m in mocks]
 
         select_mock = stack.enter_context(mock.patch('select.select'))
         channel_mock = stack.enter_context(mock.patch.object(interact, 
'channel'))
         stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
 
-        channel_mock.recv.side_effect = [ "" ] 
+        channel_mock.recv.side_effect = [""]
         stdin_mock.read.side_effect = [b"ls -all\n", b""]
-        select_mock.side_effect = [ [[stdin_mock,], [], []], [[stdin_mock, 
channel_mock], [], []] ]
+        select_mock.side_effect = [
+            [[stdin_mock], [], []],
+            [[stdin_mock, channel_mock], [], []]
+        ]
         interact.take_control()
 
-def test_06_take_control_no_termios_01(interact):
 
+def test_06_take_control_no_termios_01(interact):
     paramiko_expect.has_termios = False
     import threading
     paramiko_expect.threading = threading
@@ -167,7 +184,7 @@
         channel_mock = stack.enter_context(mock.patch.object(interact, 
'channel'))
         stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
 
-        channel_mock.recv.side_effect = [ b"test" ]
+        channel_mock.recv.side_effect = [b"test"]
         stdin_mock.read.side_effect = [b"ls -all\n", b""]
         interact.take_control()
 
@@ -182,12 +199,12 @@
         channel_mock = stack.enter_context(mock.patch.object(interact, 
'channel'))
         stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
 
-        channel_mock.recv.side_effect = [ b"" ]
+        channel_mock.recv.side_effect = [b""]
         stdin_mock.read.side_effect = [b"ls -all\n", b""]
         interact.take_control()
 
-def test_06_take_control_no_termios_03(interact):
 
+def test_06_take_control_no_termios_03(interact):
     paramiko_expect.has_termios = False
     import threading
     paramiko_expect.threading = threading
@@ -196,14 +213,33 @@
         channel_mock = stack.enter_context(mock.patch.object(interact, 
'channel'))
         stdin_mock = stack.enter_context(mock.patch('sys.stdin'))
 
-        channel_mock().recv.side_effect = [ b"test", b"test"]
+        channel_mock().recv.side_effect = [b"test", b"test"]
         stdin_mock.read.side_effect = [b"ls -all\n", EOFError()]
         interact.take_control()
 
 
 def test_07_close(interact):
-
     with mock.patch.object(interact, 'channel') as channel_mock:
-        channel_mock.close.side_effect = [ socket.timeout ]
+        channel_mock.close.side_effect = [socket.timeout]
         interact.close()
 
+
+def test_08_issue_25_skip_newline():
+    client = paramiko.SSHClient()
+    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+    client.connect(hostname="localhost", username="root", port=2222, 
key_filename='./test/id_rsa')
+    with SSHClientInteraction(client, timeout=10, display=True) as interact:
+        interact.send('ls -all')
+        interact.expect(prompt, timeout=5)
+
+        # Do not actually sleep, send a ctrl-c at the end
+        interact.send('sleep 1', newline=chr(3))
+        interact.expect(prompt, timeout=5)
+        interact.send('sleep 1' + chr(3), newline='')
+        interact.expect(prompt, timeout=5)
+
+        interact.send('ls -all')
+        interact.expect(prompt, timeout=5)
+
+def test_09_utf8(interact):
+    interact.send(u'Andr??')

Reply via email to