##// END OF EJS Templates
update ScriptMagics per review...
MinRK -
Show More
@@ -19,18 +19,50 b' from subprocess import Popen, PIPE'
19
19
20 # Our own packages
20 # Our own packages
21 from IPython.config.configurable import Configurable
21 from IPython.config.configurable import Configurable
22 from IPython.core import magic_arguments
22 from IPython.core.error import UsageError
23 from IPython.core.error import UsageError
23 from IPython.core.magic import (
24 from IPython.core.magic import (
24 Magics, magics_class, line_magic, cell_magic
25 Magics, magics_class, line_magic, cell_magic
25 )
26 )
27 from IPython.lib.backgroundjobs import BackgroundJobManager
26 from IPython.testing.skipdoctest import skip_doctest
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 from IPython.utils.traitlets import List, Dict
31 from IPython.utils.traitlets import List, Dict
29
32
30 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
31 # Magic implementation classes
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 @magics_class
66 @magics_class
35 class ScriptMagics(Magics, Configurable):
67 class ScriptMagics(Magics, Configurable):
36 """Magics for talking to scripts
68 """Magics for talking to scripts
@@ -93,6 +125,7 b' class ScriptMagics(Magics, Configurable):'
93 Configurable.__init__(self, config=shell.config)
125 Configurable.__init__(self, config=shell.config)
94 self._generate_script_magics()
126 self._generate_script_magics()
95 Magics.__init__(self, shell=shell)
127 Magics.__init__(self, shell=shell)
128 self.job_manager = BackgroundJobManager()
96
129
97 def _generate_script_magics(self):
130 def _generate_script_magics(self):
98 cell_magics = self.magics['cell']
131 cell_magics = self.magics['cell']
@@ -104,6 +137,8 b' class ScriptMagics(Magics, Configurable):'
104 # expand to explicit path if necessary:
137 # expand to explicit path if necessary:
105 script = self.script_paths.get(name, name)
138 script = self.script_paths.get(name, name)
106
139
140 @magic_arguments.magic_arguments()
141 @script_args
107 def named_script_magic(line, cell):
142 def named_script_magic(line, cell):
108 # if line, add it as cl-flags
143 # if line, add it as cl-flags
109 if line:
144 if line:
@@ -122,7 +157,9 b' class ScriptMagics(Magics, Configurable):'
122 """.format(**locals())
157 """.format(**locals())
123
158
124 return named_script_magic
159 return named_script_magic
125
160
161 @magic_arguments.magic_arguments()
162 @script_args
126 @cell_magic("script")
163 @cell_magic("script")
127 def shebang(self, line, cell):
164 def shebang(self, line, cell):
128 """Run a cell via a shell command
165 """Run a cell via a shell command
@@ -144,12 +181,35 b' class ScriptMagics(Magics, Configurable):'
144 2
181 2
145 3
182 3
146 """
183 """
147 p = Popen(line, stdout=PIPE, stderr=PIPE, stdin=PIPE)
184 argv = arg_split(line, posix = not sys.platform.startswith('win'))
148 out,err = p.communicate(cell)
185 args, cmd = self.shebang.parser.parse_known_args(argv)
149 sys.stdout.write(out)
186
150 sys.stdout.flush()
187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
151 sys.stderr.write(err)
188
152 sys.stderr.flush()
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 %%!
211 def _run_script(self, p, cell):
155 cell_magic('!')(shebang)
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