##// END OF EJS Templates
Fix failing tests in core and zmq
Fernando Perez -
Show More
@@ -1,487 +1,487 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
17 17 import nose.tools as nt
18 18
19 19 from IPython.core import magic
20 from IPython.core import magic_functions as mf
20 from IPython.core.magics import execution
21 21 from IPython.nbformat.v3.tests.nbexamples import nb0
22 22 from IPython.nbformat import current
23 23 from IPython.testing import decorators as dec
24 24 from IPython.testing import tools as tt
25 25 from IPython.utils import py3compat
26 26 from IPython.utils.tempdir import TemporaryDirectory
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Test functions begin
30 30 #-----------------------------------------------------------------------------
31 31
32 32 @magic.register_magics
33 33 class DummyMagics(magic.Magics): pass
34 34
35 35 def test_rehashx():
36 36 # clear up everything
37 37 _ip = get_ipython()
38 38 _ip.alias_manager.alias_table.clear()
39 39 del _ip.db['syscmdlist']
40 40
41 41 _ip.magic('rehashx')
42 42 # Practically ALL ipython development systems will have more than 10 aliases
43 43
44 44 yield (nt.assert_true, len(_ip.alias_manager.alias_table) > 10)
45 45 for key, val in _ip.alias_manager.alias_table.iteritems():
46 46 # we must strip dots from alias names
47 47 nt.assert_true('.' not in key)
48 48
49 49 # rehashx must fill up syscmdlist
50 50 scoms = _ip.db['syscmdlist']
51 51 yield (nt.assert_true, len(scoms) > 10)
52 52
53 53
54 54 def test_magic_parse_options():
55 55 """Test that we don't mangle paths when parsing magic options."""
56 56 ip = get_ipython()
57 57 path = 'c:\\x'
58 58 m = DummyMagics(ip)
59 59 opts = m.parse_options('-f %s' % path,'f:')[0]
60 60 # argv splitting is os-dependent
61 61 if os.name == 'posix':
62 62 expected = 'c:x'
63 63 else:
64 64 expected = path
65 65 nt.assert_equals(opts['f'], expected)
66 66
67 67
68 68 @dec.skip_without('sqlite3')
69 69 def doctest_hist_f():
70 70 """Test %hist -f with temporary filename.
71 71
72 72 In [9]: import tempfile
73 73
74 74 In [10]: tfile = tempfile.mktemp('.py','tmp-ipython-')
75 75
76 76 In [11]: %hist -nl -f $tfile 3
77 77
78 78 In [13]: import os; os.unlink(tfile)
79 79 """
80 80
81 81
82 82 @dec.skip_without('sqlite3')
83 83 def doctest_hist_r():
84 84 """Test %hist -r
85 85
86 86 XXX - This test is not recording the output correctly. For some reason, in
87 87 testing mode the raw history isn't getting populated. No idea why.
88 88 Disabling the output checking for now, though at least we do run it.
89 89
90 90 In [1]: 'hist' in _ip.lsmagic()
91 91 Out[1]: True
92 92
93 93 In [2]: x=1
94 94
95 95 In [3]: %hist -rl 2
96 96 x=1 # random
97 97 %hist -r 2
98 98 """
99 99
100 100
101 101 @dec.skip_without('sqlite3')
102 102 def doctest_hist_op():
103 103 """Test %hist -op
104 104
105 105 In [1]: class b(float):
106 106 ...: pass
107 107 ...:
108 108
109 109 In [2]: class s(object):
110 110 ...: def __str__(self):
111 111 ...: return 's'
112 112 ...:
113 113
114 114 In [3]:
115 115
116 116 In [4]: class r(b):
117 117 ...: def __repr__(self):
118 118 ...: return 'r'
119 119 ...:
120 120
121 121 In [5]: class sr(s,r): pass
122 122 ...:
123 123
124 124 In [6]:
125 125
126 126 In [7]: bb=b()
127 127
128 128 In [8]: ss=s()
129 129
130 130 In [9]: rr=r()
131 131
132 132 In [10]: ssrr=sr()
133 133
134 134 In [11]: 4.5
135 135 Out[11]: 4.5
136 136
137 137 In [12]: str(ss)
138 138 Out[12]: 's'
139 139
140 140 In [13]:
141 141
142 142 In [14]: %hist -op
143 143 >>> class b:
144 144 ... pass
145 145 ...
146 146 >>> class s(b):
147 147 ... def __str__(self):
148 148 ... return 's'
149 149 ...
150 150 >>>
151 151 >>> class r(b):
152 152 ... def __repr__(self):
153 153 ... return 'r'
154 154 ...
155 155 >>> class sr(s,r): pass
156 156 >>>
157 157 >>> bb=b()
158 158 >>> ss=s()
159 159 >>> rr=r()
160 160 >>> ssrr=sr()
161 161 >>> 4.5
162 162 4.5
163 163 >>> str(ss)
164 164 's'
165 165 >>>
166 166 """
167 167
168 168
169 169 @dec.skip_without('sqlite3')
170 170 def test_macro():
171 171 ip = get_ipython()
172 172 ip.history_manager.reset() # Clear any existing history.
173 173 cmds = ["a=1", "def b():\n return a**2", "print(a,b())"]
174 174 for i, cmd in enumerate(cmds, start=1):
175 175 ip.history_manager.store_inputs(i, cmd)
176 176 ip.magic("macro test 1-3")
177 177 nt.assert_equal(ip.user_ns["test"].value, "\n".join(cmds)+"\n")
178 178
179 179 # List macros.
180 180 assert "test" in ip.magic("macro")
181 181
182 182
183 183 @dec.skip_without('sqlite3')
184 184 def test_macro_run():
185 185 """Test that we can run a multi-line macro successfully."""
186 186 ip = get_ipython()
187 187 ip.history_manager.reset()
188 188 cmds = ["a=10", "a+=1", py3compat.doctest_refactor_print("print a"),
189 189 "%macro test 2-3"]
190 190 for cmd in cmds:
191 191 ip.run_cell(cmd, store_history=True)
192 192 nt.assert_equal(ip.user_ns["test"].value,
193 193 py3compat.doctest_refactor_print("a+=1\nprint a\n"))
194 194 with tt.AssertPrints("12"):
195 195 ip.run_cell("test")
196 196 with tt.AssertPrints("13"):
197 197 ip.run_cell("test")
198 198
199 199
200 200 @dec.skipif_not_numpy
201 201 def test_numpy_reset_array_undec():
202 202 "Test '%reset array' functionality"
203 203 _ip.ex('import numpy as np')
204 204 _ip.ex('a = np.empty(2)')
205 205 yield (nt.assert_true, 'a' in _ip.user_ns)
206 206 _ip.magic('reset -f array')
207 207 yield (nt.assert_false, 'a' in _ip.user_ns)
208 208
209 209 def test_reset_out():
210 210 "Test '%reset out' magic"
211 211 _ip.run_cell("parrot = 'dead'", store_history=True)
212 212 # test '%reset -f out', make an Out prompt
213 213 _ip.run_cell("parrot", store_history=True)
214 214 nt.assert_true('dead' in [_ip.user_ns[x] for x in '_','__','___'])
215 215 _ip.magic('reset -f out')
216 216 nt.assert_false('dead' in [_ip.user_ns[x] for x in '_','__','___'])
217 217 nt.assert_true(len(_ip.user_ns['Out']) == 0)
218 218
219 219 def test_reset_in():
220 220 "Test '%reset in' magic"
221 221 # test '%reset -f in'
222 222 _ip.run_cell("parrot", store_history=True)
223 223 nt.assert_true('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
224 224 _ip.magic('%reset -f in')
225 225 nt.assert_false('parrot' in [_ip.user_ns[x] for x in '_i','_ii','_iii'])
226 226 nt.assert_true(len(set(_ip.user_ns['In'])) == 1)
227 227
228 228 def test_reset_dhist():
229 229 "Test '%reset dhist' magic"
230 230 _ip.run_cell("tmp = [d for d in _dh]") # copy before clearing
231 231 _ip.magic('cd ' + os.path.dirname(nt.__file__))
232 232 _ip.magic('cd -')
233 233 nt.assert_true(len(_ip.user_ns['_dh']) > 0)
234 234 _ip.magic('reset -f dhist')
235 235 nt.assert_true(len(_ip.user_ns['_dh']) == 0)
236 236 _ip.run_cell("_dh = [d for d in tmp]") #restore
237 237
238 238 def test_reset_in_length():
239 239 "Test that '%reset in' preserves In[] length"
240 240 _ip.run_cell("print 'foo'")
241 241 _ip.run_cell("reset -f in")
242 242 nt.assert_true(len(_ip.user_ns['In']) == _ip.displayhook.prompt_count+1)
243 243
244 244 def test_time():
245 245 _ip.magic('time None')
246 246
247 247 def test_tb_syntaxerror():
248 248 """test %tb after a SyntaxError"""
249 249 ip = get_ipython()
250 250 ip.run_cell("for")
251 251
252 252 # trap and validate stdout
253 253 save_stdout = sys.stdout
254 254 try:
255 255 sys.stdout = StringIO()
256 256 ip.run_cell("%tb")
257 257 out = sys.stdout.getvalue()
258 258 finally:
259 259 sys.stdout = save_stdout
260 260 # trim output, and only check the last line
261 261 last_line = out.rstrip().splitlines()[-1].strip()
262 262 nt.assert_equals(last_line, "SyntaxError: invalid syntax")
263 263
264 264
265 265 @py3compat.doctest_refactor_print
266 266 def doctest_time():
267 267 """
268 268 In [10]: %time None
269 269 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
270 270 Wall time: 0.00 s
271 271
272 272 In [11]: def f(kmjy):
273 273 ....: %time print 2*kmjy
274 274
275 275 In [12]: f(3)
276 276 6
277 277 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
278 278 Wall time: 0.00 s
279 279 """
280 280
281 281
282 282 def test_doctest_mode():
283 283 "Toggle doctest_mode twice, it should be a no-op and run without error"
284 284 _ip.magic('doctest_mode')
285 285 _ip.magic('doctest_mode')
286 286
287 287
288 288 def test_parse_options():
289 289 """Tests for basic options parsing in magics."""
290 290 # These are only the most minimal of tests, more should be added later. At
291 291 # the very least we check that basic text/unicode calls work OK.
292 292 m = DummyMagics(_ip)
293 293 nt.assert_equal(m.parse_options('foo', '')[1], 'foo')
294 294 nt.assert_equal(m.parse_options(u'foo', '')[1], u'foo')
295 295
296 296
297 297 def test_dirops():
298 298 """Test various directory handling operations."""
299 299 # curpath = lambda :os.path.splitdrive(os.getcwdu())[1].replace('\\','/')
300 300 curpath = os.getcwdu
301 301 startdir = os.getcwdu()
302 302 ipdir = os.path.realpath(_ip.ipython_dir)
303 303 try:
304 304 _ip.magic('cd "%s"' % ipdir)
305 305 nt.assert_equal(curpath(), ipdir)
306 306 _ip.magic('cd -')
307 307 nt.assert_equal(curpath(), startdir)
308 308 _ip.magic('pushd "%s"' % ipdir)
309 309 nt.assert_equal(curpath(), ipdir)
310 310 _ip.magic('popd')
311 311 nt.assert_equal(curpath(), startdir)
312 312 finally:
313 313 os.chdir(startdir)
314 314
315 315
316 316 def test_xmode():
317 317 # Calling xmode three times should be a no-op
318 318 xmode = _ip.InteractiveTB.mode
319 319 for i in range(3):
320 320 _ip.magic("xmode")
321 321 nt.assert_equal(_ip.InteractiveTB.mode, xmode)
322 322
323 323 def test_reset_hard():
324 324 monitor = []
325 325 class A(object):
326 326 def __del__(self):
327 327 monitor.append(1)
328 328 def __repr__(self):
329 329 return "<A instance>"
330 330
331 331 _ip.user_ns["a"] = A()
332 332 _ip.run_cell("a")
333 333
334 334 nt.assert_equal(monitor, [])
335 335 _ip.magic("reset -f")
336 336 nt.assert_equal(monitor, [1])
337 337
338 338 class TestXdel(tt.TempFileMixin):
339 339 def test_xdel(self):
340 340 """Test that references from %run are cleared by xdel."""
341 341 src = ("class A(object):\n"
342 342 " monitor = []\n"
343 343 " def __del__(self):\n"
344 344 " self.monitor.append(1)\n"
345 345 "a = A()\n")
346 346 self.mktmp(src)
347 347 # %run creates some hidden references...
348 348 _ip.magic("run %s" % self.fname)
349 349 # ... as does the displayhook.
350 350 _ip.run_cell("a")
351 351
352 352 monitor = _ip.user_ns["A"].monitor
353 353 nt.assert_equal(monitor, [])
354 354
355 355 _ip.magic("xdel a")
356 356
357 357 # Check that a's __del__ method has been called.
358 358 nt.assert_equal(monitor, [1])
359 359
360 360 def doctest_who():
361 361 """doctest for %who
362 362
363 363 In [1]: %reset -f
364 364
365 365 In [2]: alpha = 123
366 366
367 367 In [3]: beta = 'beta'
368 368
369 369 In [4]: %who int
370 370 alpha
371 371
372 372 In [5]: %who str
373 373 beta
374 374
375 375 In [6]: %whos
376 376 Variable Type Data/Info
377 377 ----------------------------
378 378 alpha int 123
379 379 beta str beta
380 380
381 381 In [7]: %who_ls
382 382 Out[7]: ['alpha', 'beta']
383 383 """
384 384
385 385 def test_whos():
386 386 """Check that whos is protected against objects where repr() fails."""
387 387 class A(object):
388 388 def __repr__(self):
389 389 raise Exception()
390 390 _ip.user_ns['a'] = A()
391 391 _ip.magic("whos")
392 392
393 393 @py3compat.u_format
394 394 def doctest_precision():
395 395 """doctest for %precision
396 396
397 397 In [1]: f = get_ipython().display_formatter.formatters['text/plain']
398 398
399 399 In [2]: %precision 5
400 400 Out[2]: {u}'%.5f'
401 401
402 402 In [3]: f.float_format
403 403 Out[3]: {u}'%.5f'
404 404
405 405 In [4]: %precision %e
406 406 Out[4]: {u}'%e'
407 407
408 408 In [5]: f(3.1415927)
409 409 Out[5]: {u}'3.141593e+00'
410 410 """
411 411
412 412 def test_psearch():
413 413 with tt.AssertPrints("dict.fromkeys"):
414 414 _ip.run_cell("dict.fr*?")
415 415
416 416 def test_timeit_shlex():
417 417 """test shlex issues with timeit (#1109)"""
418 418 _ip.ex("def f(*a,**kw): pass")
419 419 _ip.magic('timeit -n1 "this is a bug".count(" ")')
420 420 _ip.magic('timeit -r1 -n1 f(" ", 1)')
421 421 _ip.magic('timeit -r1 -n1 f(" ", 1, " ", 2, " ")')
422 422 _ip.magic('timeit -r1 -n1 ("a " + "b")')
423 423 _ip.magic('timeit -r1 -n1 f("a " + "b")')
424 424 _ip.magic('timeit -r1 -n1 f("a " + "b ")')
425 425
426 426
427 427 def test_timeit_arguments():
428 428 "Test valid timeit arguments, should not cause SyntaxError (GH #1269)"
429 429 _ip.magic("timeit ('#')")
430 430
431 431
432 @dec.skipif(mf.profile is None)
432 @dec.skipif(execution.profile is None)
433 433 def test_prun_quotes():
434 434 "Test that prun does not clobber string escapes (GH #1302)"
435 435 _ip.magic("prun -q x = '\t'")
436 436 nt.assert_equal(_ip.user_ns['x'], '\t')
437 437
438 438 def test_extension():
439 439 tmpdir = TemporaryDirectory()
440 440 orig_ipython_dir = _ip.ipython_dir
441 441 try:
442 442 _ip.ipython_dir = tmpdir.name
443 443 nt.assert_raises(ImportError, _ip.magic, "load_ext daft_extension")
444 444 url = os.path.join(os.path.dirname(__file__), "daft_extension.py")
445 445 _ip.magic("install_ext %s" % url)
446 446 _ip.user_ns.pop('arq', None)
447 447 _ip.magic("load_ext daft_extension")
448 448 tt.assert_equal(_ip.user_ns['arq'], 185)
449 449 _ip.magic("unload_ext daft_extension")
450 450 assert 'arq' not in _ip.user_ns
451 451 finally:
452 452 _ip.ipython_dir = orig_ipython_dir
453 453
454 454 def test_notebook_export_json():
455 455 with TemporaryDirectory() as td:
456 456 outfile = os.path.join(td, "nb.ipynb")
457 457 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
458 458 _ip.magic("notebook -e %s" % outfile)
459 459
460 460 def test_notebook_export_py():
461 461 with TemporaryDirectory() as td:
462 462 outfile = os.path.join(td, "nb.py")
463 463 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
464 464 _ip.magic("notebook -e %s" % outfile)
465 465
466 466 def test_notebook_reformat_py():
467 467 with TemporaryDirectory() as td:
468 468 infile = os.path.join(td, "nb.ipynb")
469 469 with io.open(infile, 'w', encoding='utf-8') as f:
470 470 current.write(nb0, f, 'json')
471 471
472 472 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
473 473 _ip.magic("notebook -f py %s" % infile)
474 474
475 475 def test_notebook_reformat_json():
476 476 with TemporaryDirectory() as td:
477 477 infile = os.path.join(td, "nb.py")
478 478 with io.open(infile, 'w', encoding='utf-8') as f:
479 479 current.write(nb0, f, 'py')
480 480
481 481 _ip.ex(py3compat.u_format(u"u = {u}'hΓ©llo'"))
482 482 _ip.magic("notebook -f ipynb %s" % infile)
483 483 _ip.magic("notebook -f json %s" % infile)
484 484
485 485 def test_env():
486 486 env = _ip.magic("env")
487 487 assert isinstance(env, dict), type(env)
@@ -1,541 +1,540 b''
1 1 """A ZMQ-based subclass of InteractiveShell.
2 2
3 3 This code is meant to ease the refactoring of the base InteractiveShell into
4 4 something with a cleaner architecture for 2-process use, without actually
5 5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 6 we subclass and override what we want to fix. Once this is working well, we
7 7 can go back to the base class and refactor the code for a cleaner inheritance
8 8 implementation that doesn't rely on so much monkeypatching.
9 9
10 10 But this lets us maintain a fully working IPython as we develop the new
11 11 machinery. This should thus be thought of as scaffolding.
12 12 """
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib
19 19 import inspect
20 20 import os
21 21 import sys
22 22 import time
23 23 from subprocess import Popen, PIPE
24 24
25 25 # System library imports
26 26 from zmq.eventloop import ioloop
27 27
28 28 # Our own
29 29 from IPython.core.interactiveshell import (
30 30 InteractiveShell, InteractiveShellABC
31 31 )
32 32 from IPython.core import page, pylabtools
33 33 from IPython.core.autocall import ZMQExitAutocall
34 34 from IPython.core.displaypub import DisplayPublisher
35 35 from IPython.core.macro import Macro
36 from IPython.core.magic_functions import MacroToEdit
36 from IPython.core.magics import MacroToEdit
37 37 from IPython.core.payloadpage import install_payload_page
38 38 from IPython.lib.kernel import (
39 39 get_connection_file, get_connection_info, connect_qtconsole
40 40 )
41 41 from IPython.testing.skipdoctest import skip_doctest
42 42 from IPython.utils import io
43 43 from IPython.utils.jsonutil import json_clean
44 44 from IPython.utils.path import get_py_filename
45 45 from IPython.utils.process import arg_split
46 46 from IPython.utils.traitlets import Instance, Type, Dict, CBool, CBytes
47 47 from IPython.utils.warn import warn, error
48 48 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_binary
49 49 from IPython.zmq.session import extract_header
50 50 from session import Session
51 51
52
53 52 #-----------------------------------------------------------------------------
54 53 # Functions and classes
55 54 #-----------------------------------------------------------------------------
56 55
57 56 class ZMQDisplayPublisher(DisplayPublisher):
58 57 """A display publisher that publishes data using a ZeroMQ PUB socket."""
59 58
60 59 session = Instance(Session)
61 60 pub_socket = Instance('zmq.Socket')
62 61 parent_header = Dict({})
63 62 topic = CBytes(b'displaypub')
64 63
65 64 def set_parent(self, parent):
66 65 """Set the parent for outbound messages."""
67 66 self.parent_header = extract_header(parent)
68 67
69 68 def _flush_streams(self):
70 69 """flush IO Streams prior to display"""
71 70 sys.stdout.flush()
72 71 sys.stderr.flush()
73 72
74 73 def publish(self, source, data, metadata=None):
75 74 self._flush_streams()
76 75 if metadata is None:
77 76 metadata = {}
78 77 self._validate_data(source, data, metadata)
79 78 content = {}
80 79 content['source'] = source
81 80 _encode_binary(data)
82 81 content['data'] = data
83 82 content['metadata'] = metadata
84 83 self.session.send(
85 84 self.pub_socket, u'display_data', json_clean(content),
86 85 parent=self.parent_header, ident=self.topic,
87 86 )
88 87
89 88 def clear_output(self, stdout=True, stderr=True, other=True):
90 89 content = dict(stdout=stdout, stderr=stderr, other=other)
91 90
92 91 if stdout:
93 92 print('\r', file=sys.stdout, end='')
94 93 if stderr:
95 94 print('\r', file=sys.stderr, end='')
96 95
97 96 self._flush_streams()
98 97
99 98 self.session.send(
100 99 self.pub_socket, u'clear_output', content,
101 100 parent=self.parent_header, ident=self.topic,
102 101 )
103 102
104 103 class ZMQInteractiveShell(InteractiveShell):
105 104 """A subclass of InteractiveShell for ZMQ."""
106 105
107 106 displayhook_class = Type(ZMQShellDisplayHook)
108 107 display_pub_class = Type(ZMQDisplayPublisher)
109 108
110 109 # Override the traitlet in the parent class, because there's no point using
111 110 # readline for the kernel. Can be removed when the readline code is moved
112 111 # to the terminal frontend.
113 112 colors_force = CBool(True)
114 113 readline_use = CBool(False)
115 114 # autoindent has no meaning in a zmqshell, and attempting to enable it
116 115 # will print a warning in the absence of readline.
117 116 autoindent = CBool(False)
118 117
119 118 exiter = Instance(ZMQExitAutocall)
120 119 def _exiter_default(self):
121 120 return ZMQExitAutocall(self)
122 121
123 122 def _exit_now_changed(self, name, old, new):
124 123 """stop eventloop when exit_now fires"""
125 124 if new:
126 125 loop = ioloop.IOLoop.instance()
127 126 loop.add_timeout(time.time()+0.1, loop.stop)
128 127
129 128 keepkernel_on_exit = None
130 129
131 130 # Over ZeroMQ, GUI control isn't done with PyOS_InputHook as there is no
132 131 # interactive input being read; we provide event loop support in ipkernel
133 132 from .eventloops import enable_gui
134 133 enable_gui = staticmethod(enable_gui)
135 134
136 135 def init_environment(self):
137 136 """Configure the user's environment.
138 137
139 138 """
140 139 env = os.environ
141 140 # These two ensure 'ls' produces nice coloring on BSD-derived systems
142 141 env['TERM'] = 'xterm-color'
143 142 env['CLICOLOR'] = '1'
144 143 # Since normal pagers don't work at all (over pexpect we don't have
145 144 # single-key control of the subprocess), try to disable paging in
146 145 # subprocesses as much as possible.
147 146 env['PAGER'] = 'cat'
148 147 env['GIT_PAGER'] = 'cat'
149 148
150 149 # And install the payload version of page.
151 150 install_payload_page()
152 151
153 152 def auto_rewrite_input(self, cmd):
154 153 """Called to show the auto-rewritten input for autocall and friends.
155 154
156 155 FIXME: this payload is currently not correctly processed by the
157 156 frontend.
158 157 """
159 158 new = self.prompt_manager.render('rewrite') + cmd
160 159 payload = dict(
161 160 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
162 161 transformed_input=new,
163 162 )
164 163 self.payload_manager.write_payload(payload)
165 164
166 165 def ask_exit(self):
167 166 """Engage the exit actions."""
168 167 self.exit_now = True
169 168 payload = dict(
170 169 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
171 170 exit=True,
172 171 keepkernel=self.keepkernel_on_exit,
173 172 )
174 173 self.payload_manager.write_payload(payload)
175 174
176 175 def _showtraceback(self, etype, evalue, stb):
177 176
178 177 exc_content = {
179 178 u'traceback' : stb,
180 179 u'ename' : unicode(etype.__name__),
181 180 u'evalue' : unicode(evalue)
182 181 }
183 182
184 183 dh = self.displayhook
185 184 # Send exception info over pub socket for other clients than the caller
186 185 # to pick up
187 186 topic = None
188 187 if dh.topic:
189 188 topic = dh.topic.replace(b'pyout', b'pyerr')
190 189
191 190 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', json_clean(exc_content), dh.parent_header, ident=topic)
192 191
193 192 # FIXME - Hack: store exception info in shell object. Right now, the
194 193 # caller is reading this info after the fact, we need to fix this logic
195 194 # to remove this hack. Even uglier, we need to store the error status
196 195 # here, because in the main loop, the logic that sets it is being
197 196 # skipped because runlines swallows the exceptions.
198 197 exc_content[u'status'] = u'error'
199 198 self._reply_content = exc_content
200 199 # /FIXME
201 200
202 201 return exc_content
203 202
204 203 #------------------------------------------------------------------------
205 204 # Magic overrides
206 205 #------------------------------------------------------------------------
207 206 # Once the base class stops inheriting from magic, this code needs to be
208 207 # moved into a separate machinery as well. For now, at least isolate here
209 208 # the magics which this class needs to implement differently from the base
210 209 # class, or that are unique to it.
211 210
212 211 def magic_doctest_mode(self,parameter_s=''):
213 212 """Toggle doctest mode on and off.
214 213
215 214 This mode is intended to make IPython behave as much as possible like a
216 215 plain Python shell, from the perspective of how its prompts, exceptions
217 216 and output look. This makes it easy to copy and paste parts of a
218 217 session into doctests. It does so by:
219 218
220 219 - Changing the prompts to the classic ``>>>`` ones.
221 220 - Changing the exception reporting mode to 'Plain'.
222 221 - Disabling pretty-printing of output.
223 222
224 223 Note that IPython also supports the pasting of code snippets that have
225 224 leading '>>>' and '...' prompts in them. This means that you can paste
226 225 doctests from files or docstrings (even if they have leading
227 226 whitespace), and the code will execute correctly. You can then use
228 227 '%history -t' to see the translated history; this will give you the
229 228 input after removal of all the leading prompts and whitespace, which
230 229 can be pasted back into an editor.
231 230
232 231 With these features, you can switch into this mode easily whenever you
233 232 need to do testing and changes to doctests, without having to leave
234 233 your existing IPython session.
235 234 """
236 235
237 236 from IPython.utils.ipstruct import Struct
238 237
239 238 # Shorthands
240 239 shell = self.shell
241 240 disp_formatter = self.shell.display_formatter
242 241 ptformatter = disp_formatter.formatters['text/plain']
243 242 # dstore is a data store kept in the instance metadata bag to track any
244 243 # changes we make, so we can undo them later.
245 244 dstore = shell.meta.setdefault('doctest_mode', Struct())
246 245 save_dstore = dstore.setdefault
247 246
248 247 # save a few values we'll need to recover later
249 248 mode = save_dstore('mode', False)
250 249 save_dstore('rc_pprint', ptformatter.pprint)
251 250 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
252 251 save_dstore('xmode', shell.InteractiveTB.mode)
253 252
254 253 if mode == False:
255 254 # turn on
256 255 ptformatter.pprint = False
257 256 disp_formatter.plain_text_only = True
258 257 shell.magic_xmode('Plain')
259 258 else:
260 259 # turn off
261 260 ptformatter.pprint = dstore.rc_pprint
262 261 disp_formatter.plain_text_only = dstore.rc_plain_text_only
263 262 shell.magic_xmode(dstore.xmode)
264 263
265 264 # Store new mode and inform on console
266 265 dstore.mode = bool(1-int(mode))
267 266 mode_label = ['OFF','ON'][dstore.mode]
268 267 print('Doctest mode is:', mode_label)
269 268
270 269 # Send the payload back so that clients can modify their prompt display
271 270 payload = dict(
272 271 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
273 272 mode=dstore.mode)
274 273 self.payload_manager.write_payload(payload)
275 274
276 275 @skip_doctest
277 276 def magic_edit(self,parameter_s='',last_call=['','']):
278 277 """Bring up an editor and execute the resulting code.
279 278
280 279 Usage:
281 280 %edit [options] [args]
282 281
283 282 %edit runs an external text editor. You will need to set the command for
284 283 this editor via the ``TerminalInteractiveShell.editor`` option in your
285 284 configuration file before it will work.
286 285
287 286 This command allows you to conveniently edit multi-line code right in
288 287 your IPython session.
289 288
290 289 If called without arguments, %edit opens up an empty editor with a
291 290 temporary file and will execute the contents of this file when you
292 291 close it (don't forget to save it!).
293 292
294 293
295 294 Options:
296 295
297 296 -n <number>: open the editor at a specified line number. By default,
298 297 the IPython editor hook uses the unix syntax 'editor +N filename', but
299 298 you can configure this by providing your own modified hook if your
300 299 favorite editor supports line-number specifications with a different
301 300 syntax.
302 301
303 302 -p: this will call the editor with the same data as the previous time
304 303 it was used, regardless of how long ago (in your current session) it
305 304 was.
306 305
307 306 -r: use 'raw' input. This option only applies to input taken from the
308 307 user's history. By default, the 'processed' history is used, so that
309 308 magics are loaded in their transformed version to valid Python. If
310 309 this option is given, the raw input as typed as the command line is
311 310 used instead. When you exit the editor, it will be executed by
312 311 IPython's own processor.
313 312
314 313 -x: do not execute the edited code immediately upon exit. This is
315 314 mainly useful if you are editing programs which need to be called with
316 315 command line arguments, which you can then do using %run.
317 316
318 317
319 318 Arguments:
320 319
321 320 If arguments are given, the following possibilites exist:
322 321
323 322 - The arguments are numbers or pairs of colon-separated numbers (like
324 323 1 4:8 9). These are interpreted as lines of previous input to be
325 324 loaded into the editor. The syntax is the same of the %macro command.
326 325
327 326 - If the argument doesn't start with a number, it is evaluated as a
328 327 variable and its contents loaded into the editor. You can thus edit
329 328 any string which contains python code (including the result of
330 329 previous edits).
331 330
332 331 - If the argument is the name of an object (other than a string),
333 332 IPython will try to locate the file where it was defined and open the
334 333 editor at the point where it is defined. You can use `%edit function`
335 334 to load an editor exactly at the point where 'function' is defined,
336 335 edit it and have the file be executed automatically.
337 336
338 337 If the object is a macro (see %macro for details), this opens up your
339 338 specified editor with a temporary file containing the macro's data.
340 339 Upon exit, the macro is reloaded with the contents of the file.
341 340
342 341 Note: opening at an exact line is only supported under Unix, and some
343 342 editors (like kedit and gedit up to Gnome 2.8) do not understand the
344 343 '+NUMBER' parameter necessary for this feature. Good editors like
345 344 (X)Emacs, vi, jed, pico and joe all do.
346 345
347 346 - If the argument is not found as a variable, IPython will look for a
348 347 file with that name (adding .py if necessary) and load it into the
349 348 editor. It will execute its contents with execfile() when you exit,
350 349 loading any code in the file into your interactive namespace.
351 350
352 351 After executing your code, %edit will return as output the code you
353 352 typed in the editor (except when it was an existing file). This way
354 353 you can reload the code in further invocations of %edit as a variable,
355 354 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
356 355 the output.
357 356
358 357 Note that %edit is also available through the alias %ed.
359 358
360 359 This is an example of creating a simple function inside the editor and
361 360 then modifying it. First, start up the editor:
362 361
363 362 In [1]: ed
364 363 Editing... done. Executing edited code...
365 364 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
366 365
367 366 We can then call the function foo():
368 367
369 368 In [2]: foo()
370 369 foo() was defined in an editing session
371 370
372 371 Now we edit foo. IPython automatically loads the editor with the
373 372 (temporary) file where foo() was previously defined:
374 373
375 374 In [3]: ed foo
376 375 Editing... done. Executing edited code...
377 376
378 377 And if we call foo() again we get the modified version:
379 378
380 379 In [4]: foo()
381 380 foo() has now been changed!
382 381
383 382 Here is an example of how to edit a code snippet successive
384 383 times. First we call the editor:
385 384
386 385 In [5]: ed
387 386 Editing... done. Executing edited code...
388 387 hello
389 388 Out[5]: "print 'hello'n"
390 389
391 390 Now we call it again with the previous output (stored in _):
392 391
393 392 In [6]: ed _
394 393 Editing... done. Executing edited code...
395 394 hello world
396 395 Out[6]: "print 'hello world'n"
397 396
398 397 Now we call it with the output #8 (stored in _8, also as Out[8]):
399 398
400 399 In [7]: ed _8
401 400 Editing... done. Executing edited code...
402 401 hello again
403 402 Out[7]: "print 'hello again'n"
404 403 """
405 404
406 405 opts,args = self.parse_options(parameter_s,'prn:')
407 406
408 407 try:
409 408 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
410 409 except MacroToEdit as e:
411 410 # TODO: Implement macro editing over 2 processes.
412 411 print("Macro editing not yet implemented in 2-process model.")
413 412 return
414 413
415 414 # Make sure we send to the client an absolute path, in case the working
416 415 # directory of client and kernel don't match
417 416 filename = os.path.abspath(filename)
418 417
419 418 payload = {
420 419 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
421 420 'filename' : filename,
422 421 'line_number' : lineno
423 422 }
424 423 self.payload_manager.write_payload(payload)
425 424
426 425 # A few magics that are adapted to the specifics of using pexpect and a
427 426 # remote terminal
428 427
429 428 def magic_clear(self, arg_s):
430 429 """Clear the terminal."""
431 430 if os.name == 'posix':
432 431 self.shell.system("clear")
433 432 else:
434 433 self.shell.system("cls")
435 434
436 435 if os.name == 'nt':
437 436 # This is the usual name in windows
438 437 magic_cls = magic_clear
439 438
440 439 # Terminal pagers won't work over pexpect, but we do have our own pager
441 440
442 441 def magic_less(self, arg_s):
443 442 """Show a file through the pager.
444 443
445 444 Files ending in .py are syntax-highlighted."""
446 445 cont = open(arg_s).read()
447 446 if arg_s.endswith('.py'):
448 447 cont = self.shell.pycolorize(cont)
449 448 page.page(cont)
450 449
451 450 magic_more = magic_less
452 451
453 452 # Man calls a pager, so we also need to redefine it
454 453 if os.name == 'posix':
455 454 def magic_man(self, arg_s):
456 455 """Find the man page for the given command and display in pager."""
457 456 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
458 457 split=False))
459 458
460 459 # FIXME: this is specific to the GUI, so we should let the gui app load
461 460 # magics at startup that are only for the gui. Once the gui app has proper
462 461 # profile and configuration management, we can have it initialize a kernel
463 462 # with a special config file that provides these.
464 463 def magic_guiref(self, arg_s):
465 464 """Show a basic reference about the GUI console."""
466 465 from IPython.core.usage import gui_reference
467 466 page.page(gui_reference, auto_html=True)
468 467
469 468 def magic_connect_info(self, arg_s):
470 469 """Print information for connecting other clients to this kernel
471 470
472 471 It will print the contents of this session's connection file, as well as
473 472 shortcuts for local clients.
474 473
475 474 In the simplest case, when called from the most recently launched kernel,
476 475 secondary clients can be connected, simply with:
477 476
478 477 $> ipython <app> --existing
479 478
480 479 """
481 480
482 481 from IPython.core.application import BaseIPythonApplication as BaseIPApp
483 482
484 483 if BaseIPApp.initialized():
485 484 app = BaseIPApp.instance()
486 485 security_dir = app.profile_dir.security_dir
487 486 profile = app.profile
488 487 else:
489 488 profile = 'default'
490 489 security_dir = ''
491 490
492 491 try:
493 492 connection_file = get_connection_file()
494 493 info = get_connection_info(unpack=False)
495 494 except Exception as e:
496 495 error("Could not get connection info: %r" % e)
497 496 return
498 497
499 498 # add profile flag for non-default profile
500 499 profile_flag = "--profile %s" % profile if profile != 'default' else ""
501 500
502 501 # if it's in the security dir, truncate to basename
503 502 if security_dir == os.path.dirname(connection_file):
504 503 connection_file = os.path.basename(connection_file)
505 504
506 505
507 506 print (info + '\n')
508 507 print ("Paste the above JSON into a file, and connect with:\n"
509 508 " $> ipython <app> --existing <file>\n"
510 509 "or, if you are local, you can connect with just:\n"
511 510 " $> ipython <app> --existing {0} {1}\n"
512 511 "or even just:\n"
513 512 " $> ipython <app> --existing {1}\n"
514 513 "if this is the most recent IPython session you have started.".format(
515 514 connection_file, profile_flag
516 515 )
517 516 )
518 517
519 518 def magic_qtconsole(self, arg_s):
520 519 """Open a qtconsole connected to this kernel.
521 520
522 521 Useful for connecting a qtconsole to running notebooks, for better
523 522 debugging.
524 523 """
525 524 try:
526 525 p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix'))
527 526 except Exception as e:
528 527 error("Could not start qtconsole: %r" % e)
529 528 return
530 529
531 530 def set_next_input(self, text):
532 531 """Send the specified text to the frontend to be presented at the next
533 532 input cell."""
534 533 payload = dict(
535 534 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
536 535 text=text
537 536 )
538 537 self.payload_manager.write_payload(payload)
539 538
540 539
541 540 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now