summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kluyver <thomas@kluyver.me.uk>2017-08-22 14:56:46 +0100
committerThomas Kluyver <thomas@kluyver.me.uk>2017-08-22 14:56:46 +0100
commite276c17250516ff5a3deca924e35fd3fa68957d9 (patch)
treed98167086ddc11b8e4d67aaae50cce143eaeba64
parent8b4974f333f2d41b47a67c94c4c445a274d8ddd4 (diff)
parent964e03d4f63ecb045832cac9938be56feaeba46c (diff)
downloadpexpect-git-e276c17250516ff5a3deca924e35fd3fa68957d9.tar.gz
Merge branch 'master' of github.com:pexpect/pexpect
-rw-r--r--pexpect/popen_spawn.py3
-rw-r--r--pexpect/pty_spawn.py5
-rw-r--r--pexpect/spawnbase.py32
-rw-r--r--pexpect/utils.py5
-rw-r--r--tests/test_async.py30
5 files changed, 48 insertions, 27 deletions
diff --git a/pexpect/popen_spawn.py b/pexpect/popen_spawn.py
index 600ac92..c9d4738 100644
--- a/pexpect/popen_spawn.py
+++ b/pexpect/popen_spawn.py
@@ -15,6 +15,7 @@ except ImportError:
from .spawnbase import SpawnBase, PY3
from .exceptions import EOF
+from .utils import string_types
class PopenSpawn(SpawnBase):
if PY3:
@@ -39,7 +40,7 @@ class PopenSpawn(SpawnBase):
kwargs['startupinfo'] = startupinfo
kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
- if not isinstance(cmd, (list, tuple)):
+ if isinstance(cmd, string_types):
cmd = shlex.split(cmd)
self.proc = subprocess.Popen(cmd, **kwargs)
diff --git a/pexpect/pty_spawn.py b/pexpect/pty_spawn.py
index 0d44230..4afda6a 100644
--- a/pexpect/pty_spawn.py
+++ b/pexpect/pty_spawn.py
@@ -316,7 +316,10 @@ class spawn(SpawnBase):
and SIGINT). '''
self.flush()
- self.ptyproc.close(force=force)
+ with _wrap_ptyprocess_err():
+ # PtyProcessError may be raised if it is not possible to terminate
+ # the child.
+ self.ptyproc.close(force=force)
self.isalive() # Update exit status from ptyproc
self.child_fd = -1
diff --git a/pexpect/spawnbase.py b/pexpect/spawnbase.py
index cb64582..11e40f5 100644
--- a/pexpect/spawnbase.py
+++ b/pexpect/spawnbase.py
@@ -223,7 +223,7 @@ class SpawnBase(object):
self._pattern_type_err(p)
return compiled_pattern_list
- def expect(self, pattern, timeout=-1, searchwindowsize=-1, async=False):
+ def expect(self, pattern, timeout=-1, searchwindowsize=-1, async_=False, **kw):
'''This seeks through the stream until a pattern is matched. The
pattern is overloaded and may take several types. The pattern can be a
StringType, EOF, a compiled re, or a list of any of those types.
@@ -307,7 +307,7 @@ class SpawnBase(object):
If you are trying to optimize for speed then see expect_list().
On Python 3.4, or Python 3.3 with asyncio installed, passing
- ``async=True`` will make this return an :mod:`asyncio` coroutine,
+ ``async_=True`` will make this return an :mod:`asyncio` coroutine,
which you can yield from to get the same result that this method would
normally give directly. So, inside a coroutine, you can replace this code::
@@ -315,15 +315,19 @@ class SpawnBase(object):
With this non-blocking form::
- index = yield from p.expect(patterns, async=True)
+ index = yield from p.expect(patterns, async_=True)
'''
+ if 'async' in kw:
+ async_ = kw.pop('async')
+ if kw:
+ raise TypeError("Unknown keyword arguments: {}".format(kw))
compiled_pattern_list = self.compile_pattern_list(pattern)
return self.expect_list(compiled_pattern_list,
- timeout, searchwindowsize, async)
+ timeout, searchwindowsize, async_)
def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1,
- async=False):
+ async_=False, **kw):
'''This takes a list of compiled regular expressions and returns the
index into the pattern_list that matched the child output. The list may
also contain EOF or TIMEOUT(which are not compiled regular
@@ -333,21 +337,25 @@ class SpawnBase(object):
the expect() method. This is called by expect().
- Like :meth:`expect`, passing ``async=True`` will make this return an
+ Like :meth:`expect`, passing ``async_=True`` will make this return an
asyncio coroutine.
'''
if timeout == -1:
timeout = self.timeout
+ if 'async' in kw:
+ async_ = kw.pop('async')
+ if kw:
+ raise TypeError("Unknown keyword arguments: {}".format(kw))
exp = Expecter(self, searcher_re(pattern_list), searchwindowsize)
- if async:
+ if async_:
from .async import expect_async
return expect_async(exp, timeout)
else:
return exp.expect_loop(timeout)
def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1,
- async=False):
+ async_=False, **kw):
'''This is similar to expect(), but uses plain string matching instead
of compiled regular expressions in 'pattern_list'. The 'pattern_list'
@@ -361,11 +369,15 @@ class SpawnBase(object):
This method is also useful when you don't want to have to worry about
escaping regular expression characters that you want to match.
- Like :meth:`expect`, passing ``async=True`` will make this return an
+ Like :meth:`expect`, passing ``async_=True`` will make this return an
asyncio coroutine.
'''
if timeout == -1:
timeout = self.timeout
+ if 'async' in kw:
+ async_ = kw.pop('async')
+ if kw:
+ raise TypeError("Unknown keyword arguments: {}".format(kw))
if (isinstance(pattern_list, self.allowed_string_types) or
pattern_list in (TIMEOUT, EOF)):
@@ -385,7 +397,7 @@ class SpawnBase(object):
pattern_list = [prepare_pattern(p) for p in pattern_list]
exp = Expecter(self, searcher_string(pattern_list), searchwindowsize)
- if async:
+ if async_:
from .async import expect_async
return expect_async(exp, timeout)
else:
diff --git a/pexpect/utils.py b/pexpect/utils.py
index ae0fe9d..bafc280 100644
--- a/pexpect/utils.py
+++ b/pexpect/utils.py
@@ -11,6 +11,11 @@ except NameError:
# Alias Python2 exception to Python3
InterruptedError = select.error
+if sys.version_info[0] >= 3:
+ string_types = (str,)
+else:
+ string_types = (unicode, str)
+
def is_executable_file(path):
"""Checks that path is an executable regular file, or a symlink towards one.
diff --git a/tests/test_async.py b/tests/test_async.py
index 1a15524..1cc3236 100644
--- a/tests/test_async.py
+++ b/tests/test_async.py
@@ -18,53 +18,53 @@ class AsyncTests(PexpectTestCase):
def test_simple_expect(self):
p = pexpect.spawn('cat')
p.sendline('Hello asyncio')
- coro = p.expect(['Hello', pexpect.EOF] , async=True)
+ coro = p.expect(['Hello', pexpect.EOF] , async_=True)
assert run(coro) == 0
print('Done')
def test_timeout(self):
p = pexpect.spawn('cat')
- coro = p.expect('foo', timeout=1, async=True)
+ coro = p.expect('foo', timeout=1, async_=True)
with self.assertRaises(pexpect.TIMEOUT):
run(coro)
p = pexpect.spawn('cat')
- coro = p.expect(['foo', pexpect.TIMEOUT], timeout=1, async=True)
+ coro = p.expect(['foo', pexpect.TIMEOUT], timeout=1, async_=True)
assert run(coro) == 1
def test_eof(self):
p = pexpect.spawn('cat')
p.sendline('Hi')
- coro = p.expect(pexpect.EOF, async=True)
+ coro = p.expect(pexpect.EOF, async_=True)
p.sendeof()
assert run(coro) == 0
p = pexpect.spawn('cat')
p.sendeof()
- coro = p.expect('Blah', async=True)
+ coro = p.expect('Blah', async_=True)
with self.assertRaises(pexpect.EOF):
run(coro)
def test_expect_exact(self):
p = pexpect.spawn('%s list100.py' % sys.executable)
- assert run(p.expect_exact(b'5', async=True)) == 0
- assert run(p.expect_exact(['wpeok', b'11'], async=True)) == 1
- assert run(p.expect_exact([b'foo', pexpect.EOF], async=True)) == 1
+ assert run(p.expect_exact(b'5', async_=True)) == 0
+ assert run(p.expect_exact(['wpeok', b'11'], async_=True)) == 1
+ assert run(p.expect_exact([b'foo', pexpect.EOF], async_=True)) == 1
def test_async_utf8(self):
p = pexpect.spawn('%s list100.py' % sys.executable, encoding='utf8')
- assert run(p.expect_exact(u'5', async=True)) == 0
- assert run(p.expect_exact([u'wpeok', u'11'], async=True)) == 1
- assert run(p.expect_exact([u'foo', pexpect.EOF], async=True)) == 1
+ assert run(p.expect_exact(u'5', async_=True)) == 0
+ assert run(p.expect_exact([u'wpeok', u'11'], async_=True)) == 1
+ assert run(p.expect_exact([u'foo', pexpect.EOF], async_=True)) == 1
def test_async_and_gc(self):
p = pexpect.spawn('%s sleep_for.py 1' % sys.executable, encoding='utf8')
- assert run(p.expect_exact(u'READY', async=True)) == 0
+ assert run(p.expect_exact(u'READY', async_=True)) == 0
gc.collect()
- assert run(p.expect_exact(u'END', async=True)) == 0
+ assert run(p.expect_exact(u'END', async_=True)) == 0
def test_async_and_sync(self):
p = pexpect.spawn('echo 1234', encoding='utf8', maxread=1)
- assert run(p.expect_exact(u'1', async=True)) == 0
+ assert run(p.expect_exact(u'1', async_=True)) == 0
assert p.expect_exact(u'2') == 0
- assert run(p.expect_exact(u'3', async=True)) == 0
+ assert run(p.expect_exact(u'3', async_=True)) == 0