##// END OF EJS Templates
Print correct error message if user types in %gui in the zmq shell.
Fernando Perez -
Show More
@@ -1,457 +1,457 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
22 22 # Our own
23 23 from IPython.core.interactiveshell import (
24 24 InteractiveShell, InteractiveShellABC
25 25 )
26 26 from IPython.core import page
27 27 from IPython.core.autocall import ZMQExitAutocall
28 28 from IPython.core.displaypub import DisplayPublisher
29 29 from IPython.core.macro import Macro
30 30 from IPython.core.magic import MacroToEdit
31 31 from IPython.core.payloadpage import install_payload_page
32 32 from IPython.utils import io
33 33 from IPython.utils.path import get_py_filename
34 34 from IPython.utils.traitlets import Instance, Type, Dict, CBool
35 35 from IPython.utils.warn import warn
36 36 from IPython.zmq.displayhook import ZMQShellDisplayHook, _encode_png
37 37 from IPython.zmq.session import extract_header
38 38 from session import Session
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Globals and side-effects
42 42 #-----------------------------------------------------------------------------
43 43
44 44 # Install the payload version of page.
45 45 install_payload_page()
46 46
47 47 #-----------------------------------------------------------------------------
48 48 # Functions and classes
49 49 #-----------------------------------------------------------------------------
50 50
51 51 class ZMQDisplayPublisher(DisplayPublisher):
52 52 """A display publisher that publishes data using a ZeroMQ PUB socket."""
53 53
54 54 session = Instance(Session)
55 55 pub_socket = Instance('zmq.Socket')
56 56 parent_header = Dict({})
57 57
58 58 def set_parent(self, parent):
59 59 """Set the parent for outbound messages."""
60 60 self.parent_header = extract_header(parent)
61 61
62 62 def publish(self, source, data, metadata=None):
63 63 if metadata is None:
64 64 metadata = {}
65 65 self._validate_data(source, data, metadata)
66 66 content = {}
67 67 content['source'] = source
68 68 _encode_png(data)
69 69 content['data'] = data
70 70 content['metadata'] = metadata
71 71 self.session.send(
72 72 self.pub_socket, u'display_data', content,
73 73 parent=self.parent_header
74 74 )
75 75
76 76
77 77 class ZMQInteractiveShell(InteractiveShell):
78 78 """A subclass of InteractiveShell for ZMQ."""
79 79
80 80 displayhook_class = Type(ZMQShellDisplayHook)
81 81 display_pub_class = Type(ZMQDisplayPublisher)
82 82
83 83 # Override the traitlet in the parent class, because there's no point using
84 84 # readline for the kernel. Can be removed when the readline code is moved
85 85 # to the terminal frontend.
86 86
87 87 # FIXME. This is disabled for now, even though it may cause problems under
88 88 # Windows, because it breaks %run in the Qt console. See gh-617 for more
89 89 # details. Re-enable once we've fully tested that %run works in the Qt
90 90 # console with syntax highlighting in tracebacks.
91 91 # readline_use = CBool(False)
92 92 # /FIXME
93 93
94 94 exiter = Instance(ZMQExitAutocall)
95 95 def _exiter_default(self):
96 96 return ZMQExitAutocall(self)
97 97
98 98 keepkernel_on_exit = None
99 99
100 100 def init_environment(self):
101 101 """Configure the user's environment.
102 102
103 103 """
104 104 env = os.environ
105 105 # These two ensure 'ls' produces nice coloring on BSD-derived systems
106 106 env['TERM'] = 'xterm-color'
107 107 env['CLICOLOR'] = '1'
108 108 # Since normal pagers don't work at all (over pexpect we don't have
109 109 # single-key control of the subprocess), try to disable paging in
110 110 # subprocesses as much as possible.
111 111 env['PAGER'] = 'cat'
112 112 env['GIT_PAGER'] = 'cat'
113 113
114 114 def auto_rewrite_input(self, cmd):
115 115 """Called to show the auto-rewritten input for autocall and friends.
116 116
117 117 FIXME: this payload is currently not correctly processed by the
118 118 frontend.
119 119 """
120 120 new = self.displayhook.prompt1.auto_rewrite() + cmd
121 121 payload = dict(
122 122 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
123 123 transformed_input=new,
124 124 )
125 125 self.payload_manager.write_payload(payload)
126 126
127 127 def ask_exit(self):
128 128 """Engage the exit actions."""
129 129 payload = dict(
130 130 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
131 131 exit=True,
132 132 keepkernel=self.keepkernel_on_exit,
133 133 )
134 134 self.payload_manager.write_payload(payload)
135 135
136 136 def _showtraceback(self, etype, evalue, stb):
137 137
138 138 exc_content = {
139 139 u'traceback' : stb,
140 140 u'ename' : unicode(etype.__name__),
141 141 u'evalue' : unicode(evalue)
142 142 }
143 143
144 144 dh = self.displayhook
145 145 # Send exception info over pub socket for other clients than the caller
146 146 # to pick up
147 147 exc_msg = dh.session.send(dh.pub_socket, u'pyerr', exc_content, dh.parent_header)
148 148
149 149 # FIXME - Hack: store exception info in shell object. Right now, the
150 150 # caller is reading this info after the fact, we need to fix this logic
151 151 # to remove this hack. Even uglier, we need to store the error status
152 152 # here, because in the main loop, the logic that sets it is being
153 153 # skipped because runlines swallows the exceptions.
154 154 exc_content[u'status'] = u'error'
155 155 self._reply_content = exc_content
156 156 # /FIXME
157 157
158 158 return exc_content
159 159
160 160 #------------------------------------------------------------------------
161 161 # Magic overrides
162 162 #------------------------------------------------------------------------
163 163 # Once the base class stops inheriting from magic, this code needs to be
164 164 # moved into a separate machinery as well. For now, at least isolate here
165 165 # the magics which this class needs to implement differently from the base
166 166 # class, or that are unique to it.
167 167
168 168 def magic_doctest_mode(self,parameter_s=''):
169 169 """Toggle doctest mode on and off.
170 170
171 171 This mode is intended to make IPython behave as much as possible like a
172 172 plain Python shell, from the perspective of how its prompts, exceptions
173 173 and output look. This makes it easy to copy and paste parts of a
174 174 session into doctests. It does so by:
175 175
176 176 - Changing the prompts to the classic ``>>>`` ones.
177 177 - Changing the exception reporting mode to 'Plain'.
178 178 - Disabling pretty-printing of output.
179 179
180 180 Note that IPython also supports the pasting of code snippets that have
181 181 leading '>>>' and '...' prompts in them. This means that you can paste
182 182 doctests from files or docstrings (even if they have leading
183 183 whitespace), and the code will execute correctly. You can then use
184 184 '%history -t' to see the translated history; this will give you the
185 185 input after removal of all the leading prompts and whitespace, which
186 186 can be pasted back into an editor.
187 187
188 188 With these features, you can switch into this mode easily whenever you
189 189 need to do testing and changes to doctests, without having to leave
190 190 your existing IPython session.
191 191 """
192 192
193 193 from IPython.utils.ipstruct import Struct
194 194
195 195 # Shorthands
196 196 shell = self.shell
197 197 disp_formatter = self.shell.display_formatter
198 198 ptformatter = disp_formatter.formatters['text/plain']
199 199 # dstore is a data store kept in the instance metadata bag to track any
200 200 # changes we make, so we can undo them later.
201 201 dstore = shell.meta.setdefault('doctest_mode', Struct())
202 202 save_dstore = dstore.setdefault
203 203
204 204 # save a few values we'll need to recover later
205 205 mode = save_dstore('mode', False)
206 206 save_dstore('rc_pprint', ptformatter.pprint)
207 207 save_dstore('rc_plain_text_only',disp_formatter.plain_text_only)
208 208 save_dstore('xmode', shell.InteractiveTB.mode)
209 209
210 210 if mode == False:
211 211 # turn on
212 212 ptformatter.pprint = False
213 213 disp_formatter.plain_text_only = True
214 214 shell.magic_xmode('Plain')
215 215 else:
216 216 # turn off
217 217 ptformatter.pprint = dstore.rc_pprint
218 218 disp_formatter.plain_text_only = dstore.rc_plain_text_only
219 219 shell.magic_xmode(dstore.xmode)
220 220
221 221 # Store new mode and inform on console
222 222 dstore.mode = bool(1-int(mode))
223 223 mode_label = ['OFF','ON'][dstore.mode]
224 224 print('Doctest mode is:', mode_label)
225 225
226 226 # Send the payload back so that clients can modify their prompt display
227 227 payload = dict(
228 228 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
229 229 mode=dstore.mode)
230 230 self.payload_manager.write_payload(payload)
231 231
232 232 def magic_edit(self,parameter_s='',last_call=['','']):
233 233 """Bring up an editor and execute the resulting code.
234 234
235 235 Usage:
236 236 %edit [options] [args]
237 237
238 238 %edit runs IPython's editor hook. The default version of this hook is
239 239 set to call the __IPYTHON__.rc.editor command. This is read from your
240 240 environment variable $EDITOR. If this isn't found, it will default to
241 241 vi under Linux/Unix and to notepad under Windows. See the end of this
242 242 docstring for how to change the editor hook.
243 243
244 244 You can also set the value of this editor via the command line option
245 245 '-editor' or in your ipythonrc file. This is useful if you wish to use
246 246 specifically for IPython an editor different from your typical default
247 247 (and for Windows users who typically don't set environment variables).
248 248
249 249 This command allows you to conveniently edit multi-line code right in
250 250 your IPython session.
251 251
252 252 If called without arguments, %edit opens up an empty editor with a
253 253 temporary file and will execute the contents of this file when you
254 254 close it (don't forget to save it!).
255 255
256 256
257 257 Options:
258 258
259 259 -n <number>: open the editor at a specified line number. By default,
260 260 the IPython editor hook uses the unix syntax 'editor +N filename', but
261 261 you can configure this by providing your own modified hook if your
262 262 favorite editor supports line-number specifications with a different
263 263 syntax.
264 264
265 265 -p: this will call the editor with the same data as the previous time
266 266 it was used, regardless of how long ago (in your current session) it
267 267 was.
268 268
269 269 -r: use 'raw' input. This option only applies to input taken from the
270 270 user's history. By default, the 'processed' history is used, so that
271 271 magics are loaded in their transformed version to valid Python. If
272 272 this option is given, the raw input as typed as the command line is
273 273 used instead. When you exit the editor, it will be executed by
274 274 IPython's own processor.
275 275
276 276 -x: do not execute the edited code immediately upon exit. This is
277 277 mainly useful if you are editing programs which need to be called with
278 278 command line arguments, which you can then do using %run.
279 279
280 280
281 281 Arguments:
282 282
283 283 If arguments are given, the following possibilites exist:
284 284
285 285 - The arguments are numbers or pairs of colon-separated numbers (like
286 286 1 4:8 9). These are interpreted as lines of previous input to be
287 287 loaded into the editor. The syntax is the same of the %macro command.
288 288
289 289 - If the argument doesn't start with a number, it is evaluated as a
290 290 variable and its contents loaded into the editor. You can thus edit
291 291 any string which contains python code (including the result of
292 292 previous edits).
293 293
294 294 - If the argument is the name of an object (other than a string),
295 295 IPython will try to locate the file where it was defined and open the
296 296 editor at the point where it is defined. You can use `%edit function`
297 297 to load an editor exactly at the point where 'function' is defined,
298 298 edit it and have the file be executed automatically.
299 299
300 300 If the object is a macro (see %macro for details), this opens up your
301 301 specified editor with a temporary file containing the macro's data.
302 302 Upon exit, the macro is reloaded with the contents of the file.
303 303
304 304 Note: opening at an exact line is only supported under Unix, and some
305 305 editors (like kedit and gedit up to Gnome 2.8) do not understand the
306 306 '+NUMBER' parameter necessary for this feature. Good editors like
307 307 (X)Emacs, vi, jed, pico and joe all do.
308 308
309 309 - If the argument is not found as a variable, IPython will look for a
310 310 file with that name (adding .py if necessary) and load it into the
311 311 editor. It will execute its contents with execfile() when you exit,
312 312 loading any code in the file into your interactive namespace.
313 313
314 314 After executing your code, %edit will return as output the code you
315 315 typed in the editor (except when it was an existing file). This way
316 316 you can reload the code in further invocations of %edit as a variable,
317 317 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
318 318 the output.
319 319
320 320 Note that %edit is also available through the alias %ed.
321 321
322 322 This is an example of creating a simple function inside the editor and
323 323 then modifying it. First, start up the editor:
324 324
325 325 In [1]: ed
326 326 Editing... done. Executing edited code...
327 327 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
328 328
329 329 We can then call the function foo():
330 330
331 331 In [2]: foo()
332 332 foo() was defined in an editing session
333 333
334 334 Now we edit foo. IPython automatically loads the editor with the
335 335 (temporary) file where foo() was previously defined:
336 336
337 337 In [3]: ed foo
338 338 Editing... done. Executing edited code...
339 339
340 340 And if we call foo() again we get the modified version:
341 341
342 342 In [4]: foo()
343 343 foo() has now been changed!
344 344
345 345 Here is an example of how to edit a code snippet successive
346 346 times. First we call the editor:
347 347
348 348 In [5]: ed
349 349 Editing... done. Executing edited code...
350 350 hello
351 351 Out[5]: "print 'hello'n"
352 352
353 353 Now we call it again with the previous output (stored in _):
354 354
355 355 In [6]: ed _
356 356 Editing... done. Executing edited code...
357 357 hello world
358 358 Out[6]: "print 'hello world'n"
359 359
360 360 Now we call it with the output #8 (stored in _8, also as Out[8]):
361 361
362 362 In [7]: ed _8
363 363 Editing... done. Executing edited code...
364 364 hello again
365 365 Out[7]: "print 'hello again'n"
366 366
367 367
368 368 Changing the default editor hook:
369 369
370 370 If you wish to write your own editor hook, you can put it in a
371 371 configuration file which you load at startup time. The default hook
372 372 is defined in the IPython.core.hooks module, and you can use that as a
373 373 starting example for further modifications. That file also has
374 374 general instructions on how to set a new hook for use once you've
375 375 defined it."""
376 376
377 377 opts,args = self.parse_options(parameter_s,'prn:')
378 378
379 379 try:
380 380 filename, lineno, _ = self._find_edit_target(args, opts, last_call)
381 381 except MacroToEdit as e:
382 382 # TODO: Implement macro editing over 2 processes.
383 383 print("Macro editing not yet implemented in 2-process model.")
384 384 return
385 385
386 386 # Make sure we send to the client an absolute path, in case the working
387 387 # directory of client and kernel don't match
388 388 filename = os.path.abspath(filename)
389 389
390 390 payload = {
391 391 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
392 392 'filename' : filename,
393 393 'line_number' : lineno
394 394 }
395 395 self.payload_manager.write_payload(payload)
396 396
397 397 def magic_gui(self, *args, **kwargs):
398 398 raise NotImplementedError(
399 'GUI support must be enabled in command line options.')
399 'Kernel GUI support is not implemented yet, except for --pylab.')
400 400
401 401 def magic_pylab(self, *args, **kwargs):
402 402 raise NotImplementedError(
403 403 'pylab support must be enabled in command line options.')
404 404
405 405 # A few magics that are adapted to the specifics of using pexpect and a
406 406 # remote terminal
407 407
408 408 def magic_clear(self, arg_s):
409 409 """Clear the terminal."""
410 410 if os.name == 'posix':
411 411 self.shell.system("clear")
412 412 else:
413 413 self.shell.system("cls")
414 414
415 415 if os.name == 'nt':
416 416 # This is the usual name in windows
417 417 magic_cls = magic_clear
418 418
419 419 # Terminal pagers won't work over pexpect, but we do have our own pager
420 420
421 421 def magic_less(self, arg_s):
422 422 """Show a file through the pager.
423 423
424 424 Files ending in .py are syntax-highlighted."""
425 425 cont = open(arg_s).read()
426 426 if arg_s.endswith('.py'):
427 427 cont = self.shell.pycolorize(cont)
428 428 page.page(cont)
429 429
430 430 magic_more = magic_less
431 431
432 432 # Man calls a pager, so we also need to redefine it
433 433 if os.name == 'posix':
434 434 def magic_man(self, arg_s):
435 435 """Find the man page for the given command and display in pager."""
436 436 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
437 437 split=False))
438 438
439 439 # FIXME: this is specific to the GUI, so we should let the gui app load
440 440 # magics at startup that are only for the gui. Once the gui app has proper
441 441 # profile and configuration management, we can have it initialize a kernel
442 442 # with a special config file that provides these.
443 443 def magic_guiref(self, arg_s):
444 444 """Show a basic reference about the GUI console."""
445 445 from IPython.core.usage import gui_reference
446 446 page.page(gui_reference, auto_html=True)
447 447
448 448 def set_next_input(self, text):
449 449 """Send the specified text to the frontend to be presented at the next
450 450 input cell."""
451 451 payload = dict(
452 452 source='IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input',
453 453 text=text
454 454 )
455 455 self.payload_manager.write_payload(payload)
456 456
457 457 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now