Fixed OSError exception when a pexpect object is cleaned up. Previously you might have seen this exception:
Exception exceptions.OSError: (10, 'No child processes')
in <bound method spawn.__del__ of
<pexpect.spawn instance at 0xd248c>> ignored
You should not see that anymore. Thanks to Michael Surette.
Added support for buffering reads. This greatly improves speed when trying to match long output from a child process. When you create an instance of the spawn object you can then set a buffer size. For now you MUST do the following to turn on buffering -- it may be on by default in future version.
child = pexpect.spawn ('my_command')
child.maxread=1000 # Sets buffer to 1000 characters.
I made a subtle change to the way TIMEOUT and EOF exceptions behave. Previously you could either expect these states in which case pexpect will not raise an exception, or you could just let pexpect raise an exception when these states were encountered. If you expected the states then the 'before' property was set to everything before the state was encountered, but if you let pexpect raise the exception then 'before' was not set. Now the 'before' property will get set either way you choose to handle these states.
The spawn object now provides iterators for a file-like interface. This makes Pexpect a more complete file-like object. You can now write code like this:
child = pexpect.spawn ('ls -l')
for line in child:
print line
I added the attribute exitstatus. This will give the exit code returned by the child process. This will be set to None while the child is still alive. When isalive() returns 0 then exitstatus will be set.
I made a few more tweaks to isalive() so that it will operate more consistently on different platforms. Solaris is the most difficult to support.
You can now put TIMEOUT in a list of expected patterns. This is just like putting EOF in the pattern list. Expecting for a TIMEOUT may not be used as often as EOF, but this makes Pexpect more consitent.
Thanks to a suggestion and sample code from Chad J. Schroeder I added the ability for Pexpect to operate on a file descriptor that is already open. This means that Pexpect can be used to control streams such as those from serial port devices. Now you just pass the integer file descriptor as the "command" when contsructing a spawn open. For example on a Linux box with a modem on ttyS1:
fd = os.open("/dev/ttyS1", os.O_RDWR|os.O_NONBLOCK|os.O_NOCTTY)
m = pexpect.spawn(fd) # Note integer fd is used instead of usual string.
m.send("+++") # Escape sequence
m.send("ATZ0\r") # Reset modem to profile 0
rval = m.expect(["OK", "ERROR"])
I wrote a nice script that uses ssh to connect to each machine on Source Forge's Compile Farm and then run the testall.py script for each platform. The result of the test is then recorded for each platform. Now it's easy to run regression tests across multiple platforms.
The spawn object now provides a file-like interface. It supports most of the methods and attributes defined for Python File Objects.
I changed write and writelines() so that they no longer return a value. Use send() if you need that functionality. I did this to make the Spawn object more closely match a file-like object.
read() was renamed to read_nonblocking(). I added a new read() method that matches file-like object interface. In general, you should not notice the difference except that read() no longer allows you to directly set the timeout value. I hope this will not effect any existing code. Switching to read_nonblocking() should fix existing code.
I changed the name of set_echo() to setecho().
I changed the name of send_eof() to sendeof().
I modified kill() so that it checks to make sure the pid isalive().
I modified spawn() (really called from __spawn())so that it does not raise an expection if setwinsize() fails. Some platforms such as Cygwin do not like setwinsize. This was a constant problem and since it is not a critical feature I decided to just silence the error. Normally I don't like to do that, but in this case I'm making an exception.
Added a method close() that does what you think. It closes the file descriptor of the child application. It makes no attempt to actually kill the child or wait for its status.
Add variables __version__ and __revision__ (from cvs) to the pexpect modules. This is mainly helpful to me so that I can make sure that I'm testing with the right version instead of one already installed.
log_open() and log_close() have been removed. Now use setlog(). The setlog() method takes a file object. This is far more flexible than the previous log method. Each time data is written to the file object it will be flushed. To turn logging off simply call setlog() with None.
I renamed the isAlive() method to isalive() to match the more typical naming style in Python. Also the technique used to detect child process status has been drastically modified. Previously I did some funky stuff with signals which caused indigestion in other Python modules on some platforms. It's was a big headache. It still is, but I think it works better now.
The names of some attributes have been changed. This effects the names of the attributes that are set after called the expect() method.
NEW NAME OLD NAME before
Everything before the match.before after
Everything after and including the first character of the matchmatched match
This is the re MatchObject from the match.
You can get groups() from this.
See 'uptime.py' in the examples tar ball.New -- Did not exist
The expect_eof() method is gone. You can now simply use the expect() method to look for EOF.
Was:
p.expect_eof ()
Now:
p.expect (pexpect.EOF)
The following platforms have been tested:
Add an option to add a delay after each expect() or before each read()/readline() call to automatically avoid the echo bug.
![]() |