summaryrefslogtreecommitdiff
path: root/pexpect
diff options
context:
space:
mode:
authorSteven Silvester <steven.silvester@ieee.org>2014-11-23 17:51:21 -0800
committerThomas Kluyver <takowl@gmail.com>2015-09-12 11:49:09 +0100
commit157d2f4d9418aacd95f6c426279b52de318f7666 (patch)
treebfb6e05c315272eaf322899fb49b611ecd152284 /pexpect
parenteee85ecfeda167dd07e3abeaffcf8c51a6b0d5a8 (diff)
downloadpexpect-git-157d2f4d9418aacd95f6c426279b52de318f7666.tar.gz
Start implementing a Pexpect spawn class based on Popen
Initial implementation copied from https://gist.github.com/blink1073/9a0ea82efc84cb9216d0
Diffstat (limited to 'pexpect')
-rw-r--r--pexpect/popen_spawn.py83
1 files changed, 83 insertions, 0 deletions
diff --git a/pexpect/popen_spawn.py b/pexpect/popen_spawn.py
new file mode 100644
index 0000000..b3b02bd
--- /dev/null
+++ b/pexpect/popen_spawn.py
@@ -0,0 +1,83 @@
+"""Spawn interface using subprocess.Popen
+"""
+import os
+import threading
+import subprocess
+import sys
+
+try:
+ from queue import Queue # Python 3
+except ImportError:
+ from Queue import Queue # Python 2
+
+from .spawnbase import SpawnBase
+
+class PopenSpawn(SpawnBase):
+ def __init__(self, cmd, timeout=30, maxread=2000, searchwindowsize=None,
+ logfile=None, **kwargs):
+ super(PopenSpawn, self).__init__(timeout=timeout, maxread=maxread,
+ searchwindowsize=searchwindowsize, logfile=logfile)
+
+ kwargs.update(dict(bufsize=0, stdin=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ stdout=subprocess.PIPE))
+
+ if sys.platform == 'win32':
+ startupinfo = subprocess.STARTUPINFO()
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+ kwargs['startupinfo'] = startupinfo
+ kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
+
+ self.proc = subprocess.Popen(cmd, **kwargs)
+ self._buf = ''
+
+ self._read_queue = Queue()
+ self._read_thread = threading.Thread(target=self._read_incoming)
+ self._read_thread.setDaemon(True)
+ self._read_thread.start()
+
+ def read_nonblocking(self, n):
+ orig = len(self._buf)
+ while 1:
+ try:
+ self._buf += self._read_queue.get_nowait()
+ except Queue.Empty:
+ return
+ else:
+ if len(self._buf) - orig >= n:
+ return
+
+ def _read_incoming(self):
+ """Run in a thread to move output from a pipe to a queue."""
+ while 1:
+ buf = os.read(self.proc.stdout.fileno(), 1024)
+ self._read_queue.put(buf)
+
+ def readline(self):
+ while not '\n' in self._buf:
+ self.read_nonblocking(1024)
+ ind = self._buf.index('\n')
+ ret, self._buf = self._buf[:ind], self._buf[ind:]
+ return ret
+
+ def write(self, s):
+ '''This is similar to send() except that there is no return value.
+ '''
+ self.send(s)
+
+ def writelines(self, sequence):
+ '''This calls write() for each element in the sequence.
+
+ The sequence can be any iterable object producing strings, typically a
+ list of strings. This does not add line separators. There is no return
+ value.
+ '''
+ for s in sequence:
+ self.send(s)
+
+ def send(self, s):
+ self._log(s, 'send')
+ return self.proc.stdin.write(s)
+
+ def sendline(self, line):
+ return self.send(line + '\n')