##// END OF EJS Templates
py3compat fixes for %%script and tests
MinRK -
Show More
@@ -1,215 +1,216 b''
1 1 """Magic functions for running cells in various scripts."""
2 2 #-----------------------------------------------------------------------------
3 3 # Copyright (c) 2012 The IPython Development Team.
4 4 #
5 5 # Distributed under the terms of the Modified BSD License.
6 6 #
7 7 # The full license is in the file COPYING.txt, distributed with this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 # Stdlib
15 15 import os
16 16 import re
17 17 import sys
18 18 from subprocess import Popen, PIPE
19 19
20 20 # Our own packages
21 21 from IPython.config.configurable import Configurable
22 22 from IPython.core import magic_arguments
23 23 from IPython.core.error import UsageError
24 24 from IPython.core.magic import (
25 25 Magics, magics_class, line_magic, cell_magic
26 26 )
27 27 from IPython.lib.backgroundjobs import BackgroundJobManager
28 28 from IPython.testing.skipdoctest import skip_doctest
29 29 from IPython.utils import py3compat
30 30 from IPython.utils.process import find_cmd, FindCmdError, arg_split
31 31 from IPython.utils.traitlets import List, Dict
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Magic implementation classes
35 35 #-----------------------------------------------------------------------------
36 36
37 37 def script_args(f):
38 38 """single decorator for adding script args"""
39 39 args = [
40 40 magic_arguments.argument(
41 41 '--out', type=str,
42 42 help="""The variable in which to store stdout from the script.
43 43 If the script is backgrounded, this will be the stdout *pipe*,
44 44 instead of the stderr text itself.
45 45 """
46 46 ),
47 47 magic_arguments.argument(
48 48 '--err', type=str,
49 49 help="""The variable in which to store stderr from the script.
50 50 If the script is backgrounded, this will be the stderr *pipe*,
51 51 instead of the stderr text itself.
52 52 """
53 53 ),
54 54 magic_arguments.argument(
55 55 '--bg', action="store_true",
56 56 help="""Whether to run the script in the background.
57 57 If given, the only way to see the output of the command is
58 58 with --out/err.
59 59 """
60 60 ),
61 61 ]
62 62 for arg in args:
63 63 f = arg(f)
64 64 return f
65 65
66 66 @magics_class
67 67 class ScriptMagics(Magics, Configurable):
68 68 """Magics for talking to scripts
69 69
70 70 This defines a base `%%script` cell magic for running a cell
71 71 with a program in a subprocess, and registers a few top-level
72 72 magics that call %%script with common interpreters.
73 73 """
74 74 script_magics = List(config=True,
75 75 help="""Extra script cell magics to define
76 76
77 77 This generates simple wrappers of `%%script foo` as `%%foo`.
78 78
79 79 If you want to add script magics that aren't on your path,
80 80 specify them in script_paths
81 81 """,
82 82 )
83 83 def _script_magics_default(self):
84 84 """default to a common list of programs if we find them"""
85 85
86 86 defaults = []
87 87 to_try = []
88 88 if os.name == 'nt':
89 89 defaults.append('cmd')
90 90 to_try.append('powershell')
91 91 to_try.extend([
92 92 'sh',
93 93 'bash',
94 94 'perl',
95 95 'ruby',
96 96 'python3',
97 97 'pypy',
98 98 ])
99 99
100 100 for cmd in to_try:
101 101 if cmd in self.script_paths:
102 102 defaults.append(cmd)
103 103 else:
104 104 try:
105 105 find_cmd(cmd)
106 106 except FindCmdError:
107 107 # command not found, ignore it
108 108 pass
109 109 except ImportError:
110 110 # Windows without pywin32, find_cmd doesn't work
111 111 pass
112 112 else:
113 113 defaults.append(cmd)
114 114 return defaults
115 115
116 116 script_paths = Dict(config=True,
117 117 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
118 118
119 119 Only necessary for items in script_magics where the default path will not
120 120 find the right interpreter.
121 121 """
122 122 )
123 123
124 124 def __init__(self, shell=None):
125 125 Configurable.__init__(self, config=shell.config)
126 126 self._generate_script_magics()
127 127 Magics.__init__(self, shell=shell)
128 128 self.job_manager = BackgroundJobManager()
129 129
130 130 def _generate_script_magics(self):
131 131 cell_magics = self.magics['cell']
132 132 for name in self.script_magics:
133 133 cell_magics[name] = self._make_script_magic(name)
134 134
135 135 def _make_script_magic(self, name):
136 136 """make a named magic, that calls %%script with a particular program"""
137 137 # expand to explicit path if necessary:
138 138 script = self.script_paths.get(name, name)
139 139
140 140 @magic_arguments.magic_arguments()
141 141 @script_args
142 142 def named_script_magic(line, cell):
143 143 # if line, add it as cl-flags
144 144 if line:
145 145 line = "%s %s" % (script, line)
146 146 else:
147 147 line = script
148 148 return self.shebang(line, cell)
149 149
150 150 # write a basic docstring:
151 151 named_script_magic.__doc__ = \
152 152 """%%{name} script magic
153 153
154 154 Run cells with {script} in a subprocess.
155 155
156 156 This is a shortcut for `%%script {script}`
157 157 """.format(**locals())
158 158
159 159 return named_script_magic
160 160
161 161 @magic_arguments.magic_arguments()
162 162 @script_args
163 163 @cell_magic("script")
164 164 def shebang(self, line, cell):
165 165 """Run a cell via a shell command
166 166
167 167 The `%%script` line is like the #! line of script,
168 168 specifying a program (bash, perl, ruby, etc.) with which to run.
169 169
170 170 The rest of the cell is run by that program.
171 171
172 172 Examples
173 173 --------
174 174 ::
175 175
176 176 In [1]: %%script bash
177 177 ...: for i in 1 2 3; do
178 178 ...: echo $i
179 179 ...: done
180 180 1
181 181 2
182 182 3
183 183 """
184 184 argv = arg_split(line, posix = not sys.platform.startswith('win'))
185 185 args, cmd = self.shebang.parser.parse_known_args(argv)
186 186
187 187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
188
188
189 cell = cell.encode('utf8', 'replace')
189 190 if args.bg:
190 191 if args.out:
191 192 self.shell.user_ns[args.out] = p.stdout
192 193 if args.err:
193 194 self.shell.user_ns[args.err] = p.stderr
194 195 self.job_manager.new(self._run_script, p, cell)
195 196 return
196 197
197 198 out, err = p.communicate(cell)
198 199 out = py3compat.bytes_to_str(out)
199 200 err = py3compat.bytes_to_str(err)
200 201 if args.out:
201 202 self.shell.user_ns[args.out] = out
202 203 else:
203 204 sys.stdout.write(out)
204 205 sys.stdout.flush()
205 206 if args.err:
206 207 self.shell.user_ns[args.err] = err
207 208 else:
208 209 sys.stderr.write(err)
209 210 sys.stderr.flush()
210 211
211 212 def _run_script(self, p, cell):
212 213 """callback for running the script in the background"""
213 214 p.stdin.write(cell)
214 215 p.stdin.close()
215 216 p.wait()
@@ -1,664 +1,664 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for various magic functions.
3 3
4 4 Needs to be run by nose (to make ipython session available).
5 5 """
6 6 from __future__ import absolute_import
7 7
8 8 #-----------------------------------------------------------------------------
9 9 # Imports
10 10 #-----------------------------------------------------------------------------
11 11
12 12 import io
13 13 import os
14 14 import sys
15 15 from StringIO import StringIO
16 16 from unittest import TestCase
17 17
18 18 try:
19 19 from importlib import invalidate_caches # Required from Python 3.3
20 20 except ImportError:
21 21 def invalidate_caches():
22 22 pass
23 23
24 24 import nose.tools as nt
25 25
26 26 from IPython.core import magic
27 27 from IPython.core.magic import (Magics, magics_class, line_magic,
28 28 cell_magic, line_cell_magic,
29 29 register_line_magic, register_cell_magic,
30 30 register_line_cell_magic)
31 31 from IPython.core.magics import execution, script
32 32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 33 from IPython.nbformat import current
34 34 from IPython.testing import decorators as dec
35 35 from IPython.testing import tools as tt
36 36 from IPython.utils import py3compat
37 37 from IPython.utils.tempdir import TemporaryDirectory
38 38 from IPython.utils.process import find_cmd
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Test functions begin
42 42 #-----------------------------------------------------------------------------
43 43
44 44 @magic.magics_class
45 45 class DummyMagics(magic.Magics): pass
46 46
47 47 def test_rehashx():
48 48 # clear up everything
49 49 _ip = get_ipython()
50 50 _ip.alias_manager.alias_table.clear()
51 51 del _ip.db['syscmdlist']
52 52
53 53 _ip.magic('rehashx')
54 54 # Practically ALL ipython development systems will have more than 10 aliases
55 55
56 56 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
57 57 for key, val in _ip.alias_manager.alias_table.iteritems():
58 58 # we must strip dots from alias names
59 59 nt.assert_true('.' not in key)
60 60
61 61 # rehashx must fill up syscmdlist
62 62 scoms = _ip.db['syscmdlist']
63 63 yield (nt.assert_true, len(scoms) > 10)
64 64
65 65
66 66 def test_magic_parse_options():
67 67 """Test that we don't mangle paths when parsing magic options."""
68 68 ip = get_ipython()
69 69 path = 'c:\\x'
70 70 m = DummyMagics(ip)
71 71 opts = m.parse_options('-f %s' % path,'f:')[0]
72 72 # argv splitting is os-dependent
73 73 if os.name == 'posix':
74 74 expected = 'c:x'
75 75 else:
76 76 expected = path
77 77 nt.assert_equals(opts['f'], expected)
78 78
79 79 def test_magic_parse_long_options():
80 80 """Magic.parse_options can handle --foo=bar long options"""
81 81 ip = get_ipython()
82 82 m = DummyMagics(ip)
83 83 opts, _ = m.parse_options('--foo --bar=bubble', 'a', 'foo', 'bar=')
84 84 nt.assert_true('foo' in opts)
85 85 nt.assert_true('bar' in opts)
86 86 nt.assert_true(opts['bar'], "bubble")
87 87
88 88
89 89 @dec.skip_without('sqlite3')
90 90 def doctest_hist_f():
91 91 """Test %hist -f with temporary filename.
92 92
93 93 In [9]: import tempfile
94 94
95 95 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
96 96
97 97 In [11]: %hist -nl -f $tfile 3
98 98
99 99 In [13]: import os; os.unlink(tfile)
100 100 """
101 101
102 102
103 103 @dec.skip_without('sqlite3')
104 104 def doctest_hist_r():
105 105 """Test %hist -r
106 106
107 107 XXX - This test is not recording the output correctly. For some reason, in
108 108 testing mode the raw history isn't getting populated. No idea why.
109 109 Disabling the output checking for now, though at least we do run it.
110 110
111 111 In [1]: 'hist' in _ip.lsmagic()
112 112 Out[1]: True
113 113
114 114 In [2]: x=1
115 115
116 116 In [3]: %hist -rl 2
117 117 x=1 # random
118 118 %hist -r 2
119 119 """
120 120
121 121
122 122 @dec.skip_without('sqlite3')
123 123 def doctest_hist_op():
124 124 """Test %hist -op
125 125
126 126 In [1]: class b(float):
127 127 ...: pass
128 128 ...:
129 129
130 130 In [2]: class s(object):
131 131 ...: def __str__(self):
132 132 ...: return 's'
133 133 ...:
134 134
135 135 In [3]:
136 136
137 137 In [4]: class r(b):
138 138 ...: def __repr__(self):
139 139 ...: return 'r'
140 140 ...:
141 141
142 142 In [5]: class sr(s,r): pass
143 143 ...:
144 144
145 145 In [6]:
146 146
147 147 In [7]: bb=b()
148 148
149 149 In [8]: ss=s()
150 150
151 151 In [9]: rr=r()
152 152
153 153 In [10]: ssrr=sr()
154 154
155 155 In [11]: 4.5
156 156 Out[11]: 4.5
157 157
158 158 In [12]: str(ss)
159 159 Out[12]: 's'
160 160
161 161 In [13]:
162 162
163 163 In [14]: %hist -op
164 164 >>> class b:
165 165 ... pass
166 166 ...
167 167 >>> class s(b):
168 168 ... def __str__(self):
169 169 ... return 's'
170 170 ...
171 171 >>>
172 172 >>> class r(b):
173 173 ... def __repr__(self):
174 174 ... return 'r'
175 175 ...
176 176 >>> class sr(s,r): pass
177 177 >>>
178 178 >>> bb=b()
179 179 >>> ss=s()
180 180 >>> rr=r()
181 181 >>> ssrr=sr()
182 182 >>> 4.5
183 183 4.5
184 184 >>> str(ss)
185 185 's'
186 186 >>>
187 187 """
188 188
189 189
190 190 @dec.skip_without('sqlite3')
191 191 def test_macro():
192 192 ip = get_ipython()
193 193 ip.history_manager.reset() # Clear any existing history.
194 194 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
195 195 for i, cmd in enumerate(cmds, start=1):
196 196 ip.history_manager.store_inputs(i, cmd)
197 197 ip.magic("macro test 1-3")
198 198 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
199 199
200 200 # List macros.
201 201 assert "test" in ip.magic("macro")
202 202
203 203
204 204 @dec.skip_without('sqlite3')
205 205 def test_macro_run():
206 206 """Test that we can run a multi-line macro successfully."""
207 207 ip = get_ipython()
208 208 ip.history_manager.reset()
209 209 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
210 210 "%macro test 2-3"]
211 211 for cmd in cmds:
212 212 ip.run_cell(cmd, store_history=True)
213 213 nt.assert_equal(ip.user_ns["test"].value,
214 214 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
215 215 with tt.AssertPrints("12"):
216 216 ip.run_cell("test")
217 217 with tt.AssertPrints("13"):
218 218 ip.run_cell("test")
219 219
220 220
221 221 @dec.skipif_not_numpy
222 222 def test_numpy_reset_array_undec():
223 223 "Test '%reset array' functionality"
224 224 _ip.ex('import numpy as np')
225 225 _ip.ex('a = np.empty(2)')
226 226 yield (nt.assert_true, 'a' in _ip.user_ns)
227 227 _ip.magic('reset -f array')
228 228 yield (nt.assert_false, 'a' in _ip.user_ns)
229 229
230 230 def test_reset_out():
231 231 "Test '%reset out' magic"
232 232 _ip.run_cell("parrot = 'dead'", store_history=True)
233 233 # test '%reset -f out', make an Out prompt
234 234 _ip.run_cell("parrot", store_history=True)
235 235 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
236 236 _ip.magic('reset -f out')
237 237 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
238 238 nt.assert_true(len(_ip.user_ns['Out']) == 0)
239 239
240 240 def test_reset_in():
241 241 "Test '%reset in' magic"
242 242 # test '%reset -f in'
243 243 _ip.run_cell("parrot", store_history=True)
244 244 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
245 245 _ip.magic('%reset -f in')
246 246 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
247 247 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
248 248
249 249 def test_reset_dhist():
250 250 "Test '%reset dhist' magic"
251 251 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
252 252 _ip.magic('cd ' + os.path.dirname(nt.__file__))
253 253 _ip.magic('cd -')
254 254 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
255 255 _ip.magic('reset -f dhist')
256 256 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
257 257 _ip.run_cell("_dh = [d for d in tmp]") #restore
258 258
259 259 def test_reset_in_length():
260 260 "Test that '%reset in' preserves In[] length"
261 261 _ip.run_cell("print 'foo'")
262 262 _ip.run_cell("reset -f in")
263 263 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
264 264
265 265 def test_time():
266 266 _ip.magic('time None')
267 267
268 268 def test_tb_syntaxerror():
269 269 """test %tb after a SyntaxError"""
270 270 ip = get_ipython()
271 271 ip.run_cell("for")
272 272
273 273 # trap and validate stdout
274 274 save_stdout = sys.stdout
275 275 try:
276 276 sys.stdout = StringIO()
277 277 ip.run_cell("%tb")
278 278 out = sys.stdout.getvalue()
279 279 finally:
280 280 sys.stdout = save_stdout
281 281 # trim output, and only check the last line
282 282 last_line = out.rstrip().splitlines()[-1].strip()
283 283 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
284 284
285 285
286 286 @py3compat.doctest_refactor_print
287 287 def doctest_time():
288 288 """
289 289 In [10]: %time None
290 290 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
291 291 Wall time: 0.00 s
292 292
293 293 In [11]: def f(kmjy):
294 294 ....: %time print 2*kmjy
295 295
296 296 In [12]: f(3)
297 297 6
298 298 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
299 299 Wall time: 0.00 s
300 300 """
301 301
302 302
303 303 def test_doctest_mode():
304 304 "Toggle doctest_mode twice, it should be a no-op and run without error"
305 305 _ip.magic('doctest_mode')
306 306 _ip.magic('doctest_mode')
307 307
308 308
309 309 def test_parse_options():
310 310 """Tests for basic options parsing in magics."""
311 311 # These are only the most minimal of tests, more should be added later. At
312 312 # the very least we check that basic text/unicode calls work OK.
313 313 m = DummyMagics(_ip)
314 314 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
315 315 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
316 316
317 317
318 318 def test_dirops():
319 319 """Test various directory handling operations."""
320 320 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
321 321 curpath = os.getcwdu
322 322 startdir = os.getcwdu()
323 323 ipdir = os.path.realpath(_ip.ipython_dir)
324 324 try:
325 325 _ip.magic('cd "%s"' % ipdir)
326 326 nt.assert_equal(curpath(), ipdir)
327 327 _ip.magic('cd -')
328 328 nt.assert_equal(curpath(), startdir)
329 329 _ip.magic('pushd "%s"' % ipdir)
330 330 nt.assert_equal(curpath(), ipdir)
331 331 _ip.magic('popd')
332 332 nt.assert_equal(curpath(), startdir)
333 333 finally:
334 334 os.chdir(startdir)
335 335
336 336
337 337 def test_xmode():
338 338 # Calling xmode three times should be a no-op
339 339 xmode = _ip.InteractiveTB.mode
340 340 for i in range(3):
341 341 _ip.magic("xmode")
342 342 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
343 343
344 344 def test_reset_hard():
345 345 monitor = []
346 346 class A(object):
347 347 def __del__(self):
348 348 monitor.append(1)
349 349 def __repr__(self):
350 350 return "<A instance>"
351 351
352 352 _ip.user_ns["a"] = A()
353 353 _ip.run_cell("a")
354 354
355 355 nt.assert_equal(monitor, [])
356 356 _ip.magic("reset -f")
357 357 nt.assert_equal(monitor, [1])
358 358
359 359 class TestXdel(tt.TempFileMixin):
360 360 def test_xdel(self):
361 361 """Test that references from %run are cleared by xdel."""
362 362 src = ("class A(object):\n"
363 363 " monitor = []\n"
364 364 " def __del__(self):\n"
365 365 " self.monitor.append(1)\n"
366 366 "a = A()\n")
367 367 self.mktmp(src)
368 368 # %run creates some hidden references...
369 369 _ip.magic("run %s" % self.fname)
370 370 # ... as does the displayhook.
371 371 _ip.run_cell("a")
372 372
373 373 monitor = _ip.user_ns["A"].monitor
374 374 nt.assert_equal(monitor, [])
375 375
376 376 _ip.magic("xdel a")
377 377
378 378 # Check that a's __del__ method has been called.
379 379 nt.assert_equal(monitor, [1])
380 380
381 381 def doctest_who():
382 382 """doctest for %who
383 383
384 384 In [1]: %reset -f
385 385
386 386 In [2]: alpha = 123
387 387
388 388 In [3]: beta = 'beta'
389 389
390 390 In [4]: %who int
391 391 alpha
392 392
393 393 In [5]: %who str
394 394 beta
395 395
396 396 In [6]: %whos
397 397 Variable Type Data/Info
398 398 ----------------------------
399 399 alpha int 123
400 400 beta str beta
401 401
402 402 In [7]: %who_ls
403 403 Out[7]: ['alpha', 'beta']
404 404 """
405 405
406 406 def test_whos():
407 407 """Check that whos is protected against objects where repr() fails."""
408 408 class A(object):
409 409 def __repr__(self):
410 410 raise Exception()
411 411 _ip.user_ns['a'] = A()
412 412 _ip.magic("whos")
413 413
414 414 @py3compat.u_format
415 415 def doctest_precision():
416 416 """doctest for %precision
417 417
418 418 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
419 419
420 420 In [2]: %precision 5
421 421 Out[2]: {u}'%.5f'
422 422
423 423 In [3]: f.float_format
424 424 Out[3]: {u}'%.5f'
425 425
426 426 In [4]: %precision %e
427 427 Out[4]: {u}'%e'
428 428
429 429 In [5]: f(3.1415927)
430 430 Out[5]: {u}'3.141593e+00'
431 431 """
432 432
433 433 def test_psearch():
434 434 with tt.AssertPrints("dict.fromkeys"):
435 435 _ip.run_cell("dict.fr*?")
436 436
437 437 def test_timeit_shlex():
438 438 """test shlex issues with timeit (#1109)"""
439 439 _ip.ex("def f(*a,**kw): pass")
440 440 _ip.magic('timeit -n1 "this is a bug".count(" ")')
441 441 _ip.magic('timeit -r1 -n1 f(" ", 1)')
442 442 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
443 443 _ip.magic('timeit -r1 -n1 ("a " + "b")')
444 444 _ip.magic('timeit -r1 -n1 f("a " + "b")')
445 445 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
446 446
447 447
448 448 def test_timeit_arguments():
449 449 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
450 450 _ip.magic("timeit ('#')")
451 451
452 452
453 453 @dec.skipif(execution.profile is None)
454 454 def test_prun_quotes():
455 455 "Test that prun does not clobber string escapes (GH #1302)"
456 456 _ip.magic("prun -q x = '\t'")
457 457 nt.assert_equal(_ip.user_ns['x'], '\t')
458 458
459 459 def test_extension():
460 460 tmpdir = TemporaryDirectory()
461 461 orig_ipython_dir = _ip.ipython_dir
462 462 try:
463 463 _ip.ipython_dir = tmpdir.name
464 464 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
465 465 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
466 466 _ip.magic("install_ext %s" % url)
467 467 _ip.user_ns.pop('arq', None)
468 468 invalidate_caches() # Clear import caches
469 469 _ip.magic("load_ext daft_extension")
470 470 tt.assert_equal(_ip.user_ns['arq'], 185)
471 471 _ip.magic("unload_ext daft_extension")
472 472 assert 'arq' not in _ip.user_ns
473 473 finally:
474 474 _ip.ipython_dir = orig_ipython_dir
475 475
476 476 def test_notebook_export_json():
477 477 with TemporaryDirectory() as td:
478 478 outfile = os.path.join(td, "nb.ipynb")
479 479 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
480 480 _ip.magic("notebook -e %s" % outfile)
481 481
482 482 def test_notebook_export_py():
483 483 with TemporaryDirectory() as td:
484 484 outfile = os.path.join(td, "nb.py")
485 485 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
486 486 _ip.magic("notebook -e %s" % outfile)
487 487
488 488 def test_notebook_reformat_py():
489 489 with TemporaryDirectory() as td:
490 490 infile = os.path.join(td, "nb.ipynb")
491 491 with io.open(infile, 'w', encoding='utf-8') as f:
492 492 current.write(nb0, f, 'json')
493 493
494 494 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
495 495 _ip.magic("notebook -f py %s" % infile)
496 496
497 497 def test_notebook_reformat_json():
498 498 with TemporaryDirectory() as td:
499 499 infile = os.path.join(td, "nb.py")
500 500 with io.open(infile, 'w', encoding='utf-8') as f:
501 501 current.write(nb0, f, 'py')
502 502
503 503 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
504 504 _ip.magic("notebook -f ipynb %s" % infile)
505 505 _ip.magic("notebook -f json %s" % infile)
506 506
507 507 def test_env():
508 508 env = _ip.magic("env")
509 509 assert isinstance(env, dict), type(env)
510 510
511 511
512 512 class CellMagicTestCase(TestCase):
513 513
514 514 def check_ident(self, magic):
515 515 # Manually called, we get the result
516 516 out = _ip.run_cell_magic(magic, 'a', 'b')
517 517 nt.assert_equals(out, ('a','b'))
518 518 # Via run_cell, it goes into the user's namespace via displayhook
519 519 _ip.run_cell('%%' + magic +' c\nd')
520 520 nt.assert_equals(_ip.user_ns['_'], ('c','d'))
521 521
522 522 def test_cell_magic_func_deco(self):
523 523 "Cell magic using simple decorator"
524 524 @register_cell_magic
525 525 def cellm(line, cell):
526 526 return line, cell
527 527
528 528 self.check_ident('cellm')
529 529
530 530 def test_cell_magic_reg(self):
531 531 "Cell magic manually registered"
532 532 def cellm(line, cell):
533 533 return line, cell
534 534
535 535 _ip.register_magic_function(cellm, 'cell', 'cellm2')
536 536 self.check_ident('cellm2')
537 537
538 538 def test_cell_magic_class(self):
539 539 "Cell magics declared via a class"
540 540 @magics_class
541 541 class MyMagics(Magics):
542 542
543 543 @cell_magic
544 544 def cellm3(self, line, cell):
545 545 return line, cell
546 546
547 547 _ip.register_magics(MyMagics)
548 548 self.check_ident('cellm3')
549 549
550 550 def test_cell_magic_class2(self):
551 551 "Cell magics declared via a class, #2"
552 552 @magics_class
553 553 class MyMagics2(Magics):
554 554
555 555 @cell_magic('cellm4')
556 556 def cellm33(self, line, cell):
557 557 return line, cell
558 558
559 559 _ip.register_magics(MyMagics2)
560 560 self.check_ident('cellm4')
561 561 # Check that nothing is registered as 'cellm33'
562 562 c33 = _ip.find_cell_magic('cellm33')
563 563 nt.assert_equals(c33, None)
564 564
565 565 def test_file():
566 566 """Basic %%file"""
567 567 ip = get_ipython()
568 568 with TemporaryDirectory() as td:
569 569 fname = os.path.join(td, 'file1')
570 570 ip.run_cell_magic("file", fname, u'\n'.join([
571 571 'line1',
572 572 'line2',
573 573 ]))
574 574 with open(fname) as f:
575 575 s = f.read()
576 576 nt.assert_in('line1\n', s)
577 577 nt.assert_in('line2', s)
578 578
579 579 def test_file_unicode():
580 580 """%%file with unicode cell"""
581 581 ip = get_ipython()
582 582 with TemporaryDirectory() as td:
583 583 fname = os.path.join(td, 'file1')
584 584 ip.run_cell_magic("file", fname, u'\n'.join([
585 585 u'linΓ©1',
586 586 u'linΓ©2',
587 587 ]))
588 588 with io.open(fname, encoding='utf-8') as f:
589 589 s = f.read()
590 590 nt.assert_in(u'linΓ©1\n', s)
591 591 nt.assert_in(u'linΓ©2', s)
592 592
593 593 def test_file_amend():
594 594 """%%file -a amends files"""
595 595 ip = get_ipython()
596 596 with TemporaryDirectory() as td:
597 597 fname = os.path.join(td, 'file2')
598 598 ip.run_cell_magic("file", fname, u'\n'.join([
599 599 'line1',
600 600 'line2',
601 601 ]))
602 602 ip.run_cell_magic("file", "-a %s" % fname, u'\n'.join([
603 603 'line3',
604 604 'line4',
605 605 ]))
606 606 with open(fname) as f:
607 607 s = f.read()
608 608 nt.assert_in('line1\n', s)
609 609 nt.assert_in('line3\n', s)
610 610
611 611
612 612 def test_script_config():
613 613 ip = get_ipython()
614 614 ip.config.ScriptMagics.script_magics = ['whoda']
615 615 sm = script.ScriptMagics(shell=ip)
616 616 nt.assert_in('whoda', sm.magics['cell'])
617 617
618 618 @dec.skip_win32
619 619 def test_script_out():
620 620 ip = get_ipython()
621 621 ip.run_cell_magic("script", "--out output sh", "echo 'hi'")
622 622 nt.assert_equals(ip.user_ns['output'], 'hi\n')
623 623
624 624 @dec.skip_win32
625 625 def test_script_err():
626 626 ip = get_ipython()
627 627 ip.run_cell_magic("script", "--err error sh", "echo 'hello' >&2")
628 628 nt.assert_equals(ip.user_ns['error'], 'hello\n')
629 629
630 630 @dec.skip_win32
631 631 def test_script_out_err():
632 632 ip = get_ipython()
633 633 ip.run_cell_magic("script", "--out output --err error sh", "echo 'hi'\necho 'hello' >&2")
634 634 nt.assert_equals(ip.user_ns['output'], 'hi\n')
635 635 nt.assert_equals(ip.user_ns['error'], 'hello\n')
636 636
637 637 @dec.skip_win32
638 638 def test_script_bg_out():
639 639 ip = get_ipython()
640 640 ip.run_cell_magic("script", "--bg --out output sh", "echo 'hi'")
641 nt.assert_equals(ip.user_ns['output'].read(), 'hi\n')
641 nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
642 642
643 643 @dec.skip_win32
644 644 def test_script_bg_err():
645 645 ip = get_ipython()
646 646 ip.run_cell_magic("script", "--bg --err error sh", "echo 'hello' >&2")
647 nt.assert_equals(ip.user_ns['error'].read(), 'hello\n')
647 nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
648 648
649 649 @dec.skip_win32
650 650 def test_script_bg_out_err():
651 651 ip = get_ipython()
652 652 ip.run_cell_magic("script", "--bg --out output --err error sh", "echo 'hi'\necho 'hello' >&2")
653 nt.assert_equals(ip.user_ns['output'].read(), 'hi\n')
654 nt.assert_equals(ip.user_ns['error'].read(), 'hello\n')
653 nt.assert_equals(ip.user_ns['output'].read(), b'hi\n')
654 nt.assert_equals(ip.user_ns['error'].read(), b'hello\n')
655 655
656 656 def test_script_defaults():
657 657 ip = get_ipython()
658 658 for cmd in ['sh', 'bash', 'perl', 'ruby']:
659 659 try:
660 660 find_cmd(cmd)
661 661 except Exception:
662 662 pass
663 663 else:
664 664 nt.assert_in(cmd, ip.magics_manager.magics['cell'])
General Comments 0
You need to be logged in to leave comments. Login now