##// END OF EJS Templates
Fix bugs in x=!cmd; we can't use pexpect at all....
Fernando Perez -
Show More
@@ -731,16 +731,12 b" _assign_system_re = re.compile(r'(?P<lhs>(\\s*)([\\w\\.]+)((\\s*,\\s*[\\w\\.]+)*))'"
731 731
732 732 def transform_assign_system(line):
733 733 """Handle the `files = !ls` syntax."""
734 # FIXME: This transforms the line to use %sc, but we've listed that magic
735 # as deprecated. We should then implement this functionality in a
736 # standalone api that we can transform to, without going through a
737 # deprecated magic.
738 734 m = _assign_system_re.match(line)
739 735 if m is not None:
740 736 cmd = m.group('cmd')
741 737 lhs = m.group('lhs')
742 expr = make_quoted_expr("sc -l = %s" % cmd)
743 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
738 expr = make_quoted_expr(cmd)
739 new_line = '%s = get_ipython().getoutput(%s)' % (lhs, expr)
744 740 return new_line
745 741 return line
746 742
@@ -63,7 +63,7 b' from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError'
63 63 from IPython.utils.process import system, getoutput
64 64 from IPython.utils.strdispatch import StrDispatch
65 65 from IPython.utils.syspathcontext import prepended_to_syspath
66 from IPython.utils.text import num_ini_spaces, format_screen
66 from IPython.utils.text import num_ini_spaces, format_screen, LSString, SList
67 67 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
68 68 List, Unicode, Instance, Type)
69 69 from IPython.utils.warn import warn, error, fatal
@@ -1847,7 +1847,14 b' class InteractiveShell(Configurable, Magic):'
1847 1847 #-------------------------------------------------------------------------
1848 1848
1849 1849 def system(self, cmd):
1850 """Call the given cmd in a subprocess."""
1850 """Call the given cmd in a subprocess.
1851
1852 Parameters
1853 ----------
1854 cmd : str
1855 Command to execute (can not end in '&', as bacground processes are
1856 not supported.
1857 """
1851 1858 # We do not support backgrounding processes because we either use
1852 1859 # pexpect or pipes to read from. Users can always just call
1853 1860 # os.system() if they really want a background process.
@@ -1856,11 +1863,30 b' class InteractiveShell(Configurable, Magic):'
1856 1863
1857 1864 return system(self.var_expand(cmd, depth=2))
1858 1865
1859 def getoutput(self, cmd):
1860 """Get output (possibly including stderr) from a subprocess."""
1866 def getoutput(self, cmd, split=True):
1867 """Get output (possibly including stderr) from a subprocess.
1868
1869 Parameters
1870 ----------
1871 cmd : str
1872 Command to execute (can not end in '&', as bacground processes are
1873 not supported.
1874 split : bool, optional
1875
1876 If True, split the output into an IPython SList. Otherwise, an
1877 IPython LSString is returned. These are objects similar to normal
1878 lists and strings, with a few convenience attributes for easier
1879 manipulation of line-based output. You can use '?' on them for
1880 details.
1881 """
1861 1882 if cmd.endswith('&'):
1862 1883 raise OSError("Background processes not supported.")
1863 return getoutput(self.var_expand(cmd, depth=2))
1884 out = getoutput(self.var_expand(cmd, depth=2))
1885 if split:
1886 out = SList(out.splitlines())
1887 else:
1888 out = LSString(out)
1889 return out
1864 1890
1865 1891 #-------------------------------------------------------------------------
1866 1892 # Things related to aliases
@@ -2919,7 +2919,7 b' Defaulting color scheme to \'NoColor\'"""'
2919 2919 # If all looks ok, proceed
2920 2920 out = self.shell.getoutput(cmd)
2921 2921 if opts.has_key('l'):
2922 out = SList(out.split('\n'))
2922 out = SList(out.splitlines())
2923 2923 else:
2924 2924 out = LSString(out)
2925 2925 if opts.has_key('v'):
@@ -486,7 +486,7 b' class AssignSystemTransformer(PrefilterTransformer):'
486 486 if m is not None:
487 487 cmd = m.group('cmd')
488 488 lhs = m.group('lhs')
489 expr = make_quoted_expr("sc -l =%s" % cmd)
489 expr = make_quoted_expr("sc =%s" % cmd)
490 490 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
491 491 return new_line
492 492 return line
@@ -395,8 +395,8 b' def transform_checker(tests, func):'
395 395
396 396 syntax = \
397 397 dict(assign_system =
398 [('a =! ls', 'a = get_ipython().magic("sc -l = ls")'),
399 ('b = !ls', 'b = get_ipython().magic("sc -l = ls")'),
398 [('a =! ls', 'a = get_ipython().getoutput("ls")'),
399 ('b = !ls', 'b = get_ipython().getoutput("ls")'),
400 400 ('x=1', 'x=1'), # normal input is unmodified
401 401 (' ',' '), # blank lines are kept intact
402 402 ],
@@ -99,6 +99,27 b' def process_handler(cmd, callback, stderr=subprocess.PIPE):'
99 99 return out
100 100
101 101
102 def getoutput(cmd):
103 """Return standard output of executing cmd in a shell.
104
105 Accepts the same arguments as os.system().
106
107 Parameters
108 ----------
109 cmd : str
110 A command to be executed in the system shell.
111
112 Returns
113 -------
114 stdout : str
115 """
116
117 out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT)
118 if out is None:
119 out = ''
120 return out
121
122
102 123 def getoutputerror(cmd):
103 124 """Return (standard output, standard error) of executing cmd in a shell.
104 125
@@ -29,6 +29,7 b' except ImportError:'
29 29
30 30 # Our own
31 31 from .autoattr import auto_attr
32 from ._process_common import getoutput
32 33
33 34 #-----------------------------------------------------------------------------
34 35 # Function definitions
@@ -97,6 +98,28 b' class ProcessHandler(object):'
97 98 except KeyboardInterrupt:
98 99 print('^C', file=sys.stderr, end='')
99 100
101 def getoutput_pexpect(self, cmd):
102 """Run a command and return its stdout/stderr as a string.
103
104 Parameters
105 ----------
106 cmd : str
107 A command to be executed in the system shell.
108
109 Returns
110 -------
111 output : str
112 A string containing the combination of stdout and stderr from the
113 subprocess, in whatever order the subprocess originally wrote to its
114 file descriptors (so the order of the information in this string is the
115 correct order as would be seen if running the command in a terminal).
116 """
117 pcmd = self._make_cmd(cmd)
118 try:
119 return pexpect.run(pcmd).replace('\r\n', '\n')
120 except KeyboardInterrupt:
121 print('^C', file=sys.stderr, end='')
122
100 123 def system(self, cmd):
101 124 """Execute a command in a subshell.
102 125
@@ -161,9 +184,9 b' class ProcessHandler(object):'
161 184 return '%s -c "%s"' % (self.sh, cmd)
162 185
163 186
164
165 # Make objects with a functional interface for outside use
166 __ph = ProcessHandler()
167
168 system = __ph.system
169 getoutput = __ph.getoutput
187 # Make system() with a functional interface for outside use. Note that we use
188 # getoutput() from the _common utils, which is built on top of popen(). Using
189 # pexpect to get subprocess output produces difficult to parse output, since
190 # programs think they are talking to a tty and produce highly formatted output
191 # (ls is a good example) that makes them hard.
192 system = ProcessHandler().system
General Comments 0
You need to be logged in to leave comments. Login now