Skip to content

Instantly share code, notes, and snippets.

@jquast
Created October 27, 2015 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jquast/10500bcb1622ce06db8c to your computer and use it in GitHub Desktop.
Save jquast/10500bcb1622ce06db8c to your computer and use it in GitHub Desktop.
texpect.py ~/C/p/p/spawnbase.py X
#!/usr/bin/env python
"example interface on how a terminal-aware pexpect could be derived."
from pexpect.exceptions import TIMEOUT, EOF
from pexpect.expect import Expecter, searcher_re, searcher_string
from pexpect.pty_spawn import spawn
class TerminalExpecter(Expecter):
def new_data(self, data):
# we might modify and derive this method, which sets spawn.buffer,
# spawn.before, spawn.after, etc. to their matching strings. If we
# wish to strip sequences, this line:
(...)
incoming = spawn.buffer + data
# would be the most important to modify -- maybe we wish to strip
# sequences from 'data' before adding it to the 'incoming' buffer.
# the rest of the code would work more or less the same.
# I happen to maintain a 'blessed' library that happens to perform
# this "strip sequence" action, it would look like:
#
# def __init__(....)
# self.term = Terminal(kind='xterm-256color')
#
# (..)
#
# def new_data(self, data)
#
# (...)
#
# incoming = spawn.buffer + term.strip_seqs(data)
#
# (...)
# pyte is probably a better option, i just haven't used it and happen
# to be familiar with my own library
pass
# With our new Expecter class in hand, we need to derive and modify
# pexpect.spawn class to allow us to use it,
class spawn_tstrip(spawn):
"""
pexpect.spawn() interface that strips terminal sequences
before matching, setting match attributes as string buffers
stripped of their sequences.
"""
# as pexpect has only *very recently* even provided such 'Expecter' class,
# the spawn() class does not yet provide any API to select your own
# "Expect factory". So we must derive and modify all methods that use
# phrase 'Expecter', replacing with 'TerminalExpecter:
def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1,
async=False):
if timeout == -1:
timeout = self.timeout
exp = TerminalExpecter(self, searcher_re(pattern_list),
searchwindowsize)
if async:
from .async import expect_async
return expect_async(exp, timeout)
else:
return exp.expect_loop(timeout)
def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1,
async=False):
if timeout == -1:
timeout = self.timeout
if (isinstance(pattern_list, self.allowed_string_types) or
pattern_list in (TIMEOUT, EOF)):
pattern_list = [pattern_list]
def prepare_pattern(pattern):
if pattern in (TIMEOUT, EOF):
return pattern
if isinstance(pattern, self.allowed_string_types):
return self._coerce_expect_string(pattern)
self._pattern_type_err(pattern)
try:
pattern_list = iter(pattern_list)
except TypeError:
self._pattern_type_err(pattern_list)
pattern_list = [prepare_pattern(p) for p in pattern_list]
exp = TerminalExpecter(self, searcher_string(pattern_list),
searchwindowsize)
if async:
from .async import expect_async
return expect_async(exp, timeout)
else:
return exp.expect_loop(timeout)
def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1):
exp = TerminalExpecter(self, searcher, searchwindowsize)
return exp.expect_loop(timeout)
~
~
~
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment