Skip to content

Commit

Permalink
Issue-128: allow use Barnett's regexs in pexpect
Browse files Browse the repository at this point in the history
Pexpect checks explicitly for Python's regexs rejecting Barnett's one.
The adapter closes the gap between this two and allow to use Barnett's
regex with pexpect.
  • Loading branch information
eldipa committed Nov 26, 2020
1 parent 04ac594 commit 06ee339
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions byexample/runner.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import unicode_literals
import pexpect, time, termios, operator, os, itertools, contextlib
import re as re_orig
import re as python_re
from . import regex as re
from functools import reduce, partial
from .executor import TimeoutException, InputPrefixNotFound
Expand Down Expand Up @@ -80,6 +80,43 @@ def cancel(self, example, options):
return False


class PexpectSpawnAdapter(pexpect.spawn):
def compile_pattern_list(self, patterns):
''' This is an extension of pexpect.spawn.compile_pattern_list
to accept not only Python's regex objects (re module) but
also Barnett's regexs (third-party regex module).
This is a workaround for the issue #655
(https://github.com/pexpect/pexpect/issues/655)
'''
if patterns is None:
return []
if not isinstance(patterns, list):
patterns = [patterns]

# Allow dot to match \n
compile_flags = python_re.DOTALL
if self.ignorecase:
compile_flags = compile_flags | python_re.IGNORECASE
compiled_pattern_list = []
cls = pexpect.spawnbase
for idx, p in enumerate(patterns):
if isinstance(p, self.allowed_string_types):
p = self._coerce_expect_string(p)
compiled_pattern_list.append(python_re.compile(p, compile_flags))
elif p is cls.EOF:
compiled_pattern_list.append(cls.EOF)
elif p is cls.TIMEOUT:
compiled_pattern_list.append(cls.TIMEOUT)
elif isinstance(p, type(python_re.compile(''))):
compiled_pattern_list.append(p)
elif isinstance(p, type(re.compile(''))): # <-- the workaround
compiled_pattern_list.append(p)
else:
self._pattern_type_err(p)
return compiled_pattern_list


class PexpectMixin(object):
def __init__(self, PS1_re, any_PS_re):
self.PS1_re = re.compile(PS1_re)
Expand All @@ -106,7 +143,7 @@ def _spawn_interpreter(
env.update({'LINES': str(rows), 'COLUMNS': str(cols)})

self._drop_output() # there shouldn't be any output yet but...
self.interpreter = pexpect.spawn(
self.interpreter = PexpectSpawnAdapter(
cmd,
echo=False,
encoding=self.encoding,
Expand Down

0 comments on commit 06ee339

Please sign in to comment.