Python pexon clears or clears a line

I'm trying to clear any characters in a string after recovering from an unknown state, as in some cases they contain hints and other keywords that I use in future calls to the wait method. I have tried several approaches with mixed results, as I continue to work in the expected behavior.

Apparently unexpected behavior (using pexpect V3.3 with Python 2.7.9):

  • After executing the following code, when I subsequently try to read from the buffer, sometimes I see erratic behavior when only part of the accumulated characters is cleared. This smells of chaos in my logic downstream. I assume this is due to the fact that the entire stream goes into sleep mode for 5 seconds, so when it wakes up, it does not have time to fetch the full incoming buffer before executing the read_nonblocking () command.

    time.sleep(5) flushedStuff += child.read_nonblocking(100000, timeout=0) 
  • When I try to use the .expect call to clear a string in a non-blocking way, I find that after a TIMEOUT exception, the incoming buffer is not cleared. Its contents can be found as expected in the child.before property, but it will also be analyzed during the next call to the .expect method. So it doesn’t wash the line at all! I also noticed that read_nonblocking () does not read from the local buffer, but reads directly from the line through the OS, so it does not see this.

     try: child.expect("ZzqQJjSh_Impossible_String", timeout = 5) except pexpect.TIMEOUT: pass flushedStuff = child.before 

So, now my current solution, to provide a reliable way to clear the string, is to extend the spawn class and add a method that does the following ... that accesses the undocumented property:

 class ExtendedSpawn(pexpect.spawn): def flushBuffer(delay) try: # Greedily read in all the incoming characters self.expect("ZzqQJjSh_Impossible_String", timeout = delay) except pexpect.TIMEOUT: pass # Clear local input buffer inside the spawn Class self.buffer = self.string_type() return self.before 

The above method can also be used for a non-blocking sleep command.

This seems to be too complicated an approach to something that should be simple, not to mention the fact that I spent a couple of days on it. Is there a better way to do this?

Thanks!

+6
source share
2 answers

The easiest way to clear a pexpect buffer so that it reads continuously until data is available

 flushedStuff = '' while not child.expect(r'.+', timeout=5): flushedStuff += child.match.group(0) 
0
source

To see this problem, you can run the following script. (The shell script will display numbers from 1 to 10 and sleep 1 second after each number. Pexpect will wait 2 seconds for a timeout and print the numbers seen.):

 #!/usr/bin/env python import pexpect child = pexpect.spawn('/bin/sh -c "i=0; while [ $i -lt 10 ]:; do echo $((i=i+1)); sleep 1; done"') while True: i=child.expect ([pexpect.TIMEOUT, pexpect.EOF], timeout=2) if i==0: print "before=%s" % child.before else: break 

The result will look like this (we also get numbers that have already been read earlier):

 before='1\r\n2\r\n' before='1\r\n2\r\n3\r\n4\r\n' before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n' before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n' before='1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n' 

To solve the problem, two lines can be added to the script:

 #!/usr/bin/env python import pexpect child = pexpect.spawn('/bin/sh -c "i=0; while [ $i -lt 10 ]:; do echo $((i=i+1)); sleep 1; done"') while True: i=child.expect ([pexpect.TIMEOUT, pexpect.EOF], timeout=2) if i==0: print "before=%s" % repr(child.before) if child.before: child.expect (r'.+') else: break 

And the result will be as expected:

 before='1\r\n2\r\n' before='3\r\n4\r\n' before='5\r\n6\r\n' before='7\r\n8\r\n' before='9\r\n10\r\n' 
0
source

Source: https://habr.com/ru/post/985006/


All Articles