summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornoah <noah@656d521f-e311-0410-88e0-e7920216d269>2002-12-24 08:26:54 +0000
committernoah <noah@656d521f-e311-0410-88e0-e7920216d269>2002-12-24 08:26:54 +0000
commit8a37121d9607c5f8297fc7fdb9962bac0fd95999 (patch)
tree859ffd7d47d2b1520fba0b3cb46ede58505e0fdc
parent15f84a9ad93a378685b221d139c7604165e4cbcd (diff)
downloadpexpect-8a37121d9607c5f8297fc7fdb9962bac0fd95999.tar.gz
Several improvements have been made. Patterns are not compiled with DOTALL
by default. The compile_pattern_list() method now accepts compiled re instances in addition to EOF and strings. If for some reason you needed to get around the DOTALL default you could compile a pattern and use that in your pattern list instead of letting pexpect compile it for you. I added a test for the new DOTALL default. It also tests that precompiled patterns can bypass this. git-svn-id: http://pexpect.svn.sourceforge.net/svnroot/pexpect/trunk@125 656d521f-e311-0410-88e0-e7920216d269
-rw-r--r--pexpect/pexpect.py63
-rwxr-xr-xpexpect/tests/test_dotall.py24
2 files changed, 58 insertions, 29 deletions
diff --git a/pexpect/pexpect.py b/pexpect/pexpect.py
index 31cea8d..e259c00 100644
--- a/pexpect/pexpect.py
+++ b/pexpect/pexpect.py
@@ -202,43 +202,48 @@ class spawn:
"""
self.log_file = fileobject
- def compile_pattern_list(self, pattern):
+ def compile_pattern_list(self, patterns):
"""This compiles a pattern-string or a list of pattern-strings.
+ Argument must be one of StringType, EOF, SRE_Pattern, or a list of those type.
This is used by expect() when calling expect_list().
Thus expect() is nothing more than::
cpl = self.compile_pattern_list(pl)
return self.expect_list(clp, timeout)
If you are using expect() within a loop it may be more
- efficient to compile the patterns first and call expect_list():
+ efficient to compile the patterns first and then call expect_list().
+ This avoid calls in a loop to compile_pattern_list():
cpl = self.compile_pattern_list(my_pattern)
while some_condition:
...
i = self.expect_list(clp, timeout)
...
"""
- if pattern is EOF:
- compiled_pattern_list = [EOF]
- elif type(pattern) is StringType:
- compiled_pattern_list = [re.compile(pattern)]
- elif type(pattern) is ListType:
- compiled_pattern_list = []
- for x in pattern:
- if x is EOF:
- compiled_pattern_list.append(EOF)
- else:
- compiled_pattern_list.append( re.compile(x) )
- else:
- raise TypeError, 'Pattern argument must be a string or a list of strings.'
+ if type(patterns) is not ListType:
+ patterns = [patterns]
+
+ compiled_pattern_list = []
+ for p in patterns:
+ if type(p) is StringType:
+ compiled_pattern_list.append(re.compile(p, re.DOTALL))
+ elif p is EOF:
+ compiled_pattern_list.append(EOF)
+ elif type(p) is type(re.compile('')):
+ compiled_pattern_list.append(p)
+ else:
+ raise TypeError, 'Argument must be one of StringType, EOF, SRE_Pattern, or a list of those type. %s' % str(type(p))
return compiled_pattern_list
def expect(self, pattern, timeout = None):
- """This seeks through the stream looking for the given
- pattern. The 'pattern' can be a string or a list of strings.
- The strings are regular expressions (see module 're'). This
- returns the index into the pattern list or raises an exception
- on error.
+ """This seeks through the stream until an expected pattern is matched.
+ The pattern is overloaded and may take several types including a list.
+ The pattern can be a StringType, EOF, a compiled re, or
+ a list of those types. Strings will be compiled to re types.
+ This returns the index into the pattern list. If the pattern was
+ not a list this returns index 0 on a successful match.
+ This may raise exceptions for EOF or TIMEOUT.
+ To avoid the EOF exception add EOF to the pattern list.
After a match is found the instance attributes
'before', 'after' and 'match' will be set.
@@ -255,20 +260,20 @@ class spawn:
This allows you to write code like this:
index = p.expect (['good', 'bad', pexpect.EOF])
if index == 0:
- do_something()
+ do_something()
elif index == 1:
- do_something_else()
+ do_something_else()
elif index == 2:
- do_some_other_thing()
+ do_some_other_thing()
instead of code like this:
try:
- index = p.expect (['good', 'bad'])
- if index == 0:
- do_something()
- elif index == 1:
- do_something_else()
+ index = p.expect (['good', 'bad'])
+ if index == 0:
+ do_something()
+ elif index == 1:
+ do_something_else()
except EOF:
- do_some_other_thing()
+ do_some_other_thing()
These two forms are equivalent. It all depends on what you want.
You can also just expect the EOF if you are waiting for all output
of a child to finish. For example:
diff --git a/pexpect/tests/test_dotall.py b/pexpect/tests/test_dotall.py
new file mode 100755
index 0000000..88fd805
--- /dev/null
+++ b/pexpect/tests/test_dotall.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+import pexpect
+import unittest
+import os
+import re
+
+testdata = 'BEGIN\nHello world\nEND'
+class TestCaseDotall(unittest.TestCase):
+
+ def test_dotall (self):
+ p = pexpect.spawn('echo "%s"' % testdata)
+ i = p.expect (['BEGIN(.*)END', pexpect.EOF])
+ assert i==0, 'DOTALL does not seem to be working.'
+ def test_precompiled (self):
+ p = pexpect.spawn('echo "%s"' % testdata)
+ pat = re.compile('BEGIN(.*)END') # This overrides the default DOTALL.
+ i = p.expect ([pat, pexpect.EOF])
+ assert i==1, 'Precompiled pattern to override DOTALL does not seem to be working.'
+
+if __name__ == '__main__':
+ unittest.main()
+
+suite = unittest.makeSuite(TestCaseDotall,'test')
+