summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kluyver <takowl@gmail.com>2015-09-22 15:55:14 +0100
committerThomas Kluyver <takowl@gmail.com>2015-09-22 15:55:14 +0100
commitea586fb9a545854f9b1212779653ec80f3428a2c (patch)
tree73314e01eb5a39299465d1cfa4e4d5d7b4bdedbb
parent4411cd9203c0624f9f800726ea4b5ea24c989424 (diff)
parent3cdab2ef2eebb62514dee116142c73e475735a87 (diff)
downloadpexpect-ea586fb9a545854f9b1212779653ec80f3428a2c.tar.gz
Merge remote-tracking branch 'origin/setwinsize_on_spawn'
Conflicts: doc/history.rst
-rw-r--r--doc/history.rst3
-rw-r--r--pexpect/pty_spawn.py13
-rwxr-xr-xtests/sigwinch_report.py1
-rwxr-xr-xtests/test_misc.py6
-rwxr-xr-xtests/test_winsize.py59
5 files changed, 44 insertions, 38 deletions
diff --git a/doc/history.rst b/doc/history.rst
index 8ebe458..d60402a 100644
--- a/doc/history.rst
+++ b/doc/history.rst
@@ -22,6 +22,9 @@ Version 4.0
* Removed the independent top-level modules (``pxssh fdpexpect FSM screen ANSI``)
which were installed alongside Pexpect. These were moved into the Pexpect
package in 3.0, but the old names were left as aliases.
+* New :class:`pexpect.spawn` keyword argument, ``dimensions=(rows, columns)``
+ allows setting terminal screen dimensions before launching a program
+ (:ghissue:`122`).
* Fix regression that prevented executable, but unreadable files from
being found when not specified by absolute path -- such as
/usr/bin/sudo (:ghissue:`104`).
diff --git a/pexpect/pty_spawn.py b/pexpect/pty_spawn.py
index 0b9ad4c..9141b17 100644
--- a/pexpect/pty_spawn.py
+++ b/pexpect/pty_spawn.py
@@ -37,7 +37,7 @@ class spawn(SpawnBase):
def __init__(self, command, args=[], timeout=30, maxread=2000,
searchwindowsize=None, logfile=None, cwd=None, env=None,
ignore_sighup=True, echo=True, preexec_fn=None,
- encoding=None, codec_errors='strict'):
+ encoding=None, codec_errors='strict', dimensions=None):
'''This is the constructor. The command parameter may be a string that
includes a command and any arguments to the command. For example::
@@ -174,6 +174,10 @@ class spawn(SpawnBase):
If preexec_fn is given, it will be called in the child process before
launching the given command. This is useful to e.g. reset inherited
signal handlers.
+
+ The dimensions attribute specifies the size of the pseudo-terminal as
+ seen by the subprocess, and is specified as a two-entry tuple (rows,
+ columns). If this is unspecified, the defaults in ptyprocess will apply.
'''
super(spawn, self).__init__(timeout=timeout, maxread=maxread, searchwindowsize=searchwindowsize,
logfile=logfile, encoding=encoding, codec_errors=codec_errors)
@@ -190,7 +194,7 @@ class spawn(SpawnBase):
self.args = None
self.name = '<pexpect factory incomplete>'
else:
- self._spawn(command, args, preexec_fn)
+ self._spawn(command, args, preexec_fn, dimensions)
def __str__(self):
'''This returns a human-readable string that represents the state of
@@ -226,7 +230,7 @@ class spawn(SpawnBase):
s.append('delayafterterminate: ' + str(self.delayafterterminate))
return '\n'.join(s)
- def _spawn(self, command, args=[], preexec_fn=None):
+ def _spawn(self, command, args=[], preexec_fn=None, dimensions=None):
'''This starts the given command in a child process. This does all the
fork/exec type of stuff for a pty. This is called by __init__. If args
is empty then command will be parsed (split on spaces) and args will be
@@ -281,6 +285,9 @@ class spawn(SpawnBase):
preexec_fn()
kwargs['preexec_fn'] = preexec_wrapper
+ if dimensions is not None:
+ kwargs['dimensions'] = dimensions
+
self.ptyproc = ptyprocess.PtyProcess.spawn(self.args, env=self.env,
cwd=self.cwd, **kwargs)
diff --git a/tests/sigwinch_report.py b/tests/sigwinch_report.py
index 626d424..f10956a 100755
--- a/tests/sigwinch_report.py
+++ b/tests/sigwinch_report.py
@@ -39,6 +39,7 @@ def handler(signum, frame):
print('SIGWINCH:', getwinsize ())
sys.stdout.flush()
+print("Initial Size:", getwinsize())
print("setting handler for SIGWINCH")
signal.signal(signal.SIGWINCH, handler)
print("READY")
diff --git a/tests/test_misc.py b/tests/test_misc.py
index d5a707c..16bdfc2 100755
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -317,9 +317,11 @@ class TestCaseMisc(PexpectTestCase.PexpectTestCase):
" test forced self.__fork_pty() and __pty_make_controlling_tty "
# given,
class spawn_ourptyfork(pexpect.spawn):
- def _spawn(self, command, args=[], preexec_fn=None):
+ def _spawn(self, command, args=[], preexec_fn=None,
+ dimensions=None):
self.use_native_pty_fork = False
- pexpect.spawn._spawn(self, command, args, preexec_fn)
+ pexpect.spawn._spawn(self, command, args, preexec_fn,
+ dimensions)
# exercise,
p = spawn_ourptyfork('cat', echo=False)
diff --git a/tests/test_winsize.py b/tests/test_winsize.py
index 75f8c0e..be16773 100755
--- a/tests/test_winsize.py
+++ b/tests/test_winsize.py
@@ -25,39 +25,32 @@ import time
class TestCaseWinsize(PexpectTestCase.PexpectTestCase):
- def test_winsize (self):
- '''
- This tests that the child process can set and get the windows size.
- This makes use of an external script sigwinch_report.py.
- '''
- p1 = pexpect.spawn('%s sigwinch_report.py' % self.PYTHONBIN)
- p1.expect('READY', timeout=10)
-
- p1.setwinsize (11,22)
- index = p1.expect ([pexpect.TIMEOUT, b'SIGWINCH: \(([0-9]*), ([0-9]*)\)'],
- timeout=30)
- if index == 0:
- self.fail("TIMEOUT -- this platform may not support sigwinch properly.\n" + str(p1))
- self.assertEqual(p1.match.group(1, 2), (b"11" ,b"22"))
- self.assertEqual(p1.getwinsize(), (11, 22))
-
- time.sleep(1)
- p1.setwinsize (24,80)
- index = p1.expect ([pexpect.TIMEOUT, b'SIGWINCH: \(([0-9]*), ([0-9]*)\)'],
- timeout=10)
- if index == 0:
- self.fail ("TIMEOUT -- this platform may not support sigwinch properly.\n" + str(p1))
- self.assertEqual(p1.match.group(1, 2), (b"24" ,b"80"))
- self.assertEqual(p1.getwinsize(), (24, 80))
-
- p1.close()
-
-# def test_parent_resize (self):
-# pid = os.getpid()
-# p1 = pexpect.spawn('%s sigwinch_report.py' % self.PYTHONBIN)
-# time.sleep(10)
-# p1.setwinsize (11,22)
-# os.kill (pid, signal.SIGWINCH)
+ def test_initial_winsize(self):
+ """ Assert initial window dimension size (24, 80). """
+ p = pexpect.spawn('{self.PYTHONBIN} sigwinch_report.py'
+ .format(self=self), timeout=3)
+ # default size by PtyProcess class is 24 rows by 80 columns.
+ p.expect_exact('Initial Size: (24, 80)')
+ p.close()
+
+ def test_initial_winsize_by_dimension(self):
+ """ Assert user-parameter window dimension size is initial. """
+ p = pexpect.spawn('{self.PYTHONBIN} sigwinch_report.py'
+ .format(self=self), timeout=3,
+ dimensions=(40, 100))
+ p.expect_exact('Initial Size: (40, 100)')
+ p.close()
+
+ def test_setwinsize(self):
+ """ Ensure method .setwinsize() sends signal caught by child. """
+ p = pexpect.spawn('{self.PYTHONBIN} sigwinch_report.py'
+ .format(self=self), timeout=3)
+ # Note that we must await the installation of the child process'
+ # signal handler,
+ p.expect_exact('READY')
+ p.setwinsize(19, 84)
+ p.expect_exact('SIGWINCH: (19, 84)')
+ p.close()
if __name__ == '__main__':
unittest.main()