summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kluyver <takowl@gmail.com>2015-09-29 18:37:55 +0100
committerThomas Kluyver <takowl@gmail.com>2015-09-29 18:37:55 +0100
commit84f3e245b27f96c559a984039099c74569f8ae64 (patch)
tree88d2b3fefabf4d1c419b265c2bda02894534c6f1
parent578709d0a5c99d6e58e4d9a8806cbf491db4a7f9 (diff)
downloadpexpect-git-84f3e245b27f96c559a984039099c74569f8ae64.tar.gz
Ensured buffered data is processed before raising EOF
-rw-r--r--pexpect/popen_spawn.py33
1 files changed, 19 insertions, 14 deletions
diff --git a/pexpect/popen_spawn.py b/pexpect/popen_spawn.py
index f6d5d5f..ab51499 100644
--- a/pexpect/popen_spawn.py
+++ b/pexpect/popen_spawn.py
@@ -44,19 +44,26 @@ class PopenSpawn(SpawnBase):
self.proc = subprocess.Popen(cmd, **kwargs)
self.closed = False
- self._buf = ''
+ self._buf = self.string_type()
self._read_queue = Queue()
self._read_thread = threading.Thread(target=self._read_incoming)
self._read_thread.setDaemon(True)
self._read_thread.start()
+ _read_reached_eof = False
+
def read_nonblocking(self, size, timeout):
- if self.closed:
- raise ValueError('I/O operation on closed file.')
- elif self.flag_eof:
- self.closed = True
- raise EOF('End Of File (EOF).')
+ buf = self._buf
+ if self._read_reached_eof:
+ # We have already finished reading. Use up any buffered data,
+ # then raise EOF
+ if buf:
+ self._buf = buf[size:]
+ return buf[:size]
+ else:
+ self.flag_eof = True
+ raise EOF('End Of File (EOF).')
if timeout == -1:
timeout = self.timeout
@@ -64,7 +71,6 @@ class PopenSpawn(SpawnBase):
timeout = 1e6
t0 = time.time()
- buf = self.string_type()
while (time.time() - t0) < timeout and size and len(buf) < size:
try:
incoming = self._read_queue.get_nowait()
@@ -72,17 +78,15 @@ class PopenSpawn(SpawnBase):
break
else:
if incoming is None:
- self.flag_eof = True
- raise EOF('End of File')
+ self._read_reached_eof = True
+ break
buf += self._decoder.decode(incoming, final=False)
- if len(buf) > size:
- self.buffer = buf[size:]
- buf = buf[:size]
+ r, self._buf = buf[:size], buf[size:]
- self._log(buf, 'read')
- return buf
+ self._log(r, 'read')
+ return r
def _read_incoming(self):
"""Run in a thread to move output from a pipe to a queue."""
@@ -95,6 +99,7 @@ class PopenSpawn(SpawnBase):
self._log(e, 'read')
if not buf:
+ # This indicates we have reached EOF
self._read_queue.put(None)
return