summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornoah <noah@656d521f-e311-0410-88e0-e7920216d269>2007-12-16 21:04:51 +0000
committernoah <noah@656d521f-e311-0410-88e0-e7920216d269>2007-12-16 21:04:51 +0000
commitcde80d59484b8d26d74492546498d2b8b93819b5 (patch)
treef051b1db7f6d55a95c39a2810c9fc5bcbe8e4a2a
parent3c082c3fb0047e5ce17a6c6b1a208cd857bf6a35 (diff)
downloadpexpect-cde80d59484b8d26d74492546498d2b8b93819b5.tar.gz
Second patch by Jorgen Grahn.
git-svn-id: http://pexpect.svn.sourceforge.net/svnroot/pexpect/trunk@494 656d521f-e311-0410-88e0-e7920216d269
-rw-r--r--pexpect/pexpect.py22
-rwxr-xr-xpexpect/tests/test_expect.py60
2 files changed, 76 insertions, 6 deletions
diff --git a/pexpect/pexpect.py b/pexpect/pexpect.py
index 5abce7d..3298810 100644
--- a/pexpect/pexpect.py
+++ b/pexpect/pexpect.py
@@ -1187,6 +1187,22 @@ class spawn (object):
list. That will cause expect to match an EOF or TIMEOUT condition
instead of raising an exception.
+ If you pass a list of patterns and more than one matches, the first match
+ in the stream is chosen. If more than one pattern matches at that point,
+ the leftmost in the pattern list is chosen. For example::
+
+ # the input is 'foobar'
+ index = p.expect (['bar', 'foo', 'foobar'])
+ # returns 1 ('foo') even though 'foobar' is a "better" match
+
+ Please note, however, that buffering can affect this behavior, since
+ input arrives in unpredictable chunks. For example::
+
+ # the input is 'foobar'
+ index = p.expect (['foobar', 'foo'])
+ # returns 0 ('foobar') if all input is available at once,
+ # but returs 1 ('foo') if parts of the final 'bar' arrive late
+
After a match is found the instance attributes 'before', 'after' and
'match' will be set. You can see all the data read before the match in
'before'. You can see the data that was matched in 'after'. The
@@ -1588,8 +1604,7 @@ class searcher_string (object):
# better obey searchwindowsize
offset = -searchwindowsize
n = buffer.find(s, offset)
- if n >= 0 and n <= first_match:
- # note that the last, not the longest, match rules
+ if n >= 0 and n < first_match:
first_match = n
best_index, best_match = index, s
if first_match == absurd_match:
@@ -1669,8 +1684,7 @@ class searcher_re (object):
if match is None:
continue
n = match.start()
- if n <= first_match:
- # note that the last, not the longest, match rules
+ if n < first_match:
first_match = n
the_match = match
best_index = index
diff --git a/pexpect/tests/test_expect.py b/pexpect/tests/test_expect.py
index 7ded07b..3afef87 100755
--- a/pexpect/tests/test_expect.py
+++ b/pexpect/tests/test_expect.py
@@ -230,8 +230,6 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase):
else:
self.fail ('Expected an EOF exception.')
-class AdditionalExpectTestCase (PexpectTestCase.PexpectTestCase):
-
def _before_after(self, p):
p.timeout = 5
@@ -307,6 +305,64 @@ class AdditionalExpectTestCase (PexpectTestCase.PexpectTestCase):
p.expect = p.expect_exact
self._ordering(p)
+ def _greed(self, p):
+ p.timeout = 5
+ p.expect('>>> ')
+ p.sendline('import time')
+ p.expect('>>> ')
+ # the newline and sleep will (I hope) guarantee that
+ # pexpect is fed two distinct batches of data,
+ # "foo\r\n" + "bar\r\n".
+ foo_then_bar = 'print "f"+"o"+"o" ; time.sleep(3); print "b"+"a"+"r"'
+
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['foo\r\nbar']), 0)
+ p.expect('>>> ')
+
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['\r\nbar']), 0)
+ p.expect('>>> ')
+
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['foo\r\nbar', 'foo', 'bar']), 1)
+ p.expect('>>> ')
+
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['foo', 'foo\r\nbar', 'foo', 'bar']), 0)
+ p.expect('>>> ')
+
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['bar', 'foo\r\nbar']), 1)
+ p.expect('>>> ')
+
+ # If the expect works as if we rematch for every new character,
+ # 'o\r\nb' should win over 'oo\r\nba'. The latter is longer and
+ # matches earlier in the input, but isn't satisfied until the 'a'
+ # arrives.
+ # However, pexpect doesn't do that (version 2.1 didn't).
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['oo\r\nba', 'o\r\nb']), 0)
+ p.expect('>>> ')
+
+ # distinct patterns, but both suddenly match when the 'r' arrives.
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['foo\r\nbar', 'ar']), 0)
+ p.expect('>>> ')
+
+ p.sendline(foo_then_bar)
+ self.assertEqual(p.expect(['ar', 'foo\r\nbar']), 1)
+ p.expect('>>> ')
+
+ def test_greed(self):
+ p = pexpect.spawn(self.PYTHONBIN)
+ self._greed(p)
+
+ def test_greed_exact(self):
+ p = pexpect.spawn(self.PYTHONBIN)
+ # mangle the spawn so we test expect_exact() instead
+ p.expect = p.expect_exact
+ self._greed(p)
+
if __name__ == '__main__':
unittest.main()