##// END OF EJS Templates
update ScriptMagics per review...
MinRK -
Show More
@@ -19,18 +19,50 b' from subprocess import Popen, PIPE'
19 19
20 20 # Our own packages
21 21 from IPython.config.configurable import Configurable
22 from IPython.core import magic_arguments
22 23 from IPython.core.error import UsageError
23 24 from IPython.core.magic import (
24 25 Magics, magics_class, line_magic, cell_magic
25 26 )
27 from IPython.lib.backgroundjobs import BackgroundJobManager
26 28 from IPython.testing.skipdoctest import skip_doctest
27 from IPython.utils.process import find_cmd, FindCmdError
29 from IPython.utils import py3compat
30 from IPython.utils.process import find_cmd, FindCmdError, arg_split
28 31 from IPython.utils.traitlets import List, Dict
29 32
30 33 #-----------------------------------------------------------------------------
31 34 # Magic implementation classes
32 35 #-----------------------------------------------------------------------------
33 36
37 def script_args(f):
38 """single decorator for adding script args"""
39 args = [
40 magic_arguments.argument(
41 '--out', type=str,
42 help="""The variable in which to store stdout from the script.
43 If the script is backgrounded, this will be the stdout *pipe*,
44 instead of the stderr text itself.
45 """
46 ),
47 magic_arguments.argument(
48 '--err', type=str,
49 help="""The variable in which to store stderr from the script.
50 If the script is backgrounded, this will be the stderr *pipe*,
51 instead of the stderr text itself.
52 """
53 ),
54 magic_arguments.argument(
55 '--bg', action="store_true",
56 help="""Whether to run the script in the background.
57 If given, the only way to see the output of the command is
58 with --out/err.
59 """
60 ),
61 ]
62 for arg in args:
63 f = arg(f)
64 return f
65
34 66 @magics_class
35 67 class ScriptMagics(Magics, Configurable):
36 68 """Magics for talking to scripts
@@ -93,6 +125,7 b' class ScriptMagics(Magics, Configurable):'
93 125 Configurable.__init__(self, config=shell.config)
94 126 self._generate_script_magics()
95 127 Magics.__init__(self, shell=shell)
128 self.job_manager = BackgroundJobManager()
96 129
97 130 def _generate_script_magics(self):
98 131 cell_magics = self.magics['cell']
@@ -104,6 +137,8 b' class ScriptMagics(Magics, Configurable):'
104 137 # expand to explicit path if necessary:
105 138 script = self.script_paths.get(name, name)
106 139
140 @magic_arguments.magic_arguments()
141 @script_args
107 142 def named_script_magic(line, cell):
108 143 # if line, add it as cl-flags
109 144 if line:
@@ -122,7 +157,9 b' class ScriptMagics(Magics, Configurable):'
122 157 """.format(**locals())
123 158
124 159 return named_script_magic
125
160
161 @magic_arguments.magic_arguments()
162 @script_args
126 163 @cell_magic("script")
127 164 def shebang(self, line, cell):
128 165 """Run a cell via a shell command
@@ -144,12 +181,35 b' class ScriptMagics(Magics, Configurable):'
144 181 2
145 182 3
146 183 """
147 p = Popen(line, stdout=PIPE, stderr=PIPE, stdin=PIPE)
148 out,err = p.communicate(cell)
149 sys.stdout.write(out)
150 sys.stdout.flush()
151 sys.stderr.write(err)
152 sys.stderr.flush()
184 argv = arg_split(line, posix = not sys.platform.startswith('win'))
185 args, cmd = self.shebang.parser.parse_known_args(argv)
186
187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
188
189 if args.bg:
190 if args.out:
191 self.shell.user_ns[args.out] = p.stdout
192 if args.err:
193 self.shell.user_ns[args.out] = p.stderr
194 self.job_manager.new(self._run_script, p, cell)
195 return
196
197 out, err = p.communicate(cell)
198 out = py3compat.bytes_to_str(out)
199 err = py3compat.bytes_to_str(err)
200 if args.out:
201 self.shell.user_ns[args.out] = out
202 else:
203 sys.stdout.write(out)
204 sys.stdout.flush()
205 if args.err:
206 self.shell.user_ns[args.err] = err
207 else:
208 sys.stderr.write(err)
209 sys.stderr.flush()
153 210
154 # expose %%script as %%!
155 cell_magic('!')(shebang)
211 def _run_script(self, p, cell):
212 """callback for running the script in the background"""
213 p.stdin.write(cell)
214 p.stdin.close()
215 p.wait()
General Comments 0
You need to be logged in to leave comments. Login now