##// 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 def transform_assign_system(line):
732 def transform_assign_system(line):
733 """Handle the `files = !ls` syntax."""
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 m = _assign_system_re.match(line)
734 m = _assign_system_re.match(line)
739 if m is not None:
735 if m is not None:
740 cmd = m.group('cmd')
736 cmd = m.group('cmd')
741 lhs = m.group('lhs')
737 lhs = m.group('lhs')
742 expr = make_quoted_expr("sc -l = %s" % cmd)
738 expr = make_quoted_expr(cmd)
743 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
739 new_line = '%s = get_ipython().getoutput(%s)' % (lhs, expr)
744 return new_line
740 return new_line
745 return line
741 return line
746
742
@@ -63,7 +63,7 b' from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError'
63 from IPython.utils.process import system, getoutput
63 from IPython.utils.process import system, getoutput
64 from IPython.utils.strdispatch import StrDispatch
64 from IPython.utils.strdispatch import StrDispatch
65 from IPython.utils.syspathcontext import prepended_to_syspath
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 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
67 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
68 List, Unicode, Instance, Type)
68 List, Unicode, Instance, Type)
69 from IPython.utils.warn import warn, error, fatal
69 from IPython.utils.warn import warn, error, fatal
@@ -1847,7 +1847,14 b' class InteractiveShell(Configurable, Magic):'
1847 #-------------------------------------------------------------------------
1847 #-------------------------------------------------------------------------
1848
1848
1849 def system(self, cmd):
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 # We do not support backgrounding processes because we either use
1858 # We do not support backgrounding processes because we either use
1852 # pexpect or pipes to read from. Users can always just call
1859 # pexpect or pipes to read from. Users can always just call
1853 # os.system() if they really want a background process.
1860 # os.system() if they really want a background process.
@@ -1856,11 +1863,30 b' class InteractiveShell(Configurable, Magic):'
1856
1863
1857 return system(self.var_expand(cmd, depth=2))
1864 return system(self.var_expand(cmd, depth=2))
1858
1865
1859 def getoutput(self, cmd):
1866 def getoutput(self, cmd, split=True):
1860 """Get output (possibly including stderr) from a subprocess."""
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 if cmd.endswith('&'):
1882 if cmd.endswith('&'):
1862 raise OSError("Background processes not supported.")
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 # Things related to aliases
1892 # Things related to aliases
@@ -2919,7 +2919,7 b' Defaulting color scheme to \'NoColor\'"""'
2919 # If all looks ok, proceed
2919 # If all looks ok, proceed
2920 out = self.shell.getoutput(cmd)
2920 out = self.shell.getoutput(cmd)
2921 if opts.has_key('l'):
2921 if opts.has_key('l'):
2922 out = SList(out.split('\n'))
2922 out = SList(out.splitlines())
2923 else:
2923 else:
2924 out = LSString(out)
2924 out = LSString(out)
2925 if opts.has_key('v'):
2925 if opts.has_key('v'):
@@ -486,7 +486,7 b' class AssignSystemTransformer(PrefilterTransformer):'
486 if m is not None:
486 if m is not None:
487 cmd = m.group('cmd')
487 cmd = m.group('cmd')
488 lhs = m.group('lhs')
488 lhs = m.group('lhs')
489 expr = make_quoted_expr("sc -l =%s" % cmd)
489 expr = make_quoted_expr("sc =%s" % cmd)
490 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
490 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
491 return new_line
491 return new_line
492 return line
492 return line
@@ -395,8 +395,8 b' def transform_checker(tests, func):'
395
395
396 syntax = \
396 syntax = \
397 dict(assign_system =
397 dict(assign_system =
398 [('a =! ls', 'a = get_ipython().magic("sc -l = ls")'),
398 [('a =! ls', 'a = get_ipython().getoutput("ls")'),
399 ('b = !ls', 'b = get_ipython().magic("sc -l = ls")'),
399 ('b = !ls', 'b = get_ipython().getoutput("ls")'),
400 ('x=1', 'x=1'), # normal input is unmodified
400 ('x=1', 'x=1'), # normal input is unmodified
401 (' ',' '), # blank lines are kept intact
401 (' ',' '), # blank lines are kept intact
402 ],
402 ],
@@ -99,6 +99,27 b' def process_handler(cmd, callback, stderr=subprocess.PIPE):'
99 return out
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 def getoutputerror(cmd):
123 def getoutputerror(cmd):
103 """Return (standard output, standard error) of executing cmd in a shell.
124 """Return (standard output, standard error) of executing cmd in a shell.
104
125
@@ -29,6 +29,7 b' except ImportError:'
29
29
30 # Our own
30 # Our own
31 from .autoattr import auto_attr
31 from .autoattr import auto_attr
32 from ._process_common import getoutput
32
33
33 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
34 # Function definitions
35 # Function definitions
@@ -97,6 +98,28 b' class ProcessHandler(object):'
97 except KeyboardInterrupt:
98 except KeyboardInterrupt:
98 print('^C', file=sys.stderr, end='')
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 def system(self, cmd):
123 def system(self, cmd):
101 """Execute a command in a subshell.
124 """Execute a command in a subshell.
102
125
@@ -161,9 +184,9 b' class ProcessHandler(object):'
161 return '%s -c "%s"' % (self.sh, cmd)
184 return '%s -c "%s"' % (self.sh, cmd)
162
185
163
186
164
187 # Make system() with a functional interface for outside use. Note that we use
165 # Make objects with a functional interface for outside use
188 # getoutput() from the _common utils, which is built on top of popen(). Using
166 __ph = ProcessHandler()
189 # pexpect to get subprocess output produces difficult to parse output, since
167
190 # programs think they are talking to a tty and produce highly formatted output
168 system = __ph.system
191 # (ls is a good example) that makes them hard.
169 getoutput = __ph.getoutput
192 system = ProcessHandler().system
General Comments 0
You need to be logged in to leave comments. Login now