3030
3131To do:
3232- option negotiation
33+ - timeout should be intrinsic to the connection object instead of an
34+ option on one of the read calls only
3335
3436"""
3537
3638
3739# Imported modules
40+ import sys
3841import socket
3942import select
4043import string
@@ -371,7 +374,6 @@ def sock_avail(self):
371374
372375 def interact (self ):
373376 """Interaction function, emulates a very dumb telnet client."""
374- import sys , select
375377 while 1 :
376378 rfd , wfd , xfd = select .select ([self , sys .stdin ], [], [])
377379 if sys .stdin in rfd :
@@ -388,6 +390,55 @@ def interact(self):
388390 sys .stdout .flush ()
389391 self .close ()
390392
393+ def expect (self , list , timeout = None ):
394+ """Read until one from a list of a regular expressions matches.
395+
396+ The first argument is a list of regular expressions, either
397+ compiled (re.RegexObject instances) or uncompiled (strings).
398+ The optional second argument is a timeout, in seconds; default
399+ is no timeout.
400+
401+ Return a tuple of three items: the index in the list of the
402+ first regular expression that matches; the match object
403+ returned; and the text read up till and including the match.
404+
405+ If EOF is read and no text was read, raise EOFError.
406+ Otherwise, when nothing matches, return (-1, None, text) where
407+ text is the text received so far (may be the empty string if a
408+ timeout happened).
409+
410+ If a regular expression ends with a greedy match (e.g. '.*')
411+ or if more than one expression can match the same input, the
412+ results are undeterministic, and may depend on the I/O timing.
413+
414+ """
415+ re = None
416+ list = list [:]
417+ indices = range (len (list ))
418+ for i in indices :
419+ if not hasattr (list [i ], "search" ):
420+ if not re : import re
421+ list [i ] = re .compile (list [i ])
422+ while 1 :
423+ self .process_rawq ()
424+ for i in indices :
425+ m = list [i ].search (self .cookedq )
426+ if m :
427+ e = m .end ()
428+ text = self .cookedq [:e ]
429+ self .cookedq = self .cookedq [e :]
430+ return (i , m , text )
431+ if self .eof :
432+ break
433+ if timeout is not None :
434+ r , w , x = select .select ([self .fileno ()], [], [], timeout )
435+ if not r :
436+ break
437+ self .fill_rawq ()
438+ text = self .read_very_lazy ()
439+ if not text and self .eof :
440+ raise EOFError
441+ return (- 1 , None , text )
391442
392443
393444def test ():
@@ -398,7 +449,6 @@ def test():
398449 Default host is localhost; default port is 23.
399450
400451 """
401- import sys
402452 debuglevel = 0
403453 while sys .argv [1 :] and sys .argv [1 ] == '-d' :
404454 debuglevel = debuglevel + 1
0 commit comments