From fe42cfa8daec2aa8e471a618b5e315ae2083d4ff 2014-06-18 16:53:27 From: Thomas Kluyver Date: 2014-06-18 16:53:27 Subject: [PATCH] Merge pull request #6006 from minrk/ec128 handle error code > 128 in system_raw like system_piped --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index af5d798..6874b63 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2328,6 +2328,11 @@ class InteractiveShell(SingletonConfigurable): ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None)) # exit code is positive for program failure, or negative for # terminating signal number. + + # Interpret ec > 128 as signal + # Some shells (csh, fish) don't follow sh/bash conventions for exit codes + if ec > 128: + ec = -(ec - 128) # We explicitly do NOT return the subprocess status code, because # a non-None value would trigger :func:`sys.displayhook` calls. diff --git a/IPython/core/tests/test_interactiveshell.py b/IPython/core/tests/test_interactiveshell.py index f5ceb03..77e27ff 100644 --- a/IPython/core/tests/test_interactiveshell.py +++ b/IPython/core/tests/test_interactiveshell.py @@ -25,9 +25,12 @@ from os.path import join import nose.tools as nt from IPython.core.inputtransformer import InputTransformer -from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths +from IPython.testing.decorators import ( + skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist, +) from IPython.testing import tools as tt from IPython.utils import io +from IPython.utils.process import find_cmd from IPython.utils import py3compat from IPython.utils.py3compat import unicode_type, PY3 @@ -436,7 +439,7 @@ class ExitCodeChecks(tt.TempFileMixin): def test_exit_code_error(self): self.system('exit 1') self.assertEqual(ip.user_ns['_exit_code'], 1) - + @skipif(not hasattr(signal, 'SIGALRM')) def test_exit_code_signal(self): self.mktmp("import signal, time\n" @@ -444,6 +447,18 @@ class ExitCodeChecks(tt.TempFileMixin): "time.sleep(1)\n") self.system("%s %s" % (sys.executable, self.fname)) self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM) + + @onlyif_cmds_exist("csh") + def test_exit_code_signal_csh(self): + SHELL = os.environ.get('SHELL', None) + os.environ['SHELL'] = find_cmd("csh") + try: + self.test_exit_code_signal() + finally: + if SHELL is not None: + os.environ['SHELL'] = SHELL + else: + del os.environ['SHELL'] class TestSystemRaw(unittest.TestCase, ExitCodeChecks): system = ip.system_raw