diff options
author | Thomas Kluyver <takowl@gmail.com> | 2015-09-22 15:55:14 +0100 |
---|---|---|
committer | Thomas Kluyver <takowl@gmail.com> | 2015-09-22 15:55:14 +0100 |
commit | ea586fb9a545854f9b1212779653ec80f3428a2c (patch) | |
tree | 73314e01eb5a39299465d1cfa4e4d5d7b4bdedbb | |
parent | 4411cd9203c0624f9f800726ea4b5ea24c989424 (diff) | |
parent | 3cdab2ef2eebb62514dee116142c73e475735a87 (diff) | |
download | pexpect-ea586fb9a545854f9b1212779653ec80f3428a2c.tar.gz |
Merge remote-tracking branch 'origin/setwinsize_on_spawn'
Conflicts:
doc/history.rst
-rw-r--r-- | doc/history.rst | 3 | ||||
-rw-r--r-- | pexpect/pty_spawn.py | 13 | ||||
-rwxr-xr-x | tests/sigwinch_report.py | 1 | ||||
-rwxr-xr-x | tests/test_misc.py | 6 | ||||
-rwxr-xr-x | tests/test_winsize.py | 59 |
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() |