diff --git a/IPython/utils/_process_common.py b/IPython/utils/_process_common.py index 00436ee..34ca83b 100644 --- a/IPython/utils/_process_common.py +++ b/IPython/utils/_process_common.py @@ -103,9 +103,7 @@ def process_handler(cmd, callback, stderr=subprocess.PIPE): def getoutput(cmd): - """Return standard output of executing cmd in a shell. - - Accepts the same arguments as os.system(). + """Run a command and return its stdout/stderr as a string. Parameters ---------- @@ -114,9 +112,12 @@ def getoutput(cmd): Returns ------- - stdout : str + output : str + A string containing the combination of stdout and stderr from the + subprocess, in whatever order the subprocess originally wrote to its + file descriptors (so the order of the information in this string is the + correct order as would be seen if running the command in a terminal). """ - out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT) if out is None: return '' diff --git a/IPython/utils/tests/test_process.py b/IPython/utils/tests/test_process.py index 1e1a8f3..787e194 100644 --- a/IPython/utils/tests/test_process.py +++ b/IPython/utils/tests/test_process.py @@ -15,6 +15,7 @@ Tests for platutils.py #----------------------------------------------------------------------------- import sys +import os from unittest import TestCase import nose.tools as nt @@ -24,13 +25,15 @@ from IPython.utils.process import (find_cmd, FindCmdError, arg_split, from IPython.testing import decorators as dec from IPython.testing import tools as tt +python = os.path.basename(sys.executable) + #----------------------------------------------------------------------------- # Tests #----------------------------------------------------------------------------- def test_find_cmd_python(): """Make sure we find sys.exectable for python.""" - nt.assert_equal(find_cmd('python'), sys.executable) + nt.assert_equal(find_cmd(python), sys.executable) @dec.skip_win32 @@ -102,30 +105,34 @@ class SubProcessTestCase(TestCase, tt.TempFileMixin): self.mktmp('\n'.join(lines)) def test_system(self): - status = system('python "%s"' % self.fname) + status = system('%s "%s"' % (python, self.fname)) self.assertEqual(status, 0) def test_system_quotes(self): - status = system('python -c "import sys"') + status = system('%s -c "import sys"' % python) self.assertEqual(status, 0) def test_getoutput(self): - out = getoutput('python "%s"' % self.fname) - self.assertEqual(out, 'on stdout') + out = getoutput('%s "%s"' % (python, self.fname)) + # we can't rely on the order the line buffered streams are flushed + try: + self.assertEqual(out, 'on stderron stdout') + except AssertionError: + self.assertEqual(out, 'on stdouton stderr') def test_getoutput_quoted(self): - out = getoutput('python -c "print (1)"') + out = getoutput('%s -c "print (1)"' % python) self.assertEqual(out.strip(), '1') #Invalid quoting on windows @dec.skip_win32 def test_getoutput_quoted2(self): - out = getoutput("python -c 'print (1)'") + out = getoutput("%s -c 'print (1)'" % python) self.assertEqual(out.strip(), '1') - out = getoutput("python -c 'print (\"1\")'") + out = getoutput("%s -c 'print (\"1\")'" % python) self.assertEqual(out.strip(), '1') - def test_getoutput(self): - out, err = getoutputerror('python "%s"' % self.fname) + def test_getoutput_error(self): + out, err = getoutputerror('%s "%s"' % (python, self.fname)) self.assertEqual(out, 'on stdout') self.assertEqual(err, 'on stderr')