Skip to content

Commit

Permalink
Allow {p}.interact(escape_character=None)
Browse files Browse the repository at this point in the history
For those who wish to disable the ability to escape using
escape_character until normal process termination, they
may now set the value of escape_character to None.

Some of the related docstring on escape_character was made more
brief and clear about its related value behavior.

This closes #131 #132 #167
  • Loading branch information
jquast committed Sep 18, 2015
1 parent cde8e15 commit faff3e6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 10 deletions.
15 changes: 8 additions & 7 deletions pexpect/pty_spawn.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,11 +684,10 @@ def interact(self, escape_character=chr(29),
the stdout and stderr output of the child process is printed. This
simply echos the child stdout and child stderr to the real stdout and
it echos the real stdin to the child stdin. When the user types the
escape_character this method will stop. The default for
escape_character is ^]. This should not be confused with ASCII 27 --
the ESC character. ASCII 29 was chosen for historical merit because
this is the character used by 'telnet' as the escape character. The
escape_character will not be sent to the child process.
escape_character this method will return None. The escape_character
will not be transmitted. The default for escape_character is
entered as ``Ctrl - ]``, the very same as BSD telnet. To prevent
escaping, escape_character may be set to None.
You may pass in optional input and output filter functions. These
functions should take a string and return a string. The output_filter
Expand Down Expand Up @@ -720,7 +719,7 @@ def sigwinch_passthrough (sig, data):
self.buffer = self.string_type()
mode = tty.tcgetattr(self.STDIN_FILENO)
tty.setraw(self.STDIN_FILENO)
if PY3:
if escape_character is not None and PY3:
escape_character = escape_character.encode('latin-1')
try:
self.__interact_copy(escape_character, input_filter, output_filter)
Expand Down Expand Up @@ -770,7 +769,9 @@ def __interact_copy(self, escape_character=None,
data = self.__interact_read(self.STDIN_FILENO)
if input_filter:
data = input_filter(data)
i = data.rfind(escape_character)
i = -1
if escape_character is not None:
i = data.rfind(escape_character)
if i != -1:
data = data[:i]
self.__interact_writen(self.child_fd, data)
Expand Down
5 changes: 3 additions & 2 deletions tests/getch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
'''
from __future__ import print_function
import sys, tty, termios

if hasattr(sys.stdin, 'buffer'):
Expand All @@ -27,13 +28,13 @@
stdin = sys.stdin

def main():
print('READY')
print('READY', end='\r\n')
while True:
try:
val = ord(stdin.read(1))
except KeyboardInterrupt:
val = 3
sys.stdout.write('%d<STOP>\r\n' % (val,))
print('%d<STOP>' % (val,), end='\r\n')
if val == 0:
# StopIteration equivalent is ctrl+' ' (\x00, NUL)
break
Expand Down
5 changes: 4 additions & 1 deletion tests/interact.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
def main():
p = pexpect.spawn(sys.executable + ' echo_w_prompt.py',
env=no_coverage_env())
p.interact()
escape_character = chr(29) # default matches api
if len(sys.argv) > 1 and sys.argv[1] == '--no-escape':
escape_character = None
p.interact(escape_character=escape_character)
print("Escaped interact")

if __name__ == '__main__':
Expand Down
15 changes: 15 additions & 0 deletions tests/test_interact.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ def test_interact_escape(self):
assert not p.isalive()
assert p.exitstatus == 0

def test_interact_escape_None(self):
" Return only after Termination when `escape_character=None'. "
p = pexpect.spawn('{self.interact_py} --no-escape'.format(self=self),
timeout=5, env=self.env)
p.expect('<in >')
p.sendcontrol(']')
p.sendline('')
p.expect('<out>\x1d')
p.sendcontrol('d')
p.expect('<eof>')
p.expect_exact('Escaped interact')
p.expect(pexpect.EOF)
assert not p.isalive()
assert p.exitstatus == 0

def test_interact_spawn_eof(self):
" Ensure subprocess receives EOF and exit. "
p = pexpect.spawn(self.interact_py, timeout=5, env=self.env)
Expand Down

0 comments on commit faff3e6

Please sign in to comment.