Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Unified Diff: third_party/pexpect/pexpect/async.py

Issue 1398903002: Add third_party/pexpect (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@end-to-end-test
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/pexpect/pexpect/__init__.py ('k') | third_party/pexpect/pexpect/bashrc.sh » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pexpect/pexpect/async.py
diff --git a/third_party/pexpect/pexpect/async.py b/third_party/pexpect/pexpect/async.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad759947232c51b492b57d99fa974aeeb60b82c9
--- /dev/null
+++ b/third_party/pexpect/pexpect/async.py
@@ -0,0 +1,72 @@
+import asyncio
+import errno
+
+from pexpect import EOF
+
+@asyncio.coroutine
+def expect_async(expecter, timeout=None):
+ # First process data that was previously read - if it maches, we don't need
+ # async stuff.
+ previously_read = expecter.spawn.buffer
+ expecter.spawn.buffer = expecter.spawn.string_type()
+ idx = expecter.new_data(previously_read)
+ if idx is not None:
+ return idx
+
+ transport, pw = yield from asyncio.get_event_loop()\
+ .connect_read_pipe(lambda: PatternWaiter(expecter), expecter.spawn)
+
+ try:
+ return (yield from asyncio.wait_for(pw.fut, timeout))
+ except asyncio.TimeoutError as e:
+ transport.pause_reading()
+ return expecter.timeout(e)
+
+class PatternWaiter(asyncio.Protocol):
+ def __init__(self, expecter):
+ self.expecter = expecter
+ self.fut = asyncio.Future()
+
+ def found(self, result):
+ if not self.fut.done():
+ self.fut.set_result(result)
+
+ def error(self, exc):
+ if not self.fut.done():
+ self.fut.set_exception(exc)
+
+ def data_received(self, data):
+ spawn = self.expecter.spawn
+ s = spawn._decoder.decode(data)
+ spawn._log(s, 'read')
+
+ if self.fut.done():
+ spawn.buffer += data
+ return
+
+ try:
+ index = self.expecter.new_data(data)
+ if index is not None:
+ # Found a match
+ self.found(index)
+ except Exception as e:
+ self.expecter.errored()
+ self.error(e)
+
+ def eof_received(self):
+ # N.B. If this gets called, async will close the pipe (the spawn object)
+ # for us
+ try:
+ self.expecter.spawn.flag_eof = True
+ index = self.expecter.eof()
+ except EOF as e:
+ self.error(e)
+ else:
+ self.found(index)
+
+ def connection_lost(self, exc):
+ if isinstance(exc, OSError) and exc.errno == errno.EIO:
+ # We may get here without eof_received being called, e.g on Linux
+ self.eof_received()
+ elif exc is not None:
+ self.error(exc)
« no previous file with comments | « third_party/pexpect/pexpect/__init__.py ('k') | third_party/pexpect/pexpect/bashrc.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698