summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kluyver <takowl@gmail.com>2015-05-20 15:49:51 -0700
committerThomas Kluyver <takowl@gmail.com>2015-05-20 15:49:51 -0700
commit57a55194771088b8ad076c3aea591e2355c15979 (patch)
tree8d9d9e966e4a727286a82d85f20c5e660bbeb2e6
parent82d4937b73a2fc49824e1f60fa0e036731a03135 (diff)
parente2e7952f23ffdc6486b70bb5288ee6a39fc95ddc (diff)
downloadpexpect-git-57a55194771088b8ad076c3aea591e2355c15979.tar.gz
Merge pull request #211 from pexpect/noexception-on-wait-after-terminate
Do not raise Exception on wait() after terminate or previous wait()
-rw-r--r--doc/history.rst3
-rw-r--r--pexpect/pty_spawn.py9
-rw-r--r--setup.py2
-rwxr-xr-xtests/test_isalive.py27
4 files changed, 31 insertions, 10 deletions
diff --git a/doc/history.rst b/doc/history.rst
index 95bf371..7844270 100644
--- a/doc/history.rst
+++ b/doc/history.rst
@@ -14,6 +14,9 @@ Version 4.0
waiting for output that matches a pattern.
* Enhancement: allow method as callbacks of argument ``events`` for
:func:`pexpect.run` (:ghissue:`176`).
+* It is now possible to call :meth:`~.wait` multiple times, or after a process
+ is already determined to be terminated without raising an exception
+ (:ghpull:`211`).
Version 3.4
```````````
diff --git a/pexpect/pty_spawn.py b/pexpect/pty_spawn.py
index 0ba1e0c..fe2cc0c 100644
--- a/pexpect/pty_spawn.py
+++ b/pexpect/pty_spawn.py
@@ -614,10 +614,17 @@ class spawn(SpawnBase):
not read any data from the child, so this will block forever if the
child has unread output and has terminated. In other words, the child
may have printed output then called exit(), but, the child is
- technically still alive until its output is read by the parent. '''
+ technically still alive until its output is read by the parent.
+
+ This method is non-blocking if :meth:`wait` has already been called
+ previously or :meth:`isalive` method returns False. It simply returns
+ the previously determined exit status.
+ '''
ptyproc = self.ptyproc
with _wrap_ptyprocess_err():
+ # exception may occur if "Is some other process attempting
+ # "job control with our child pid?"
exitstatus = ptyproc.wait()
self.status = ptyproc.status
self.exitstatus = ptyproc.exitstatus
diff --git a/setup.py b/setup.py
index 126749a..feb5e64 100644
--- a/setup.py
+++ b/setup.py
@@ -61,5 +61,5 @@ setup (name='pexpect',
'Topic :: System :: Software Distribution',
'Topic :: Terminals',
],
- install_requires=['ptyprocess'],
+ install_requires=['ptyprocess>=0.5'],
)
diff --git a/tests/test_isalive.py b/tests/test_isalive.py
index 5168a52..cd79d09 100755
--- a/tests/test_isalive.py
+++ b/tests/test_isalive.py
@@ -25,22 +25,33 @@ import sys
import time
from . import PexpectTestCase
+
class IsAliveTestCase(PexpectTestCase.PexpectTestCase):
+ """Various tests for the running status of processes."""
- def test_expect_wait (self):
- '''This tests that calling wait on a finished process works as expected.
- '''
- p = pexpect.spawn('sleep 3')
+ def test_expect_wait(self):
+ """Ensure consistency in wait() and isalive()."""
+ p = pexpect.spawn('sleep 1')
assert p.isalive()
- p.wait()
+ assert p.wait() == 0
assert not p.isalive()
+ # In previous versions of ptyprocess/pexpect, calling wait() a second
+ # time would raise an exception, but not since v4.0
+ assert p.wait() == 0
+ def test_expect_wait_after_termination(self):
+ """Ensure wait on a process terminated by kill -9."""
p = pexpect.spawn('sleep 3')
assert p.isalive()
p.kill(9)
time.sleep(1)
- with self.assertRaises(pexpect.ExceptionPexpect):
- p.wait()
+
+ # when terminated, the exitstatus is None, but p.signalstatus
+ # and p.terminated reflects that the kill -9 nature.
+ assert p.wait() is None
+ assert p.signalstatus == 9
+ assert p.terminated == True
+ assert not p.isalive()
def test_signal_wait(self):
'''Test calling wait with a process terminated by a signal.'''
@@ -102,7 +113,7 @@ class IsAliveTestCase(PexpectTestCase.PexpectTestCase):
p = pexpect.spawn('cat')
assert p.isalive()
assert p.isalive()
- p.kill(9)
+ p.sendeof()
p.expect(pexpect.EOF)
assert not p.isalive()
assert not p.isalive()