summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornoah <noah@656d521f-e311-0410-88e0-e7920216d269>2002-09-19 23:17:41 +0000
committernoah <noah@656d521f-e311-0410-88e0-e7920216d269>2002-09-19 23:17:41 +0000
commit36fa845b37a74b0a43aa24204196085184ee140d (patch)
tree611bc98ed0b4f22b8729ce26e454f6862cb081ae
parent851c8d708240c5dded8a6c7c13ddb11a47d75a1c (diff)
downloadpexpect-36fa845b37a74b0a43aa24204196085184ee140d.tar.gz
Big interface change. 'matched' is now called 'after' and 'match' is
set to the regular expression match object returned by the re match. git-svn-id: http://pexpect.svn.sourceforge.net/svnroot/pexpect/trunk@59 656d521f-e311-0410-88e0-e7920216d269
-rw-r--r--pexpect/alltests.py25
-rwxr-xr-xpexpect/examples/chess.py22
-rwxr-xr-xpexpect/examples/chess2.py4
-rwxr-xr-xpexpect/examples/chess3.py136
-rwxr-xr-xpexpect/examples/ftp.py4
-rwxr-xr-xpexpect/examples/python.py2
-rw-r--r--pexpect/pexpect.py122
-rw-r--r--pexpect/tests/test_ansi.py2
-rwxr-xr-xpexpect/tests/test_expect.py14
-rwxr-xr-xpexpect/tests/test_run_out_of_pty.py4
10 files changed, 258 insertions, 77 deletions
diff --git a/pexpect/alltests.py b/pexpect/alltests.py
new file mode 100644
index 0000000..6bf7540
--- /dev/null
+++ b/pexpect/alltests.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+import unittest
+import sys
+sys.path.append('tests')
+
+modules_to_test = (
+'test_expect',
+'test_ansi',
+'test_command_list_split',
+'test_destructor',
+'test_missing_command',
+'test_run_out_of_pty',
+'test_screen'
+)
+
+def suite():
+ alltests = unittest.TestSuite()
+ for module in map(__import__, modules_to_test):
+ alltests.addTest(unittest.findTestCases(module))
+ return alltests
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
+
diff --git a/pexpect/examples/chess.py b/pexpect/examples/chess.py
index 0820024..c760433 100755
--- a/pexpect/examples/chess.py
+++ b/pexpect/examples/chess.py
@@ -16,10 +16,10 @@ class Chess:
self.term = ANSI.ANSI ()
self.child.expect ('Chess')
- if self.child.matched != 'Chess':
+ if self.child.after != 'Chess':
raise IOError, 'incompatible chess program'
self.term.process_list (self.before)
- self.term.process_list (self.matched)
+ self.term.process_list (self.after)
self.last_computer_move = ''
def read_until_cursor (self, r,c)
while 1:
@@ -32,7 +32,7 @@ class Chess:
self.child.expect ('Your move is')
self.child.sendline (move)
self.term.process_list (self.before)
- self.term.process_list (self.matched)
+ self.term.process_list (self.after)
return move
def do_move (self, move):
@@ -45,8 +45,8 @@ class Chess:
def get_first_computer_move (self):
self.child.expect ('My move is')
self.child.expect (REGEX_MOVE)
-# print '', self.child.matched
- return self.child.matched
+# print '', self.child.after
+ return self.child.after
def get_computer_move (self):
print 'Here'
@@ -54,14 +54,14 @@ class Chess:
print i
if i == 0:
self.child.expect (REGEX_MOVE)
- if len(self.child.matched) < 4:
- self.child.matched = self.child.matched + self.last_computer_move[3]
+ if len(self.child.after) < 4:
+ self.child.after = self.child.after + self.last_computer_move[3]
if i == 1:
self.child.expect (REGEX_MOVE_PART)
- self.child.matched = self.last_computer_move[0] + self.child.matched
- print '', self.child.matched
- self.last_computer_move = self.child.matched
- return self.child.matched
+ self.child.after = self.last_computer_move[0] + self.child.after
+ print '', self.child.after
+ self.last_computer_move = self.child.after
+ return self.child.after
def switch (self):
self.child.sendline ('switch')
diff --git a/pexpect/examples/chess2.py b/pexpect/examples/chess2.py
index 5654f31..e4378b3 100755
--- a/pexpect/examples/chess2.py
+++ b/pexpect/examples/chess2.py
@@ -14,10 +14,10 @@ class Chess:
self.term = ANSI.ANSI ()
#self.child.expect ('Chess')
- #if self.child.matched != 'Chess':
+ #if self.child.after != 'Chess':
# raise IOError, 'incompatible chess program'
#self.term.process_list (self.child.before)
- #self.term.process_list (self.child.matched)
+ #self.term.process_list (self.child.after)
self.last_computer_move = ''
diff --git a/pexpect/examples/chess3.py b/pexpect/examples/chess3.py
new file mode 100755
index 0000000..286a8e3
--- /dev/null
+++ b/pexpect/examples/chess3.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+'''This demonstrates controlling a screen oriented application (curses).
+It starts two instances of gnuchess and then pits them against each other.
+'''
+import pexpect
+import string
+import ANSI
+
+REGEX_MOVE = '(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)'
+REGEX_MOVE_PART = '(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)'
+
+class Chess:
+
+ def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"):
+ self.child = pexpect.spawn (engine)
+ self.term = ANSI.ANSI ()
+
+# self.child.expect ('Chess')
+ # if self.child.after != 'Chess':
+ # raise IOError, 'incompatible chess program'
+ # self.term.process_list (self.before)
+ # self.term.process_list (self.after)
+ self.last_computer_move = ''
+ def read_until_cursor (self, r,c):
+ fout = open ('log','a')
+ while 1:
+ k = self.child.read(1, 10)
+ self.term.process (k)
+ fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c))
+ fout.flush()
+ if self.term.cur_r == r and self.term.cur_c == c:
+ fout.close()
+ return 1
+ sys.stdout.write (k)
+ sys.stdout.flush()
+
+ def do_scan (self):
+ fout = open ('log','a')
+ while 1:
+ c = self.child.read(1,10)
+ self.term.process (c)
+ fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c))
+ fout.flush()
+ sys.stdout.write (c)
+ sys.stdout.flush()
+
+ def do_move (self, move):
+ self.read_until_cursor (19,60)
+ self.child.sendline (move)
+ return move
+
+ def get_computer_move (self):
+ print 'Here'
+ i = self.child.expect (['\[17;59H', '\[17;58H'])
+ print i
+ if i == 0:
+ self.child.expect (REGEX_MOVE)
+ if len(self.child.after) < 4:
+ self.child.after = self.child.after + self.last_computer_move[3]
+ if i == 1:
+ self.child.expect (REGEX_MOVE_PART)
+ self.child.after = self.last_computer_move[0] + self.child.after
+ print '', self.child.after
+ self.last_computer_move = self.child.after
+ return self.child.after
+
+ def switch (self):
+ self.child.sendline ('switch')
+
+ def set_depth (self, depth):
+ self.child.sendline ('depth')
+ self.child.expect ('depth=')
+ self.child.sendline ('%d' % depth)
+
+ def quit(self):
+ self.child.sendline ('quit')
+import sys, os
+print 'Starting...'
+white = Chess()
+white.do_move('b2b4')
+white.read_until_cursor (19,60)
+c1 = white.term.get_abs(17,58)
+c2 = white.term.get_abs(17,59)
+c3 = white.term.get_abs(17,60)
+c4 = white.term.get_abs(17,61)
+fout = open ('log','a')
+fout.write ('Computer:%s%s%s%s\n' %(c1,c2,c3,c4))
+fout.close()
+white.do_move('c2c4')
+white.read_until_cursor (19,60)
+c1 = white.term.get_abs(17,58)
+c2 = white.term.get_abs(17,59)
+c3 = white.term.get_abs(17,60)
+c4 = white.term.get_abs(17,61)
+fout = open ('log','a')
+fout.write ('Computer:%s%s%s%s\n' %(c1,c2,c3,c4))
+fout.close()
+white.do_scan ()
+
+#white.do_move ('b8a6')
+#move_white = white.get_computer_move()
+#print 'move white:', move_white
+
+sys.exit(1)
+
+
+
+black = Chess()
+white = Chess()
+white.child.expect ('Your move is')
+white.switch()
+
+move_white = white.get_first_computer_move()
+print 'first move white:', move_white
+
+black.do_first_move (move_white)
+move_black = black.get_first_computer_move()
+print 'first move black:', move_black
+
+white.do_move (move_black)
+
+done = 0
+while not done:
+ move_white = white.get_computer_move()
+ print 'move white:', move_white
+
+ black.do_move (move_white)
+ move_black = black.get_computer_move()
+ print 'move black:', move_black
+
+ white.do_move (move_black)
+ print 'tail of loop'
+
+g.quit()
+
+
diff --git a/pexpect/examples/ftp.py b/pexpect/examples/ftp.py
index 42e159a..69909d5 100755
--- a/pexpect/examples/ftp.py
+++ b/pexpect/examples/ftp.py
@@ -10,7 +10,7 @@ child.sendline('anonymous')
child.expect('Password:')
child.sendline('noah@noah.org')
child.expect('ftp> ')
-child.sendline('cd /pub/OpenBSD/2.9/packages/i386')
+child.sendline('cd /pub/OpenBSD/3.1/packages/i386')
child.expect('ftp> ')
child.sendline('bin')
child.expect('ftp> ')
@@ -19,7 +19,7 @@ child.expect('ftp> ')
child.sendline('pwd')
child.expect('ftp> ')
print("Escape character is '^]'.\n")
-sys.stdout.write (child.matched)
+sys.stdout.write (child.after)
sys.stdout.flush()
child.interact() # Escape character defaults to ^]
diff --git a/pexpect/examples/python.py b/pexpect/examples/python.py
index 9ba0d61..82b507f 100755
--- a/pexpect/examples/python.py
+++ b/pexpect/examples/python.py
@@ -15,7 +15,7 @@ print f(c.before)
print 'Yes, it\'s python, but it\'s backwards.'
print
print 'Escape character is \'^]\'.'
-print c.matched,
+print c.after,
c.interact()
c.kill(1)
print 'isAlive:', c.isAlive()
diff --git a/pexpect/pexpect.py b/pexpect/pexpect.py
index 9b04afd..4297531 100644
--- a/pexpect/pexpect.py
+++ b/pexpect/pexpect.py
@@ -83,7 +83,8 @@ class spawn:
self.log_fd = -1
self.before = None
- self.matched = None
+ self.after = None
+ self.match = None
self.args = split_command_line(command)
self.command = self.args[0]
@@ -213,21 +214,46 @@ class spawn:
returns the index into the pattern list or raises an exception
on error.
- Afterwards the instance attributes 'before', 'matched' and
- 'match' will be set. You can read all the data read before the
- match in 'before'. You can read the data that was matched in
- 'matched', while 'match' is the corresponding
- 're.MatchObject'. If an error occured, both 'matched' and
- 'match' will be None.
-
- Special: A list entry may be EOF instead of a string. This
- will catch EOF exceptions and return the index of this entry
- instead. 'matched' and 'match' will be None anyhow.
+ 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 re.MatchObject used in the re match will be in 'match'.
+ If an error occured then 'before' will be set to all the
+ data read so far and 'after' and 'match' will be None.
+
+ Note: A list entry may be EOF instead of a string.
+ This will catch EOF exceptions and return the index
+ of the EOF entry instead of raising the EOF exception.
+ The attributes 'after' and 'match' will be None.
+ This allows you to write code like this:
+ index = p.expect (['good', 'bad', pexpect.EOF])
+ if index == 0:
+ do_something()
+ elif index == 1:
+ do_something_else()
+ elif index == 2:
+ 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()
+ except EOF:
+ 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:
+ p = pexpect.spawn('/bin/ls')
+ p.expect (pexpect.EOF)
+ print p.before
"""
compiled_pattern_list = self.compile_pattern_list(pattern)
return self.expect_list(compiled_pattern_list, timeout)
- def expect_exact (self, str_list, local_timeout = None):
+ def expect_exact (self, pattern_list, local_timeout = None):
"""This is similar to expect() except that it takes
list of regular strings instead of compiled regular expressions.
The idea is that this should be much faster. It could also be
@@ -236,65 +262,57 @@ class spawn:
You may also pass just a string without a list and the single
string will be converted to a list.
"""
- matched_pattern = None
- before_pattern = None
- index = 0
-
- if type(str_list)is StringType:
- str_list = [str_list]
+ ### This is dumb. It shares most of the code with expect_list.
+ ### The only different is the comparison method and that
+ ### self.match is always None after calling this.
+
+ if type(pattern_list) is StringType:
+ pattern_list = [pattern_list]
try:
- done = 0
incoming = ''
- while not done: # Keep reading until done.
+ while 1: # Keep reading until exception or return.
c = self.read(1, local_timeout)
incoming = incoming + c
# Sequence through the list of patterns and look for a match.
- for str_target in str_list:
+ index = -1
+ for str_target in pattern_list:
+ index = index + 1
match_index = incoming.find (str_target)
if match_index >= 0:
- matched_pattern = incoming[match_index:]
- before_pattern = incoming[:match_index]
- done = 1
- break
- else:
- index = index + 1
+ self.before = incoming [ : match_index]
+ self.after = incoming [match_index : ]
+ self.match = None
+ return index
+ except EOF, e:
+ if EOF in pattern_list:
+ self.before = incoming
+ self.after = EOF
+ return pattern_list.index(EOF)
+ else:
+ raise
except Exception, e:
- ### Here I should test if the client wants to pass exceptions, or
- ### to return some state flag. Exception versus return value.
- matched_pattern = None
- before_pattern = incoming
+ self.before = incoming
+ self.after = None
+ self.match = None
raise
-
- self.before = before_pattern
- self.matched = matched_pattern
- return index
-
+
+ assert 0 == 1, 'Should not get here.'
def expect_list(self, pattern_list, local_timeout = None):
"""This is called by expect(). This takes a list of compiled
- regular expressions. This returns the matched index into the
- pattern_list.
+ regular expressions. This returns the index into the pattern_list
+ that matched the child's output.
- Special: A list entry may be None instead of
- a compiled regular expression. This will catch EOF exceptions and
- return the index of this entry; otherwise, an exception is raised.
- After an EOF 'matched' and 'match' will be None.
"""
- # if partial=='': ### self.flag_eof:
- # flag_eof = 1 ### Should not need this if self.flag_eof is used.
- # index = None
- # matched_pattern = None
- # done = 1
- # break
if local_timeout is None:
local_timeout = self.timeout
try:
incoming = ''
- while 1: # Keep reading until except or return.
+ while 1: # Keep reading until exception or return.
c = self.read(1, local_timeout)
incoming = incoming + c
@@ -306,18 +324,20 @@ class spawn:
continue # The EOF pattern is not a regular expression.
match = cre.search(incoming)
if match is not None:
- self.match = incoming[match.start() : match.end()]
self.before = incoming[ : match.start()]
+ self.after = incoming[match.start() : ]
+ self.match = match
return index
except EOF, e:
if EOF in pattern_list:
self.before = incoming
- self.match = EOF
+ self.after = EOF
return pattern_list.index(EOF)
else:
raise
except Exception, e:
self.before = incoming
+ self.after = None
self.match = None
raise
diff --git a/pexpect/tests/test_ansi.py b/pexpect/tests/test_ansi.py
index e5bc18c..6026bee 100644
--- a/pexpect/tests/test_ansi.py
+++ b/pexpect/tests/test_ansi.py
@@ -69,7 +69,7 @@ class ansiTestCase (unittest.TestCase):
assert str(s) == write_target
def test_tetris (self):
s = ANSI.ANSI (24,80)
- tetris_text = open ('tetris.data').read()
+ tetris_text = open ('tests/tetris.data').read()
for c in tetris_text:
s.process (c)
assert str(s) == tetris_target
diff --git a/pexpect/tests/test_expect.py b/pexpect/tests/test_expect.py
index 63dad46..a657d72 100755
--- a/pexpect/tests/test_expect.py
+++ b/pexpect/tests/test_expect.py
@@ -7,14 +7,14 @@ import sys
class ExpectTestCase(unittest.TestCase):
#def runTest (self):
- def test_expect_exact (self):
+ def test_expect (self):
the_old_way = commands.getoutput('/bin/ls -l')
p = pexpect.spawn('/bin/ls -l')
+ the_new_way = ''
try:
- the_new_way = ''
while 1:
- p.expect_exact ('\n')
+ p.expect ('\n')
the_new_way = the_new_way + p.before
except:
the_new_way = the_new_way[:-1]
@@ -22,16 +22,16 @@ class ExpectTestCase(unittest.TestCase):
assert the_old_way == the_new_way
- def test_expect (self):
+ def test_expect_exact (self):
the_old_way = commands.getoutput('/bin/ls -l')
p = pexpect.spawn('/bin/ls -l')
- the_new_way = ''
try:
+ the_new_way = ''
while 1:
- p.expect ('\n')
+ p.expect_exact ('\n')
the_new_way = the_new_way + p.before
- except Exception, e:
+ except:
the_new_way = the_new_way[:-1]
the_new_way = the_new_way.replace('\r','\n')
diff --git a/pexpect/tests/test_run_out_of_pty.py b/pexpect/tests/test_run_out_of_pty.py
index 6ef67ef..082397b 100755
--- a/pexpect/tests/test_run_out_of_pty.py
+++ b/pexpect/tests/test_run_out_of_pty.py
@@ -16,8 +16,8 @@ class ExpectTestCase(unittest.TestCase):
plist.append (pexpect.spawn('/bin/ls -l'))
except pexpect.ExceptionPexpect, e:
return
- else:
- self.fail ('Expected ExceptionPexpect.')
+ except Exception, e:
+ self.fail ('Expected ExceptionPexpect. ' + str(e))
self.fail ('Could not run out of pty devices. This may be OK.')
if __name__ == '__main__':