mirror of
https://github.com/clearml/wexpect-venv
synced 2025-05-07 13:44:43 +00:00
[CLN] replace pexpect -> wexpect
This commit is contained in:
parent
a10eb6a368
commit
063aea8ddf
141
wexpect.py
141
wexpect.py
@ -1,21 +1,21 @@
|
||||
"""Pexpect is a Python module for spawning child applications and controlling
|
||||
them automatically. Pexpect can be used for automating interactive applications
|
||||
"""Wexpect is a Windows variant of pexpect https://pexpect.readthedocs.io.
|
||||
|
||||
Wexpect is a Python module for spawning child applications and controlling
|
||||
them automatically. Wexpect 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 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. Other Expect-like modules for Python
|
||||
require TCL and Expect or require C extensions to be compiled. Pexpect does not
|
||||
use C, Expect, or TCL extensions. It should work on any platform that supports
|
||||
the standard Python pty module. The Pexpect interface focuses on ease of use so
|
||||
that simple tasks are easy.
|
||||
can be used for automated software testing. Wexpect is in the spirit of Don
|
||||
Libes' Expect, but Wexpect is pure Python. Other Expect-like modules for Python
|
||||
require TCL and Expect or require C extensions to be compiled. Wexpect does not
|
||||
use C, Expect, or TCL extensions.
|
||||
|
||||
There are two main interfaces to Pexpect -- the function, run() and the class,
|
||||
There are two main interfaces to Wexpect -- the function, run() and the class,
|
||||
spawn. You can call the run() function to execute a command and return the
|
||||
output. This is a handy replacement for os.system().
|
||||
|
||||
For example::
|
||||
|
||||
pexpect.run('ls -la')
|
||||
wexpect.run('ls -la')
|
||||
|
||||
The more powerful interface is the spawn class. You can use this to spawn an
|
||||
external child command and then interact with the child by sending lines and
|
||||
@ -23,9 +23,9 @@ expecting responses.
|
||||
|
||||
For example::
|
||||
|
||||
child = pexpect.spawn('scp foo myname@host.example.com:.')
|
||||
child.expect ('Password:')
|
||||
child.sendline (mypassword)
|
||||
child = wexpect.spawn('scp foo myname@host.example.com:.')
|
||||
child.expect('Password:')
|
||||
child.sendline(mypassword)
|
||||
|
||||
This works even for commands that ask for passwords or other input outside of
|
||||
the normal stdio streams.
|
||||
@ -35,7 +35,7 @@ Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids
|
||||
vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin,
|
||||
Geoffrey Marshall, Francisco Lourenco, Glen Mabey, Karthik Gurusamy, Fernando
|
||||
Perez, Corey Minyard, Jon Cohen, Guillaume Chazarain, Andrew Ryan, Nick
|
||||
Craig-Wood, Andrew Stone, Jorgen Grahn (Let me know if I forgot anyone.)
|
||||
Craig-Wood, Andrew Stone, Jorgen Grahn, Benedek Racz
|
||||
|
||||
Free, open source, and all that good stuff.
|
||||
|
||||
@ -57,10 +57,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Pexpect Copyright (c) 2008 Noah Spurrier
|
||||
http://pexpect.sourceforge.net/
|
||||
Wexpect Copyright (c) 2019 Benedek Racz
|
||||
|
||||
$Id: pexpect.py 507 2007-12-27 02:40:52Z noah $
|
||||
"""
|
||||
|
||||
#
|
||||
@ -168,21 +166,20 @@ class ExceptionPexpect(Exception):
|
||||
warnings.warn(deprecation_warning.format("ExceptionPexpect::get_trace"), DeprecationWarning)
|
||||
|
||||
"""This returns an abbreviated stack trace with lines that only concern
|
||||
the caller. In other words, the stack trace inside the Pexpect module
|
||||
the caller. In other words, the stack trace inside the Wexpect module
|
||||
is not included. """
|
||||
|
||||
tblist = traceback.extract_tb(sys.exc_info()[2])
|
||||
#tblist = filter(self.__filter_not_pexpect, tblist)
|
||||
tblist = [item for item in tblist if self.__filter_not_pexpect(item)]
|
||||
tblist = [item for item in tblist if self.__filter_not_wexpect(item)]
|
||||
tblist = traceback.format_list(tblist)
|
||||
return ''.join(tblist)
|
||||
|
||||
def __filter_not_pexpect(self, trace_list_item): # pragma: no cover
|
||||
warnings.warn(deprecation_warning.format("ExceptionPexpect::__filter_not_pexpect"), DeprecationWarning)
|
||||
def __filter_not_wexpect(self, trace_list_item): # pragma: no cover
|
||||
warnings.warn(deprecation_warning.format("ExceptionPexpect::__filter_not_wexpect"), DeprecationWarning)
|
||||
|
||||
"""This returns True if list item 0 the string 'pexpect.py' in it. """
|
||||
"""This returns True if list item 0 the string 'wexpect.py' in it. """
|
||||
|
||||
if trace_list_item[0].find('pexpect.py') == -1:
|
||||
if trace_list_item[0].find('wexpect.py') == -1:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@ -241,9 +238,6 @@ def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None
|
||||
|
||||
run ("ssh username@machine.example.com 'ls -l'", events={'(?i)password':'secret\\n'})
|
||||
|
||||
This will start mencoder to rip a video from DVD. This will also display
|
||||
progress ticks every 5 seconds as it runs. For example::
|
||||
|
||||
The 'events' argument should be a dictionary of patterns and responses.
|
||||
Whenever one of the patterns is seen in the command out run() will send the
|
||||
associated response string. Note that you should put newlines in your
|
||||
@ -304,50 +298,29 @@ def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None
|
||||
|
||||
def spawn(command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None,
|
||||
codepage=None):
|
||||
log('=' * 80)
|
||||
log('Buffer size: %s' % maxread)
|
||||
if searchwindowsize:
|
||||
log('Search window size: %s' % searchwindowsize)
|
||||
log('Timeout: %ss' % timeout)
|
||||
if env:
|
||||
log('Environment:')
|
||||
for name in env:
|
||||
log('\t%s=%s' % (name, env[name]))
|
||||
if cwd:
|
||||
log('Working directory: %s' % cwd)
|
||||
|
||||
return spawn_windows(command, args, timeout, maxread, searchwindowsize, logfile, cwd, env,
|
||||
codepage)
|
||||
|
||||
class spawn_windows ():
|
||||
"""This is the main class interface for Pexpect. Use this class to start
|
||||
and control child applications. """
|
||||
|
||||
def __init__(self, command, args=[], timeout=30, maxread=60000, searchwindowsize=None, logfile=None, cwd=None, env=None,
|
||||
codepage=None):
|
||||
"""This is the constructor. The command parameter may be a string that
|
||||
"""This is the most essential function. The command parameter may be a string that
|
||||
includes a command and any arguments to the command. For example::
|
||||
|
||||
child = pexpect.spawn ('/usr/bin/ftp')
|
||||
child = pexpect.spawn ('/usr/bin/ssh user@example.com')
|
||||
child = pexpect.spawn ('ls -latr /tmp')
|
||||
child = wexpect.spawn ('/usr/bin/ftp')
|
||||
child = wexpect.spawn ('/usr/bin/ssh user@example.com')
|
||||
child = wexpect.spawn ('ls -latr /tmp')
|
||||
|
||||
You may also construct it with a list of arguments like so::
|
||||
|
||||
child = pexpect.spawn ('/usr/bin/ftp', [])
|
||||
child = pexpect.spawn ('/usr/bin/ssh', ['user@example.com'])
|
||||
child = pexpect.spawn ('ls', ['-latr', '/tmp'])
|
||||
child = wexpect.spawn ('/usr/bin/ftp', [])
|
||||
child = wexpect.spawn ('/usr/bin/ssh', ['user@example.com'])
|
||||
child = wexpect.spawn ('ls', ['-latr', '/tmp'])
|
||||
|
||||
After this the child application will be created and will be ready to
|
||||
talk to. For normal use, see expect() and send() and sendline().
|
||||
|
||||
Remember that Pexpect does NOT interpret shell meta characters such as
|
||||
Remember that Wexpect does NOT interpret shell meta characters such as
|
||||
redirect, pipe, or wild cards (>, |, or *). This is a common mistake.
|
||||
If you want to run a command and pipe it through another command then
|
||||
you must also start a shell. For example::
|
||||
|
||||
child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"')
|
||||
child.expect(pexpect.EOF)
|
||||
child = wexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"')
|
||||
child.expect(wexpect.EOF)
|
||||
|
||||
The second form of spawn (where you pass a list of arguments) is useful
|
||||
in situations where you wish to spawn a command and pass it its own
|
||||
@ -355,19 +328,19 @@ class spawn_windows ():
|
||||
following is equivalent to the previous example::
|
||||
|
||||
shell_cmd = 'ls -l | grep LOG > log_list.txt'
|
||||
child = pexpect.spawn('/bin/bash', ['-c', shell_cmd])
|
||||
child.expect(pexpect.EOF)
|
||||
child = wexpect.spawn('/bin/bash', ['-c', shell_cmd])
|
||||
child.expect(wexpect.EOF)
|
||||
|
||||
The maxread attribute sets the read buffer size. This is maximum number
|
||||
of bytes that Pexpect will try to read from a TTY at one time. Setting
|
||||
of bytes that Wexpect will try to read from a TTY at one time. Setting
|
||||
the maxread size to 1 will turn off buffering. Setting the maxread
|
||||
value higher may help performance in cases where large amounts of
|
||||
output are read back from the child. This feature is useful in
|
||||
conjunction with searchwindowsize.
|
||||
|
||||
The searchwindowsize attribute sets the how far back in the incomming
|
||||
seach buffer Pexpect will search for pattern matches. Every time
|
||||
Pexpect reads some data from the child it will append the data to the
|
||||
seach buffer Wexpect will search for pattern matches. Every time
|
||||
Wexpect reads some data from the child it will append the data to the
|
||||
incomming buffer. The default is to search from the beginning of the
|
||||
imcomming buffer each time new data is read from the child. But this is
|
||||
very inefficient if you are running a command that generates a large
|
||||
@ -382,13 +355,13 @@ class spawn_windows ():
|
||||
|
||||
Example log input and output to a file::
|
||||
|
||||
child = pexpect.spawn('some_command')
|
||||
child = wexpect.spawn('some_command')
|
||||
fout = file('mylog.txt','w')
|
||||
child.logfile = fout
|
||||
|
||||
Example log to stdout::
|
||||
|
||||
child = pexpect.spawn('some_command')
|
||||
child = wexpect.spawn('some_command')
|
||||
child.logfile = sys.stdout
|
||||
|
||||
The logfile_read and logfile_send members can be used to separately log
|
||||
@ -396,7 +369,7 @@ class spawn_windows ():
|
||||
don't want to see everything you write to the child. You only want to
|
||||
log what the child sends back. For example::
|
||||
|
||||
child = pexpect.spawn('some_command')
|
||||
child = wexpect.spawn('some_command')
|
||||
child.logfile_read = sys.stdout
|
||||
|
||||
To separately log output sent to the child use logfile_send::
|
||||
@ -414,7 +387,7 @@ class spawn_windows ():
|
||||
Normally this wouldn't be a problem when interacting with a human at a
|
||||
real keyboard. If you introduce a slight delay just before writing then
|
||||
this seems to clear up the problem. This was such a common problem for
|
||||
many users that I decided that the default pexpect behavior should be
|
||||
many users that I decided that the default wexpect behavior should be
|
||||
to sleep just before writing to the child application. 1/20th of a
|
||||
second (50 ms) seems to be enough to clear up the problem. You can set
|
||||
delaybeforesend to 0 to return to the old behavior. Most Linux machines
|
||||
@ -433,6 +406,29 @@ class spawn_windows ():
|
||||
stores the status returned by os.waitpid. You can interpret this using
|
||||
os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. """
|
||||
|
||||
log('=' * 80)
|
||||
log('Buffer size: %s' % maxread)
|
||||
if searchwindowsize:
|
||||
log('Search window size: %s' % searchwindowsize)
|
||||
log('Timeout: %ss' % timeout)
|
||||
if env:
|
||||
log('Environment:')
|
||||
for name in env:
|
||||
log('\t%s=%s' % (name, env[name]))
|
||||
if cwd:
|
||||
log('Working directory: %s' % cwd)
|
||||
|
||||
return spawn_windows(command, args, timeout, maxread, searchwindowsize, logfile, cwd, env,
|
||||
codepage)
|
||||
|
||||
class spawn_windows ():
|
||||
"""This is the main class interface for Wexpect. Use this class to start
|
||||
and control child applications. """
|
||||
|
||||
def __init__(self, command, args=[], timeout=30, maxread=60000, searchwindowsize=None, logfile=None, cwd=None, env=None,
|
||||
codepage=None):
|
||||
""" The spawn_windows constructor. Do not call it directly. Use spawn(), or run() instead.
|
||||
"""
|
||||
self.codepage = codepage
|
||||
|
||||
self.stdin = sys.stdin
|
||||
@ -460,7 +456,6 @@ class spawn_windows ():
|
||||
self.maxread = maxread # max bytes to read at one time into buffer
|
||||
self.buffer = '' # This is the read buffer. See maxread.
|
||||
self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched.
|
||||
# Most Linux machines don't like delaybeforesend to be below 0.03 (30 ms).
|
||||
self.delaybeforesend = 0.05 # Sets sleep time used just before sending data to child. Time in seconds.
|
||||
self.delayafterclose = 0.1 # Sets delay in close() method to allow kernel time to update process status. Time in seconds.
|
||||
self.delayafterterminate = 0.1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds.
|
||||
@ -476,7 +471,7 @@ class spawn_windows ():
|
||||
if command is None:
|
||||
self.command = None
|
||||
self.args = None
|
||||
self.name = '<pexpect factory incomplete>'
|
||||
self.name = '<wexpect factory incomplete>'
|
||||
else:
|
||||
self._spawn (command, args)
|
||||
|
||||
@ -616,7 +611,7 @@ class spawn_windows ():
|
||||
example, instead of expecting the "password:" prompt you can wait for
|
||||
the child to set ECHO off::
|
||||
|
||||
p = pexpect.spawn ('ssh user@example.com')
|
||||
p = wexpect.spawn ('ssh user@example.com')
|
||||
p.waitnoecho()
|
||||
p.sendline(mypassword)
|
||||
|
||||
@ -1033,7 +1028,7 @@ class spawn_windows ():
|
||||
exception type. The attribute 'match' will be None. This allows you to
|
||||
write code like this::
|
||||
|
||||
index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
|
||||
index = p.expect (['good', 'bad', wexpect.EOF, wexpect.TIMEOUT])
|
||||
if index == 0:
|
||||
do_something()
|
||||
elif index == 1:
|
||||
@ -1060,8 +1055,8 @@ class spawn_windows ():
|
||||
can also just expect the EOF if you are waiting for all output of a
|
||||
child to finish. For example::
|
||||
|
||||
p = pexpect.spawn('/bin/ls')
|
||||
p.expect (pexpect.EOF)
|
||||
p = wexpect.spawn('/bin/ls')
|
||||
p.expect (wexpect.EOF)
|
||||
print p.before
|
||||
|
||||
If you are trying to optimize for speed then see expect_list().
|
||||
|
Loading…
Reference in New Issue
Block a user