##// END OF EJS Templates
ENH: Extend the DisplayHook.compute_result_repr() and write_result_repr() methods to produce and consume the lists of extra formats. Use this capability in the ZMQ shell. Document the extension to the messaging format.
Robert Kern -
Show More
@@ -1,291 +1,301 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Displayhook for IPython.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2008-2010 The IPython Development Team
12 12 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 import __builtin__
23 23
24 24 from IPython.config.configurable import Configurable
25 25 from IPython.core import prompts
26 26 import IPython.utils.generics
27 27 import IPython.utils.io
28 28 from IPython.utils.traitlets import Instance, List
29 29 from IPython.utils.warn import warn
30 30 from IPython.core.formatters import DefaultFormatter
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Main displayhook class
34 34 #-----------------------------------------------------------------------------
35 35
36 36 # TODO: The DisplayHook class should be split into two classes, one that
37 37 # manages the prompts and their synchronization and another that just does the
38 38 # displayhook logic and calls into the prompt manager.
39 39
40 40 # TODO: Move the various attributes (cache_size, colors, input_sep,
41 41 # output_sep, output_sep2, ps1, ps2, ps_out, pad_left). Some of these are also
42 42 # attributes of InteractiveShell. They should be on ONE object only and the
43 43 # other objects should ask that one object for their values.
44 44
45 45 class DisplayHook(Configurable):
46 46 """The custom IPython displayhook to replace sys.displayhook.
47 47
48 48 This class does many things, but the basic idea is that it is a callable
49 49 that gets called anytime user code returns a value.
50 50
51 51 Currently this class does more than just the displayhook logic and that
52 52 extra logic should eventually be moved out of here.
53 53 """
54 54
55 55 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
56 56
57 57 # The default formatter.
58 58 default_formatter = Instance('IPython.core.formatters.FormatterABC')
59 59 def _default_formatter_default(self):
60 60 # FIXME: backwards compatibility for the InteractiveShell.pprint option?
61 61 return DefaultFormatter(config=self.config)
62 62
63 63 # Any additional FormatterABC instances we use.
64 64 # FIXME: currently unused.
65 65 extra_formatters = List(config=True)
66 66
67 67 # Each call to the In[] prompt raises it by 1, even the first.
68 68 #prompt_count = Int(0)
69 69
70 70 def __init__(self, shell=None, cache_size=1000,
71 71 colors='NoColor', input_sep='\n',
72 72 output_sep='\n', output_sep2='',
73 73 ps1 = None, ps2 = None, ps_out = None, pad_left=True,
74 74 config=None):
75 75 super(DisplayHook, self).__init__(shell=shell, config=config)
76 76
77 77 cache_size_min = 3
78 78 if cache_size <= 0:
79 79 self.do_full_cache = 0
80 80 cache_size = 0
81 81 elif cache_size < cache_size_min:
82 82 self.do_full_cache = 0
83 83 cache_size = 0
84 84 warn('caching was disabled (min value for cache size is %s).' %
85 85 cache_size_min,level=3)
86 86 else:
87 87 self.do_full_cache = 1
88 88
89 89 self.cache_size = cache_size
90 90 self.input_sep = input_sep
91 91
92 92 # we need a reference to the user-level namespace
93 93 self.shell = shell
94 94
95 95 # Set input prompt strings and colors
96 96 if cache_size == 0:
97 97 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
98 98 or ps1.find(r'\N') > -1:
99 99 ps1 = '>>> '
100 100 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
101 101 or ps2.find(r'\N') > -1:
102 102 ps2 = '... '
103 103 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
104 104 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
105 105 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
106 106
107 107 self.color_table = prompts.PromptColors
108 108 self.prompt1 = prompts.Prompt1(self,sep=input_sep,prompt=self.ps1_str,
109 109 pad_left=pad_left)
110 110 self.prompt2 = prompts.Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
111 111 self.prompt_out = prompts.PromptOut(self,sep='',prompt=self.ps_out_str,
112 112 pad_left=pad_left)
113 113 self.set_colors(colors)
114 114
115 115 # Store the last prompt string each time, we need it for aligning
116 116 # continuation and auto-rewrite prompts
117 117 self.last_prompt = ''
118 118 self.output_sep = output_sep
119 119 self.output_sep2 = output_sep2
120 120 self._,self.__,self.___ = '','',''
121 121
122 122 # these are deliberately global:
123 123 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
124 124 self.shell.user_ns.update(to_user_ns)
125 125
126 126 @property
127 127 def prompt_count(self):
128 128 return self.shell.execution_count
129 129
130 130 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
131 131 if p_str is None:
132 132 if self.do_full_cache:
133 133 return cache_def
134 134 else:
135 135 return no_cache_def
136 136 else:
137 137 return p_str
138 138
139 139 def set_colors(self, colors):
140 140 """Set the active color scheme and configure colors for the three
141 141 prompt subsystems."""
142 142
143 143 # FIXME: This modifying of the global prompts.prompt_specials needs
144 144 # to be fixed. We need to refactor all of the prompts stuff to use
145 145 # proper configuration and traits notifications.
146 146 if colors.lower()=='nocolor':
147 147 prompts.prompt_specials = prompts.prompt_specials_nocolor
148 148 else:
149 149 prompts.prompt_specials = prompts.prompt_specials_color
150 150
151 151 self.color_table.set_active_scheme(colors)
152 152 self.prompt1.set_colors()
153 153 self.prompt2.set_colors()
154 154 self.prompt_out.set_colors()
155 155
156 156 #-------------------------------------------------------------------------
157 157 # Methods used in __call__. Override these methods to modify the behavior
158 158 # of the displayhook.
159 159 #-------------------------------------------------------------------------
160 160
161 161 def check_for_underscore(self):
162 162 """Check if the user has set the '_' variable by hand."""
163 163 # If something injected a '_' variable in __builtin__, delete
164 164 # ipython's automatic one so we don't clobber that. gettext() in
165 165 # particular uses _, so we need to stay away from it.
166 166 if '_' in __builtin__.__dict__:
167 167 try:
168 168 del self.shell.user_ns['_']
169 169 except KeyError:
170 170 pass
171 171
172 172 def quiet(self):
173 173 """Should we silence the display hook because of ';'?"""
174 174 # do not print output if input ends in ';'
175 175 try:
176 176 if self.shell.input_hist[self.prompt_count].endswith(';\n'):
177 177 return True
178 178 except IndexError:
179 179 # some uses of ipshellembed may fail here
180 180 pass
181 181 return False
182 182
183 183 def start_displayhook(self):
184 184 """Start the displayhook, initializing resources."""
185 185 pass
186 186
187 187 def write_output_prompt(self):
188 188 """Write the output prompt."""
189 189 # Use write, not print which adds an extra space.
190 190 IPython.utils.io.Term.cout.write(self.output_sep)
191 191 outprompt = str(self.prompt_out)
192 192 if self.do_full_cache:
193 193 IPython.utils.io.Term.cout.write(outprompt)
194 194
195 195 def compute_result_repr(self, result):
196 196 """Compute and return the repr of the object to be displayed.
197 197
198 198 This method only compute the string form of the repr and should NOT
199 199 actual print or write that to a stream.
200 200 """
201 201 result_repr = self.default_formatter(result)
202 202 if '\n' in result_repr:
203 203 # So that multi-line strings line up with the left column of
204 204 # the screen, instead of having the output prompt mess up
205 205 # their first line.
206 206 outprompt = str(self.prompt_out)
207 207 if outprompt and not outprompt.endswith('\n'):
208 208 # But avoid extraneous empty lines.
209 209 result_repr = '\n' + result_repr
210 210
211 return result_repr
211 extra_formats = []
212 for f in self.extra_formatters:
213 try:
214 data = f(result)
215 except Exception:
216 # FIXME: log the exception.
217 continue
218 if data is not None:
219 extra_formats.append((f.id, f.format, data))
220
221 return result_repr, extra_formats
212 222
213 def write_result_repr(self, result_repr):
223 def write_result_repr(self, result_repr, extra_formats):
214 224 # We want to print because we want to always make sure we have a
215 225 # newline, even if all the prompt separators are ''. This is the
216 226 # standard IPython behavior.
217 227 print >>IPython.utils.io.Term.cout, result_repr
218 228
219 229 def update_user_ns(self, result):
220 230 """Update user_ns with various things like _, __, _1, etc."""
221 231
222 232 # Avoid recursive reference when displaying _oh/Out
223 233 if result is not self.shell.user_ns['_oh']:
224 234 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
225 235 warn('Output cache limit (currently '+
226 236 `self.cache_size`+' entries) hit.\n'
227 237 'Flushing cache and resetting history counter...\n'
228 238 'The only history variables available will be _,__,___ and _1\n'
229 239 'with the current result.')
230 240
231 241 self.flush()
232 242 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
233 243 # we cause buggy behavior for things like gettext).
234 244 if '_' not in __builtin__.__dict__:
235 245 self.___ = self.__
236 246 self.__ = self._
237 247 self._ = result
238 248 self.shell.user_ns.update({'_':self._,'__':self.__,'___':self.___})
239 249
240 250 # hackish access to top-level namespace to create _1,_2... dynamically
241 251 to_main = {}
242 252 if self.do_full_cache:
243 253 new_result = '_'+`self.prompt_count`
244 254 to_main[new_result] = result
245 255 self.shell.user_ns.update(to_main)
246 256 self.shell.user_ns['_oh'][self.prompt_count] = result
247 257
248 258 def log_output(self, result):
249 259 """Log the output."""
250 260 if self.shell.logger.log_output:
251 261 self.shell.logger.log_write(repr(result), 'output')
252 262
253 263 def finish_displayhook(self):
254 264 """Finish up all displayhook activities."""
255 265 IPython.utils.io.Term.cout.write(self.output_sep2)
256 266 IPython.utils.io.Term.cout.flush()
257 267
258 268 def __call__(self, result=None):
259 269 """Printing with history cache management.
260 270
261 271 This is invoked everytime the interpreter needs to print, and is
262 272 activated by setting the variable sys.displayhook to it.
263 273 """
264 274 self.check_for_underscore()
265 275 if result is not None and not self.quiet():
266 276 self.start_displayhook()
267 277 self.write_output_prompt()
268 result_repr = self.compute_result_repr(result)
269 self.write_result_repr(result_repr)
278 result_repr, extra_formats = self.compute_result_repr(result)
279 self.write_result_repr(result_repr, extra_formats)
270 280 self.update_user_ns(result)
271 281 self.log_output(result)
272 282 self.finish_displayhook()
273 283
274 284 def flush(self):
275 285 if not self.do_full_cache:
276 286 raise ValueError,"You shouldn't have reached the cache flush "\
277 287 "if full caching is not enabled!"
278 288 # delete auto-generated vars from global namespace
279 289
280 290 for n in range(1,self.prompt_count + 1):
281 291 key = '_'+`n`
282 292 try:
283 293 del self.shell.user_ns[key]
284 294 except: pass
285 295 self.shell.user_ns['_oh'].clear()
286 296
287 297 if '_' not in __builtin__.__dict__:
288 298 self.shell.user_ns.update({'_':None,'__':None, '___':None})
289 299 import gc
290 300 gc.collect() # xxx needed?
291 301
@@ -1,580 +1,581 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 re
22 22
23 23 # Our own
24 24 from IPython.core.interactiveshell import (
25 25 InteractiveShell, InteractiveShellABC
26 26 )
27 27 from IPython.core import page
28 28 from IPython.core.displayhook import DisplayHook
29 29 from IPython.core.macro import Macro
30 30 from IPython.core.payloadpage import install_payload_page
31 31 from IPython.utils import io
32 32 from IPython.utils.path import get_py_filename
33 33 from IPython.utils.text import StringTypes
34 34 from IPython.utils.traitlets import Instance, Type, Dict
35 35 from IPython.utils.warn import warn
36 36 from IPython.zmq.session import extract_header
37 37 from session import Session
38 38
39 39 #-----------------------------------------------------------------------------
40 40 # Globals and side-effects
41 41 #-----------------------------------------------------------------------------
42 42
43 43 # Install the payload version of page.
44 44 install_payload_page()
45 45
46 46 #-----------------------------------------------------------------------------
47 47 # Functions and classes
48 48 #-----------------------------------------------------------------------------
49 49
50 50 class ZMQDisplayHook(DisplayHook):
51 51
52 52 session = Instance(Session)
53 53 pub_socket = Instance('zmq.Socket')
54 54 parent_header = Dict({})
55 55
56 56 def set_parent(self, parent):
57 57 """Set the parent for outbound messages."""
58 58 self.parent_header = extract_header(parent)
59 59
60 60 def start_displayhook(self):
61 61 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
62 62
63 63 def write_output_prompt(self):
64 64 """Write the output prompt."""
65 65 if self.do_full_cache:
66 66 self.msg['content']['execution_count'] = self.prompt_count
67 67
68 def write_result_repr(self, result_repr):
68 def write_result_repr(self, result_repr, extra_formats):
69 69 self.msg['content']['data'] = result_repr
70 self.msg['content']['extra_formats'] = extra_formats
70 71
71 72 def finish_displayhook(self):
72 73 """Finish up all displayhook activities."""
73 74 self.pub_socket.send_json(self.msg)
74 75 self.msg = None
75 76
76 77
77 78 class ZMQInteractiveShell(InteractiveShell):
78 79 """A subclass of InteractiveShell for ZMQ."""
79 80
80 81 displayhook_class = Type(ZMQDisplayHook)
81 82 keepkernel_on_exit = None
82 83
83 84 def init_environment(self):
84 85 """Configure the user's environment.
85 86
86 87 """
87 88 env = os.environ
88 89 # These two ensure 'ls' produces nice coloring on BSD-derived systems
89 90 env['TERM'] = 'xterm-color'
90 91 env['CLICOLOR'] = '1'
91 92 # Since normal pagers don't work at all (over pexpect we don't have
92 93 # single-key control of the subprocess), try to disable paging in
93 94 # subprocesses as much as possible.
94 95 env['PAGER'] = 'cat'
95 96 env['GIT_PAGER'] = 'cat'
96 97
97 98 def auto_rewrite_input(self, cmd):
98 99 """Called to show the auto-rewritten input for autocall and friends.
99 100
100 101 FIXME: this payload is currently not correctly processed by the
101 102 frontend.
102 103 """
103 104 new = self.displayhook.prompt1.auto_rewrite() + cmd
104 105 payload = dict(
105 106 source='IPython.zmq.zmqshell.ZMQInteractiveShell.auto_rewrite_input',
106 107 transformed_input=new,
107 108 )
108 109 self.payload_manager.write_payload(payload)
109 110
110 111 def ask_exit(self):
111 112 """Engage the exit actions."""
112 113 payload = dict(
113 114 source='IPython.zmq.zmqshell.ZMQInteractiveShell.ask_exit',
114 115 exit=True,
115 116 keepkernel=self.keepkernel_on_exit,
116 117 )
117 118 self.payload_manager.write_payload(payload)
118 119
119 120 def _showtraceback(self, etype, evalue, stb):
120 121
121 122 exc_content = {
122 123 u'traceback' : stb,
123 124 u'ename' : unicode(etype.__name__),
124 125 u'evalue' : unicode(evalue)
125 126 }
126 127
127 128 dh = self.displayhook
128 129 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
129 130 # Send exception info over pub socket for other clients than the caller
130 131 # to pick up
131 132 dh.pub_socket.send_json(exc_msg)
132 133
133 134 # FIXME - Hack: store exception info in shell object. Right now, the
134 135 # caller is reading this info after the fact, we need to fix this logic
135 136 # to remove this hack. Even uglier, we need to store the error status
136 137 # here, because in the main loop, the logic that sets it is being
137 138 # skipped because runlines swallows the exceptions.
138 139 exc_content[u'status'] = u'error'
139 140 self._reply_content = exc_content
140 141 # /FIXME
141 142
142 143 return exc_content
143 144
144 145 #------------------------------------------------------------------------
145 146 # Magic overrides
146 147 #------------------------------------------------------------------------
147 148 # Once the base class stops inheriting from magic, this code needs to be
148 149 # moved into a separate machinery as well. For now, at least isolate here
149 150 # the magics which this class needs to implement differently from the base
150 151 # class, or that are unique to it.
151 152
152 153 def magic_doctest_mode(self,parameter_s=''):
153 154 """Toggle doctest mode on and off.
154 155
155 156 This mode is intended to make IPython behave as much as possible like a
156 157 plain Python shell, from the perspective of how its prompts, exceptions
157 158 and output look. This makes it easy to copy and paste parts of a
158 159 session into doctests. It does so by:
159 160
160 161 - Changing the prompts to the classic ``>>>`` ones.
161 162 - Changing the exception reporting mode to 'Plain'.
162 163 - Disabling pretty-printing of output.
163 164
164 165 Note that IPython also supports the pasting of code snippets that have
165 166 leading '>>>' and '...' prompts in them. This means that you can paste
166 167 doctests from files or docstrings (even if they have leading
167 168 whitespace), and the code will execute correctly. You can then use
168 169 '%history -t' to see the translated history; this will give you the
169 170 input after removal of all the leading prompts and whitespace, which
170 171 can be pasted back into an editor.
171 172
172 173 With these features, you can switch into this mode easily whenever you
173 174 need to do testing and changes to doctests, without having to leave
174 175 your existing IPython session.
175 176 """
176 177
177 178 from IPython.utils.ipstruct import Struct
178 179
179 180 # Shorthands
180 181 shell = self.shell
181 182 # dstore is a data store kept in the instance metadata bag to track any
182 183 # changes we make, so we can undo them later.
183 184 dstore = shell.meta.setdefault('doctest_mode', Struct())
184 185 save_dstore = dstore.setdefault
185 186
186 187 # save a few values we'll need to recover later
187 188 mode = save_dstore('mode', False)
188 189 save_dstore('rc_pprint', shell.pprint)
189 190 save_dstore('xmode', shell.InteractiveTB.mode)
190 191
191 192 if mode == False:
192 193 # turn on
193 194 shell.pprint = False
194 195 shell.magic_xmode('Plain')
195 196 else:
196 197 # turn off
197 198 shell.pprint = dstore.rc_pprint
198 199 shell.magic_xmode(dstore.xmode)
199 200
200 201 # Store new mode and inform on console
201 202 dstore.mode = bool(1-int(mode))
202 203 mode_label = ['OFF','ON'][dstore.mode]
203 204 print('Doctest mode is:', mode_label)
204 205
205 206 # Send the payload back so that clients can modify their prompt display
206 207 payload = dict(
207 208 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_doctest_mode',
208 209 mode=dstore.mode)
209 210 self.payload_manager.write_payload(payload)
210 211
211 212 def magic_edit(self,parameter_s='',last_call=['','']):
212 213 """Bring up an editor and execute the resulting code.
213 214
214 215 Usage:
215 216 %edit [options] [args]
216 217
217 218 %edit runs IPython's editor hook. The default version of this hook is
218 219 set to call the __IPYTHON__.rc.editor command. This is read from your
219 220 environment variable $EDITOR. If this isn't found, it will default to
220 221 vi under Linux/Unix and to notepad under Windows. See the end of this
221 222 docstring for how to change the editor hook.
222 223
223 224 You can also set the value of this editor via the command line option
224 225 '-editor' or in your ipythonrc file. This is useful if you wish to use
225 226 specifically for IPython an editor different from your typical default
226 227 (and for Windows users who typically don't set environment variables).
227 228
228 229 This command allows you to conveniently edit multi-line code right in
229 230 your IPython session.
230 231
231 232 If called without arguments, %edit opens up an empty editor with a
232 233 temporary file and will execute the contents of this file when you
233 234 close it (don't forget to save it!).
234 235
235 236
236 237 Options:
237 238
238 239 -n <number>: open the editor at a specified line number. By default,
239 240 the IPython editor hook uses the unix syntax 'editor +N filename', but
240 241 you can configure this by providing your own modified hook if your
241 242 favorite editor supports line-number specifications with a different
242 243 syntax.
243 244
244 245 -p: this will call the editor with the same data as the previous time
245 246 it was used, regardless of how long ago (in your current session) it
246 247 was.
247 248
248 249 -r: use 'raw' input. This option only applies to input taken from the
249 250 user's history. By default, the 'processed' history is used, so that
250 251 magics are loaded in their transformed version to valid Python. If
251 252 this option is given, the raw input as typed as the command line is
252 253 used instead. When you exit the editor, it will be executed by
253 254 IPython's own processor.
254 255
255 256 -x: do not execute the edited code immediately upon exit. This is
256 257 mainly useful if you are editing programs which need to be called with
257 258 command line arguments, which you can then do using %run.
258 259
259 260
260 261 Arguments:
261 262
262 263 If arguments are given, the following possibilites exist:
263 264
264 265 - The arguments are numbers or pairs of colon-separated numbers (like
265 266 1 4:8 9). These are interpreted as lines of previous input to be
266 267 loaded into the editor. The syntax is the same of the %macro command.
267 268
268 269 - If the argument doesn't start with a number, it is evaluated as a
269 270 variable and its contents loaded into the editor. You can thus edit
270 271 any string which contains python code (including the result of
271 272 previous edits).
272 273
273 274 - If the argument is the name of an object (other than a string),
274 275 IPython will try to locate the file where it was defined and open the
275 276 editor at the point where it is defined. You can use `%edit function`
276 277 to load an editor exactly at the point where 'function' is defined,
277 278 edit it and have the file be executed automatically.
278 279
279 280 If the object is a macro (see %macro for details), this opens up your
280 281 specified editor with a temporary file containing the macro's data.
281 282 Upon exit, the macro is reloaded with the contents of the file.
282 283
283 284 Note: opening at an exact line is only supported under Unix, and some
284 285 editors (like kedit and gedit up to Gnome 2.8) do not understand the
285 286 '+NUMBER' parameter necessary for this feature. Good editors like
286 287 (X)Emacs, vi, jed, pico and joe all do.
287 288
288 289 - If the argument is not found as a variable, IPython will look for a
289 290 file with that name (adding .py if necessary) and load it into the
290 291 editor. It will execute its contents with execfile() when you exit,
291 292 loading any code in the file into your interactive namespace.
292 293
293 294 After executing your code, %edit will return as output the code you
294 295 typed in the editor (except when it was an existing file). This way
295 296 you can reload the code in further invocations of %edit as a variable,
296 297 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
297 298 the output.
298 299
299 300 Note that %edit is also available through the alias %ed.
300 301
301 302 This is an example of creating a simple function inside the editor and
302 303 then modifying it. First, start up the editor:
303 304
304 305 In [1]: ed
305 306 Editing... done. Executing edited code...
306 307 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
307 308
308 309 We can then call the function foo():
309 310
310 311 In [2]: foo()
311 312 foo() was defined in an editing session
312 313
313 314 Now we edit foo. IPython automatically loads the editor with the
314 315 (temporary) file where foo() was previously defined:
315 316
316 317 In [3]: ed foo
317 318 Editing... done. Executing edited code...
318 319
319 320 And if we call foo() again we get the modified version:
320 321
321 322 In [4]: foo()
322 323 foo() has now been changed!
323 324
324 325 Here is an example of how to edit a code snippet successive
325 326 times. First we call the editor:
326 327
327 328 In [5]: ed
328 329 Editing... done. Executing edited code...
329 330 hello
330 331 Out[5]: "print 'hello'n"
331 332
332 333 Now we call it again with the previous output (stored in _):
333 334
334 335 In [6]: ed _
335 336 Editing... done. Executing edited code...
336 337 hello world
337 338 Out[6]: "print 'hello world'n"
338 339
339 340 Now we call it with the output #8 (stored in _8, also as Out[8]):
340 341
341 342 In [7]: ed _8
342 343 Editing... done. Executing edited code...
343 344 hello again
344 345 Out[7]: "print 'hello again'n"
345 346
346 347
347 348 Changing the default editor hook:
348 349
349 350 If you wish to write your own editor hook, you can put it in a
350 351 configuration file which you load at startup time. The default hook
351 352 is defined in the IPython.core.hooks module, and you can use that as a
352 353 starting example for further modifications. That file also has
353 354 general instructions on how to set a new hook for use once you've
354 355 defined it."""
355 356
356 357 # FIXME: This function has become a convoluted mess. It needs a
357 358 # ground-up rewrite with clean, simple logic.
358 359
359 360 def make_filename(arg):
360 361 "Make a filename from the given args"
361 362 try:
362 363 filename = get_py_filename(arg)
363 364 except IOError:
364 365 if args.endswith('.py'):
365 366 filename = arg
366 367 else:
367 368 filename = None
368 369 return filename
369 370
370 371 # custom exceptions
371 372 class DataIsObject(Exception): pass
372 373
373 374 opts,args = self.parse_options(parameter_s,'prn:')
374 375 # Set a few locals from the options for convenience:
375 376 opts_p = opts.has_key('p')
376 377 opts_r = opts.has_key('r')
377 378
378 379 # Default line number value
379 380 lineno = opts.get('n',None)
380 381 if lineno is not None:
381 382 try:
382 383 lineno = int(lineno)
383 384 except:
384 385 warn("The -n argument must be an integer.")
385 386 return
386 387
387 388 if opts_p:
388 389 args = '_%s' % last_call[0]
389 390 if not self.shell.user_ns.has_key(args):
390 391 args = last_call[1]
391 392
392 393 # use last_call to remember the state of the previous call, but don't
393 394 # let it be clobbered by successive '-p' calls.
394 395 try:
395 396 last_call[0] = self.shell.displayhook.prompt_count
396 397 if not opts_p:
397 398 last_call[1] = parameter_s
398 399 except:
399 400 pass
400 401
401 402 # by default this is done with temp files, except when the given
402 403 # arg is a filename
403 404 use_temp = 1
404 405
405 406 if re.match(r'\d',args):
406 407 # Mode where user specifies ranges of lines, like in %macro.
407 408 # This means that you can't edit files whose names begin with
408 409 # numbers this way. Tough.
409 410 ranges = args.split()
410 411 data = ''.join(self.extract_input_slices(ranges,opts_r))
411 412 elif args.endswith('.py'):
412 413 filename = make_filename(args)
413 414 data = ''
414 415 use_temp = 0
415 416 elif args:
416 417 try:
417 418 # Load the parameter given as a variable. If not a string,
418 419 # process it as an object instead (below)
419 420
420 421 #print '*** args',args,'type',type(args) # dbg
421 422 data = eval(args,self.shell.user_ns)
422 423 if not type(data) in StringTypes:
423 424 raise DataIsObject
424 425
425 426 except (NameError,SyntaxError):
426 427 # given argument is not a variable, try as a filename
427 428 filename = make_filename(args)
428 429 if filename is None:
429 430 warn("Argument given (%s) can't be found as a variable "
430 431 "or as a filename." % args)
431 432 return
432 433
433 434 data = ''
434 435 use_temp = 0
435 436 except DataIsObject:
436 437
437 438 # macros have a special edit function
438 439 if isinstance(data,Macro):
439 440 self._edit_macro(args,data)
440 441 return
441 442
442 443 # For objects, try to edit the file where they are defined
443 444 try:
444 445 filename = inspect.getabsfile(data)
445 446 if 'fakemodule' in filename.lower() and inspect.isclass(data):
446 447 # class created by %edit? Try to find source
447 448 # by looking for method definitions instead, the
448 449 # __module__ in those classes is FakeModule.
449 450 attrs = [getattr(data, aname) for aname in dir(data)]
450 451 for attr in attrs:
451 452 if not inspect.ismethod(attr):
452 453 continue
453 454 filename = inspect.getabsfile(attr)
454 455 if filename and 'fakemodule' not in filename.lower():
455 456 # change the attribute to be the edit target instead
456 457 data = attr
457 458 break
458 459
459 460 datafile = 1
460 461 except TypeError:
461 462 filename = make_filename(args)
462 463 datafile = 1
463 464 warn('Could not find file where `%s` is defined.\n'
464 465 'Opening a file named `%s`' % (args,filename))
465 466 # Now, make sure we can actually read the source (if it was in
466 467 # a temp file it's gone by now).
467 468 if datafile:
468 469 try:
469 470 if lineno is None:
470 471 lineno = inspect.getsourcelines(data)[1]
471 472 except IOError:
472 473 filename = make_filename(args)
473 474 if filename is None:
474 475 warn('The file `%s` where `%s` was defined cannot '
475 476 'be read.' % (filename,data))
476 477 return
477 478 use_temp = 0
478 479 else:
479 480 data = ''
480 481
481 482 if use_temp:
482 483 filename = self.shell.mktempfile(data)
483 484 print('IPython will make a temporary file named:', filename)
484 485
485 486 # Make sure we send to the client an absolute path, in case the working
486 487 # directory of client and kernel don't match
487 488 filename = os.path.abspath(filename)
488 489
489 490 payload = {
490 491 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
491 492 'filename' : filename,
492 493 'line_number' : lineno
493 494 }
494 495 self.payload_manager.write_payload(payload)
495 496
496 497 def magic_gui(self, *args, **kwargs):
497 498 raise NotImplementedError(
498 499 'GUI support must be enabled in command line options.')
499 500
500 501 def magic_pylab(self, *args, **kwargs):
501 502 raise NotImplementedError(
502 503 'pylab support must be enabled in command line options.')
503 504
504 505 # A few magics that are adapted to the specifics of using pexpect and a
505 506 # remote terminal
506 507
507 508 def magic_clear(self, arg_s):
508 509 """Clear the terminal."""
509 510 if os.name == 'posix':
510 511 self.shell.system("clear")
511 512 else:
512 513 self.shell.system("cls")
513 514
514 515 if os.name == 'nt':
515 516 # This is the usual name in windows
516 517 magic_cls = magic_clear
517 518
518 519 # Terminal pagers won't work over pexpect, but we do have our own pager
519 520
520 521 def magic_less(self, arg_s):
521 522 """Show a file through the pager.
522 523
523 524 Files ending in .py are syntax-highlighted."""
524 525 cont = open(arg_s).read()
525 526 if arg_s.endswith('.py'):
526 527 cont = self.shell.pycolorize(cont)
527 528 page.page(cont)
528 529
529 530 magic_more = magic_less
530 531
531 532 # Man calls a pager, so we also need to redefine it
532 533 if os.name == 'posix':
533 534 def magic_man(self, arg_s):
534 535 """Find the man page for the given command and display in pager."""
535 536 page.page(self.shell.getoutput('man %s | col -b' % arg_s,
536 537 split=False))
537 538
538 539 # FIXME: this is specific to the GUI, so we should let the gui app load
539 540 # magics at startup that are only for the gui. Once the gui app has proper
540 541 # profile and configuration management, we can have it initialize a kernel
541 542 # with a special config file that provides these.
542 543 def magic_guiref(self, arg_s):
543 544 """Show a basic reference about the GUI console."""
544 545 from IPython.core.usage import gui_reference
545 546 page.page(gui_reference, auto_html=True)
546 547
547 548 def magic_loadpy(self, arg_s):
548 549 """Load a .py python script into the GUI console.
549 550
550 551 This magic command can either take a local filename or a url::
551 552
552 553 %loadpy myscript.py
553 554 %loadpy http://www.example.com/myscript.py
554 555 """
555 556 if not arg_s.endswith('.py'):
556 557 raise ValueError('%%load only works with .py files: %s' % arg_s)
557 558 if arg_s.startswith('http'):
558 559 import urllib2
559 560 response = urllib2.urlopen(arg_s)
560 561 content = response.read()
561 562 else:
562 563 content = open(arg_s).read()
563 564 payload = dict(
564 565 source='IPython.zmq.zmqshell.ZMQInteractiveShell.magic_loadpy',
565 566 text=content
566 567 )
567 568 self.payload_manager.write_payload(payload)
568 569
569 570 def magic_Exit(self, parameter_s=''):
570 571 """Exit IPython. If the -k option is provided, the kernel will be left
571 572 running. Otherwise, it will shutdown without prompting.
572 573 """
573 574 opts,args = self.parse_options(parameter_s,'k')
574 575 self.shell.keepkernel_on_exit = opts.has_key('k')
575 576 self.shell.ask_exit()
576 577
577 578 # Add aliases as magics so all common forms work: exit, quit, Exit, Quit.
578 579 magic_exit = magic_quit = magic_Quit = magic_Exit
579 580
580 581 InteractiveShellABC.register(ZMQInteractiveShell)
@@ -1,873 +1,892 b''
1 1 .. _messaging:
2 2
3 3 ======================
4 4 Messaging in IPython
5 5 ======================
6 6
7 7
8 8 Introduction
9 9 ============
10 10
11 11 This document explains the basic communications design and messaging
12 12 specification for how the various IPython objects interact over a network
13 13 transport. The current implementation uses the ZeroMQ_ library for messaging
14 14 within and between hosts.
15 15
16 16 .. Note::
17 17
18 18 This document should be considered the authoritative description of the
19 19 IPython messaging protocol, and all developers are strongly encouraged to
20 20 keep it updated as the implementation evolves, so that we have a single
21 21 common reference for all protocol details.
22 22
23 23 The basic design is explained in the following diagram:
24 24
25 25 .. image:: frontend-kernel.png
26 26 :width: 450px
27 27 :alt: IPython kernel/frontend messaging architecture.
28 28 :align: center
29 29 :target: ../_images/frontend-kernel.png
30 30
31 31 A single kernel can be simultaneously connected to one or more frontends. The
32 32 kernel has three sockets that serve the following functions:
33 33
34 34 1. REQ: this socket is connected to a *single* frontend at a time, and it allows
35 35 the kernel to request input from a frontend when :func:`raw_input` is called.
36 36 The frontend holding the matching REP socket acts as a 'virtual keyboard'
37 37 for the kernel while this communication is happening (illustrated in the
38 38 figure by the black outline around the central keyboard). In practice,
39 39 frontends may display such kernel requests using a special input widget or
40 40 otherwise indicating that the user is to type input for the kernel instead
41 41 of normal commands in the frontend.
42 42
43 43 2. XREP: this single sockets allows multiple incoming connections from
44 44 frontends, and this is the socket where requests for code execution, object
45 45 information, prompts, etc. are made to the kernel by any frontend. The
46 46 communication on this socket is a sequence of request/reply actions from
47 47 each frontend and the kernel.
48 48
49 49 3. PUB: this socket is the 'broadcast channel' where the kernel publishes all
50 50 side effects (stdout, stderr, etc.) as well as the requests coming from any
51 51 client over the XREP socket and its own requests on the REP socket. There
52 52 are a number of actions in Python which generate side effects: :func:`print`
53 53 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
54 54 a multi-client scenario, we want all frontends to be able to know what each
55 55 other has sent to the kernel (this can be useful in collaborative scenarios,
56 56 for example). This socket allows both side effects and the information
57 57 about communications taking place with one client over the XREQ/XREP channel
58 58 to be made available to all clients in a uniform manner.
59 59
60 60 All messages are tagged with enough information (details below) for clients
61 61 to know which messages come from their own interaction with the kernel and
62 62 which ones are from other clients, so they can display each type
63 63 appropriately.
64 64
65 65 The actual format of the messages allowed on each of these channels is
66 66 specified below. Messages are dicts of dicts with string keys and values that
67 67 are reasonably representable in JSON. Our current implementation uses JSON
68 68 explicitly as its message format, but this shouldn't be considered a permanent
69 69 feature. As we've discovered that JSON has non-trivial performance issues due
70 70 to excessive copying, we may in the future move to a pure pickle-based raw
71 71 message format. However, it should be possible to easily convert from the raw
72 72 objects to JSON, since we may have non-python clients (e.g. a web frontend).
73 73 As long as it's easy to make a JSON version of the objects that is a faithful
74 74 representation of all the data, we can communicate with such clients.
75 75
76 76 .. Note::
77 77
78 78 Not all of these have yet been fully fleshed out, but the key ones are, see
79 79 kernel and frontend files for actual implementation details.
80 80
81 81
82 82 Python functional API
83 83 =====================
84 84
85 85 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
86 86 should develop, at a few key points, functional forms of all the requests that
87 87 take arguments in this manner and automatically construct the necessary dict
88 88 for sending.
89 89
90 90
91 91 General Message Format
92 92 ======================
93 93
94 94 All messages send or received by any IPython process should have the following
95 95 generic structure::
96 96
97 97 {
98 98 # The message header contains a pair of unique identifiers for the
99 99 # originating session and the actual message id, in addition to the
100 100 # username for the process that generated the message. This is useful in
101 101 # collaborative settings where multiple users may be interacting with the
102 102 # same kernel simultaneously, so that frontends can label the various
103 103 # messages in a meaningful way.
104 104 'header' : { 'msg_id' : uuid,
105 105 'username' : str,
106 106 'session' : uuid
107 107 },
108 108
109 109 # In a chain of messages, the header from the parent is copied so that
110 110 # clients can track where messages come from.
111 111 'parent_header' : dict,
112 112
113 113 # All recognized message type strings are listed below.
114 114 'msg_type' : str,
115 115
116 116 # The actual content of the message must be a dict, whose structure
117 117 # depends on the message type.x
118 118 'content' : dict,
119 119 }
120 120
121 121 For each message type, the actual content will differ and all existing message
122 122 types are specified in what follows of this document.
123 123
124 124
125 125 Messages on the XREP/XREQ socket
126 126 ================================
127 127
128 128 .. _execute:
129 129
130 130 Execute
131 131 -------
132 132
133 133 This message type is used by frontends to ask the kernel to execute code on
134 134 behalf of the user, in a namespace reserved to the user's variables (and thus
135 135 separate from the kernel's own internal code and variables).
136 136
137 137 Message type: ``execute_request``::
138 138
139 139 content = {
140 140 # Source code to be executed by the kernel, one or more lines.
141 141 'code' : str,
142 142
143 143 # A boolean flag which, if True, signals the kernel to execute this
144 144 # code as quietly as possible. This means that the kernel will compile
145 145 # the code witIPython/core/tests/h 'exec' instead of 'single' (so
146 146 # sys.displayhook will not fire), and will *not*:
147 147 # - broadcast exceptions on the PUB socket
148 148 # - do any logging
149 149 # - populate any history
150 150 #
151 151 # The default is False.
152 152 'silent' : bool,
153 153
154 154 # A list of variable names from the user's namespace to be retrieved. What
155 155 # returns is a JSON string of the variable's repr(), not a python object.
156 156 'user_variables' : list,
157 157
158 158 # Similarly, a dict mapping names to expressions to be evaluated in the
159 159 # user's dict.
160 160 'user_expressions' : dict,
161 161 }
162 162
163 163 The ``code`` field contains a single string (possibly multiline). The kernel
164 164 is responsible for splitting this into one or more independent execution blocks
165 165 and deciding whether to compile these in 'single' or 'exec' mode (see below for
166 166 detailed execution semantics).
167 167
168 168 The ``user_`` fields deserve a detailed explanation. In the past, IPython had
169 169 the notion of a prompt string that allowed arbitrary code to be evaluated, and
170 170 this was put to good use by many in creating prompts that displayed system
171 171 status, path information, and even more esoteric uses like remote instrument
172 172 status aqcuired over the network. But now that IPython has a clean separation
173 173 between the kernel and the clients, the kernel has no prompt knowledge; prompts
174 174 are a frontend-side feature, and it should be even possible for different
175 175 frontends to display different prompts while interacting with the same kernel.
176 176
177 177 The kernel now provides the ability to retrieve data from the user's namespace
178 178 after the execution of the main ``code``, thanks to two fields in the
179 179 ``execute_request`` message:
180 180
181 181 - ``user_variables``: If only variables from the user's namespace are needed, a
182 182 list of variable names can be passed and a dict with these names as keys and
183 183 their :func:`repr()` as values will be returned.
184 184
185 185 - ``user_expressions``: For more complex expressions that require function
186 186 evaluations, a dict can be provided with string keys and arbitrary python
187 187 expressions as values. The return message will contain also a dict with the
188 188 same keys and the :func:`repr()` of the evaluated expressions as value.
189 189
190 190 With this information, frontends can display any status information they wish
191 191 in the form that best suits each frontend (a status line, a popup, inline for a
192 192 terminal, etc).
193 193
194 194 .. Note::
195 195
196 196 In order to obtain the current execution counter for the purposes of
197 197 displaying input prompts, frontends simply make an execution request with an
198 198 empty code string and ``silent=True``.
199 199
200 200 Execution semantics
201 201 ~~~~~~~~~~~~~~~~~~~
202 202
203 203 When the silent flag is false, the execution of use code consists of the
204 204 following phases (in silent mode, only the ``code`` field is executed):
205 205
206 206 1. Run the ``pre_runcode_hook``.
207 207
208 208 2. Execute the ``code`` field, see below for details.
209 209
210 210 3. If #2 succeeds, compute ``user_variables`` and ``user_expressions`` are
211 211 computed. This ensures that any error in the latter don't harm the main
212 212 code execution.
213 213
214 214 4. Call any method registered with :meth:`register_post_execute`.
215 215
216 216 .. warning::
217 217
218 218 The API for running code before/after the main code block is likely to
219 219 change soon. Both the ``pre_runcode_hook`` and the
220 220 :meth:`register_post_execute` are susceptible to modification, as we find a
221 221 consistent model for both.
222 222
223 223 To understand how the ``code`` field is executed, one must know that Python
224 224 code can be compiled in one of three modes (controlled by the ``mode`` argument
225 225 to the :func:`compile` builtin):
226 226
227 227 *single*
228 228 Valid for a single interactive statement (though the source can contain
229 229 multiple lines, such as a for loop). When compiled in this mode, the
230 230 generated bytecode contains special instructions that trigger the calling of
231 231 :func:`sys.displayhook` for any expression in the block that returns a value.
232 232 This means that a single statement can actually produce multiple calls to
233 233 :func:`sys.displayhook`, if for example it contains a loop where each
234 234 iteration computes an unassigned expression would generate 10 calls::
235 235
236 236 for i in range(10):
237 237 i**2
238 238
239 239 *exec*
240 240 An arbitrary amount of source code, this is how modules are compiled.
241 241 :func:`sys.displayhook` is *never* implicitly called.
242 242
243 243 *eval*
244 244 A single expression that returns a value. :func:`sys.displayhook` is *never*
245 245 implicitly called.
246 246
247 247
248 248 The ``code`` field is split into individual blocks each of which is valid for
249 249 execution in 'single' mode, and then:
250 250
251 251 - If there is only a single block: it is executed in 'single' mode.
252 252
253 253 - If there is more than one block:
254 254
255 255 * if the last one is a single line long, run all but the last in 'exec' mode
256 256 and the very last one in 'single' mode. This makes it easy to type simple
257 257 expressions at the end to see computed values.
258 258
259 259 * if the last one is no more than two lines long, run all but the last in
260 260 'exec' mode and the very last one in 'single' mode. This makes it easy to
261 261 type simple expressions at the end to see computed values. - otherwise
262 262 (last one is also multiline), run all in 'exec' mode
263 263
264 264 * otherwise (last one is also multiline), run all in 'exec' mode as a single
265 265 unit.
266 266
267 267 Any error in retrieving the ``user_variables`` or evaluating the
268 268 ``user_expressions`` will result in a simple error message in the return fields
269 269 of the form::
270 270
271 271 [ERROR] ExceptionType: Exception message
272 272
273 273 The user can simply send the same variable name or expression for evaluation to
274 274 see a regular traceback.
275 275
276 276 Errors in any registered post_execute functions are also reported similarly,
277 277 and the failing function is removed from the post_execution set so that it does
278 278 not continue triggering failures.
279 279
280 280 Upon completion of the execution request, the kernel *always* sends a reply,
281 281 with a status code indicating what happened and additional data depending on
282 282 the outcome. See :ref:`below <execution_results>` for the possible return
283 283 codes and associated data.
284 284
285 285
286 286 Execution counter (old prompt number)
287 287 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288 288
289 289 The kernel has a single, monotonically increasing counter of all execution
290 290 requests that are made with ``silent=False``. This counter is used to populate
291 291 the ``In[n]``, ``Out[n]`` and ``_n`` variables, so clients will likely want to
292 292 display it in some form to the user, which will typically (but not necessarily)
293 293 be done in the prompts. The value of this counter will be returned as the
294 294 ``execution_count`` field of all ``execute_reply`` messages.
295 295
296 296 .. _execution_results:
297 297
298 298 Execution results
299 299 ~~~~~~~~~~~~~~~~~
300 300
301 301 Message type: ``execute_reply``::
302 302
303 303 content = {
304 304 # One of: 'ok' OR 'error' OR 'abort'
305 305 'status' : str,
306 306
307 307 # The global kernel counter that increases by one with each non-silent
308 308 # executed request. This will typically be used by clients to display
309 309 # prompt numbers to the user. If the request was a silent one, this will
310 310 # be the current value of the counter in the kernel.
311 311 'execution_count' : int,
312 312 }
313 313
314 314 When status is 'ok', the following extra fields are present::
315 315
316 316 {
317 317 # The execution payload is a dict with string keys that may have been
318 318 # produced by the code being executed. It is retrieved by the kernel at
319 319 # the end of the execution and sent back to the front end, which can take
320 320 # action on it as needed. See main text for further details.
321 321 'payload' : dict,
322 322
323 323 # Results for the user_variables and user_expressions.
324 324 'user_variables' : dict,
325 325 'user_expressions' : dict,
326 326
327 327 # The kernel will often transform the input provided to it. If the
328 328 # '---->' transform had been applied, this is filled, otherwise it's the
329 329 # empty string. So transformations like magics don't appear here, only
330 330 # autocall ones.
331 331 'transformed_code' : str,
332 332 }
333 333
334 334 .. admonition:: Execution payloads
335 335
336 336 The notion of an 'execution payload' is different from a return value of a
337 337 given set of code, which normally is just displayed on the pyout stream
338 338 through the PUB socket. The idea of a payload is to allow special types of
339 339 code, typically magics, to populate a data container in the IPython kernel
340 340 that will be shipped back to the caller via this channel. The kernel will
341 341 have an API for this, probably something along the lines of::
342 342
343 343 ip.exec_payload_add(key, value)
344 344
345 345 though this API is still in the design stages. The data returned in this
346 346 payload will allow frontends to present special views of what just happened.
347 347
348 348
349 349 When status is 'error', the following extra fields are present::
350 350
351 351 {
352 352 'exc_name' : str, # Exception name, as a string
353 353 'exc_value' : str, # Exception value, as a string
354 354
355 355 # The traceback will contain a list of frames, represented each as a
356 356 # string. For now we'll stick to the existing design of ultraTB, which
357 357 # controls exception level of detail statefully. But eventually we'll
358 358 # want to grow into a model where more information is collected and
359 359 # packed into the traceback object, with clients deciding how little or
360 360 # how much of it to unpack. But for now, let's start with a simple list
361 361 # of strings, since that requires only minimal changes to ultratb as
362 362 # written.
363 363 'traceback' : list,
364 364 }
365 365
366 366
367 367 When status is 'abort', there are for now no additional data fields. This
368 368 happens when the kernel was interrupted by a signal.
369 369
370 370 Kernel attribute access
371 371 -----------------------
372 372
373 373 .. warning::
374 374
375 375 This part of the messaging spec is not actually implemented in the kernel
376 376 yet.
377 377
378 378 While this protocol does not specify full RPC access to arbitrary methods of
379 379 the kernel object, the kernel does allow read (and in some cases write) access
380 380 to certain attributes.
381 381
382 382 The policy for which attributes can be read is: any attribute of the kernel, or
383 383 its sub-objects, that belongs to a :class:`Configurable` object and has been
384 384 declared at the class-level with Traits validation, is in principle accessible
385 385 as long as its name does not begin with a leading underscore. The attribute
386 386 itself will have metadata indicating whether it allows remote read and/or write
387 387 access. The message spec follows for attribute read and write requests.
388 388
389 389 Message type: ``getattr_request``::
390 390
391 391 content = {
392 392 # The (possibly dotted) name of the attribute
393 393 'name' : str,
394 394 }
395 395
396 396 When a ``getattr_request`` fails, there are two possible error types:
397 397
398 398 - AttributeError: this type of error was raised when trying to access the
399 399 given name by the kernel itself. This means that the attribute likely
400 400 doesn't exist.
401 401
402 402 - AccessError: the attribute exists but its value is not readable remotely.
403 403
404 404
405 405 Message type: ``getattr_reply``::
406 406
407 407 content = {
408 408 # One of ['ok', 'AttributeError', 'AccessError'].
409 409 'status' : str,
410 410 # If status is 'ok', a JSON object.
411 411 'value' : object,
412 412 }
413 413
414 414 Message type: ``setattr_request``::
415 415
416 416 content = {
417 417 # The (possibly dotted) name of the attribute
418 418 'name' : str,
419 419
420 420 # A JSON-encoded object, that will be validated by the Traits
421 421 # information in the kernel
422 422 'value' : object,
423 423 }
424 424
425 425 When a ``setattr_request`` fails, there are also two possible error types with
426 426 similar meanings as those of the ``getattr_request`` case, but for writing.
427 427
428 428 Message type: ``setattr_reply``::
429 429
430 430 content = {
431 431 # One of ['ok', 'AttributeError', 'AccessError'].
432 432 'status' : str,
433 433 }
434 434
435 435
436 436
437 437 Object information
438 438 ------------------
439 439
440 440 One of IPython's most used capabilities is the introspection of Python objects
441 441 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
442 442 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
443 443 enough that it warrants an explicit message type, especially because frontends
444 444 may want to get object information in response to user keystrokes (like Tab or
445 445 F1) besides from the user explicitly typing code like ``x??``.
446 446
447 447 Message type: ``object_info_request``::
448 448
449 449 content = {
450 450 # The (possibly dotted) name of the object to be searched in all
451 451 # relevant namespaces
452 452 'name' : str,
453 453
454 454 # The level of detail desired. The default (0) is equivalent to typing
455 455 # 'x?' at the prompt, 1 is equivalent to 'x??'.
456 456 'detail_level' : int,
457 457 }
458 458
459 459 The returned information will be a dictionary with keys very similar to the
460 460 field names that IPython prints at the terminal.
461 461
462 462 Message type: ``object_info_reply``::
463 463
464 464 content = {
465 465 # The name the object was requested under
466 466 'name' : str,
467 467
468 468 # Boolean flag indicating whether the named object was found or not. If
469 469 # it's false, all other fields will be empty.
470 470 'found' : bool,
471 471
472 472 # Flags for magics and system aliases
473 473 'ismagic' : bool,
474 474 'isalias' : bool,
475 475
476 476 # The name of the namespace where the object was found ('builtin',
477 477 # 'magics', 'alias', 'interactive', etc.)
478 478 'namespace' : str,
479 479
480 480 # The type name will be type.__name__ for normal Python objects, but it
481 481 # can also be a string like 'Magic function' or 'System alias'
482 482 'type_name' : str,
483 483
484 484 'string_form' : str,
485 485
486 486 # For objects with a __class__ attribute this will be set
487 487 'base_class' : str,
488 488
489 489 # For objects with a __len__ attribute this will be set
490 490 'length' : int,
491 491
492 492 # If the object is a function, class or method whose file we can find,
493 493 # we give its full path
494 494 'file' : str,
495 495
496 496 # For pure Python callable objects, we can reconstruct the object
497 497 # definition line which provides its call signature. For convenience this
498 498 # is returned as a single 'definition' field, but below the raw parts that
499 499 # compose it are also returned as the argspec field.
500 500 'definition' : str,
501 501
502 502 # The individual parts that together form the definition string. Clients
503 503 # with rich display capabilities may use this to provide a richer and more
504 504 # precise representation of the definition line (e.g. by highlighting
505 505 # arguments based on the user's cursor position). For non-callable
506 506 # objects, this field is empty.
507 507 'argspec' : { # The names of all the arguments
508 508 args : list,
509 509 # The name of the varargs (*args), if any
510 510 varargs : str,
511 511 # The name of the varkw (**kw), if any
512 512 varkw : str,
513 513 # The values (as strings) of all default arguments. Note
514 514 # that these must be matched *in reverse* with the 'args'
515 515 # list above, since the first positional args have no default
516 516 # value at all.
517 517 defaults : list,
518 518 },
519 519
520 520 # For instances, provide the constructor signature (the definition of
521 521 # the __init__ method):
522 522 'init_definition' : str,
523 523
524 524 # Docstrings: for any object (function, method, module, package) with a
525 525 # docstring, we show it. But in addition, we may provide additional
526 526 # docstrings. For example, for instances we will show the constructor
527 527 # and class docstrings as well, if available.
528 528 'docstring' : str,
529 529
530 530 # For instances, provide the constructor and class docstrings
531 531 'init_docstring' : str,
532 532 'class_docstring' : str,
533 533
534 534 # If it's a callable object whose call method has a separate docstring and
535 535 # definition line:
536 536 'call_def' : str,
537 537 'call_docstring' : str,
538 538
539 539 # If detail_level was 1, we also try to find the source code that
540 540 # defines the object, if possible. The string 'None' will indicate
541 541 # that no source was found.
542 542 'source' : str,
543 543 }
544 544 '
545 545
546 546 Complete
547 547 --------
548 548
549 549 Message type: ``complete_request``::
550 550
551 551 content = {
552 552 # The text to be completed, such as 'a.is'
553 553 'text' : str,
554 554
555 555 # The full line, such as 'print a.is'. This allows completers to
556 556 # make decisions that may require information about more than just the
557 557 # current word.
558 558 'line' : str,
559 559
560 560 # The entire block of text where the line is. This may be useful in the
561 561 # case of multiline completions where more context may be needed. Note: if
562 562 # in practice this field proves unnecessary, remove it to lighten the
563 563 # messages.
564 564
565 565 'block' : str,
566 566
567 567 # The position of the cursor where the user hit 'TAB' on the line.
568 568 'cursor_pos' : int,
569 569 }
570 570
571 571 Message type: ``complete_reply``::
572 572
573 573 content = {
574 574 # The list of all matches to the completion request, such as
575 575 # ['a.isalnum', 'a.isalpha'] for the above example.
576 576 'matches' : list
577 577 }
578 578
579 579
580 580 History
581 581 -------
582 582
583 583 For clients to explicitly request history from a kernel. The kernel has all
584 584 the actual execution history stored in a single location, so clients can
585 585 request it from the kernel when needed.
586 586
587 587 Message type: ``history_request``::
588 588
589 589 content = {
590 590
591 591 # If True, also return output history in the resulting dict.
592 592 'output' : bool,
593 593
594 594 # If True, return the raw input history, else the transformed input.
595 595 'raw' : bool,
596 596
597 597 # This parameter can be one of: A number, a pair of numbers, None
598 598 # If not given, last 40 are returned.
599 599 # - number n: return the last n entries.
600 600 # - pair n1, n2: return entries in the range(n1, n2).
601 601 # - None: return all history
602 602 'index' : n or (n1, n2) or None,
603 603 }
604 604
605 605 Message type: ``history_reply``::
606 606
607 607 content = {
608 608 # A dict with prompt numbers as keys and either (input, output) or input
609 609 # as the value depending on whether output was True or False,
610 610 # respectively.
611 611 'history' : dict,
612 612 }
613 613
614 614
615 615 Connect
616 616 -------
617 617
618 618 When a client connects to the request/reply socket of the kernel, it can issue
619 619 a connect request to get basic information about the kernel, such as the ports
620 620 the other ZeroMQ sockets are listening on. This allows clients to only have
621 621 to know about a single port (the XREQ/XREP channel) to connect to a kernel.
622 622
623 623 Message type: ``connect_request``::
624 624
625 625 content = {
626 626 }
627 627
628 628 Message type: ``connect_reply``::
629 629
630 630 content = {
631 631 'xrep_port' : int # The port the XREP socket is listening on.
632 632 'pub_port' : int # The port the PUB socket is listening on.
633 633 'req_port' : int # The port the REQ socket is listening on.
634 634 'hb_port' : int # The port the heartbeat socket is listening on.
635 635 }
636 636
637 637
638 638
639 639 Kernel shutdown
640 640 ---------------
641 641
642 642 The clients can request the kernel to shut itself down; this is used in
643 643 multiple cases:
644 644
645 645 - when the user chooses to close the client application via a menu or window
646 646 control.
647 647 - when the user types 'exit' or 'quit' (or their uppercase magic equivalents).
648 648 - when the user chooses a GUI method (like the 'Ctrl-C' shortcut in the
649 649 IPythonQt client) to force a kernel restart to get a clean kernel without
650 650 losing client-side state like history or inlined figures.
651 651
652 652 The client sends a shutdown request to the kernel, and once it receives the
653 653 reply message (which is otherwise empty), it can assume that the kernel has
654 654 completed shutdown safely.
655 655
656 656 Upon their own shutdown, client applications will typically execute a last
657 657 minute sanity check and forcefully terminate any kernel that is still alive, to
658 658 avoid leaving stray processes in the user's machine.
659 659
660 660 For both shutdown request and reply, there is no actual content that needs to
661 661 be sent, so the content dict is empty.
662 662
663 663 Message type: ``shutdown_request``::
664 664
665 665 content = {
666 666 'restart' : bool # whether the shutdown is final, or precedes a restart
667 667 }
668 668
669 669 Message type: ``shutdown_reply``::
670 670
671 671 content = {
672 672 'restart' : bool # whether the shutdown is final, or precedes a restart
673 673 }
674 674
675 675 .. Note::
676 676
677 677 When the clients detect a dead kernel thanks to inactivity on the heartbeat
678 678 socket, they simply send a forceful process termination signal, since a dead
679 679 process is unlikely to respond in any useful way to messages.
680 680
681 681
682 682 Messages on the PUB/SUB socket
683 683 ==============================
684 684
685 685 Streams (stdout, stderr, etc)
686 686 ------------------------------
687 687
688 688 Message type: ``stream``::
689 689
690 690 content = {
691 691 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
692 692 'name' : str,
693 693
694 694 # The data is an arbitrary string to be written to that stream
695 695 'data' : str,
696 696 }
697 697
698 698 When a kernel receives a raw_input call, it should also broadcast it on the pub
699 699 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
700 700 to monitor/display kernel interactions and possibly replay them to their user
701 701 or otherwise expose them.
702 702
703 703 Python inputs
704 704 -------------
705 705
706 706 These messages are the re-broadcast of the ``execute_request``.
707 707
708 708 Message type: ``pyin``::
709 709
710 710 content = {
711 711 # Source code to be executed, one or more lines
712 712 'code' : str
713 713 }
714 714
715 715 Python outputs
716 716 --------------
717 717
718 718 When Python produces output from code that has been compiled in with the
719 719 'single' flag to :func:`compile`, any expression that produces a value (such as
720 720 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
721 721 this value whatever it wants. The default behavior of ``sys.displayhook`` in
722 722 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
723 723 the value as long as it is not ``None`` (which isn't printed at all). In our
724 724 case, the kernel instantiates as ``sys.displayhook`` an object which has
725 725 similar behavior, but which instead of printing to stdout, broadcasts these
726 726 values as ``pyout`` messages for clients to display appropriately.
727 727
728 IPython's displayhook can handle multiple simultaneous formats depending on its
729 configuration. The default pretty-printed repr text is always given with the
730 ``data`` entry in this message. Any other formats are provided in the
731 ``extra_formats`` list. Frontends are free to display any or all of these
732 according to its capabilities. ``extra_formats`` list contains 3-tuples of an ID
733 string, a type string, and the data. The ID is unique to the formatter
734 implementation that created the data. Frontends will typically ignore the ID
735 unless if it has requested a particular formatter. The type string tells the
736 frontend how to interpret the data. It is often, but not always a MIME type.
737 Frontends should ignore types that it does not understand. The data itself is
738 any JSON object and depends on the format. It is often, but not always a string.
739
728 740 Message type: ``pyout``::
729 741
730 742 content = {
731 # The data is typically the repr() of the object.
732 'data' : str,
743 # The data is typically the repr() of the object. It should be displayed
744 # as monospaced text.
745 'data' : str,
733 746
734 # The counter for this execution is also provided so that clients can
735 # display it, since IPython automatically creates variables called _N (for
736 # prompt N).
737 'execution_count' : int,
747 # The counter for this execution is also provided so that clients can
748 # display it, since IPython automatically creates variables called _N
749 # (for prompt N).
750 'execution_count' : int,
751
752 # Any extra formats.
753 # The tuples are of the form (ID, type, data).
754 'extra_formats' : [
755 [str, str, object]
756 ]
738 757 }
739 758
740 759 Python errors
741 760 -------------
742 761
743 762 When an error occurs during code execution
744 763
745 764 Message type: ``pyerr``::
746 765
747 766 content = {
748 767 # Similar content to the execute_reply messages for the 'error' case,
749 768 # except the 'status' field is omitted.
750 769 }
751 770
752 771 Kernel status
753 772 -------------
754 773
755 774 This message type is used by frontends to monitor the status of the kernel.
756 775
757 776 Message type: ``status``::
758 777
759 778 content = {
760 779 # When the kernel starts to execute code, it will enter the 'busy'
761 780 # state and when it finishes, it will enter the 'idle' state.
762 781 execution_state : ('busy', 'idle')
763 782 }
764 783
765 784 Kernel crashes
766 785 --------------
767 786
768 787 When the kernel has an unexpected exception, caught by the last-resort
769 788 sys.excepthook, we should broadcast the crash handler's output before exiting.
770 789 This will allow clients to notice that a kernel died, inform the user and
771 790 propose further actions.
772 791
773 792 Message type: ``crash``::
774 793
775 794 content = {
776 795 # Similarly to the 'error' case for execute_reply messages, this will
777 796 # contain exc_name, exc_type and traceback fields.
778 797
779 798 # An additional field with supplementary information such as where to
780 799 # send the crash message
781 800 'info' : str,
782 801 }
783 802
784 803
785 804 Future ideas
786 805 ------------
787 806
788 807 Other potential message types, currently unimplemented, listed below as ideas.
789 808
790 809 Message type: ``file``::
791 810
792 811 content = {
793 812 'path' : 'cool.jpg',
794 813 'mimetype' : str,
795 814 'data' : str,
796 815 }
797 816
798 817
799 818 Messages on the REQ/REP socket
800 819 ==============================
801 820
802 821 This is a socket that goes in the opposite direction: from the kernel to a
803 822 *single* frontend, and its purpose is to allow ``raw_input`` and similar
804 823 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
805 824 client. For now we will keep these messages as simple as possible, since they
806 825 basically only mean to convey the ``raw_input(prompt)`` call.
807 826
808 827 Message type: ``input_request``::
809 828
810 829 content = { 'prompt' : str }
811 830
812 831 Message type: ``input_reply``::
813 832
814 833 content = { 'value' : str }
815 834
816 835 .. Note::
817 836
818 837 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
819 838 practice the kernel should behave like an interactive program. When a
820 839 program is opened on the console, the keyboard effectively takes over the
821 840 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
822 841 Since the IPython kernel effectively behaves like a console program (albeit
823 842 one whose "keyboard" is actually living in a separate process and
824 843 transported over the zmq connection), raw ``stdin`` isn't expected to be
825 844 available.
826 845
827 846
828 847 Heartbeat for kernels
829 848 =====================
830 849
831 850 Initially we had considered using messages like those above over ZMQ for a
832 851 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
833 852 alive at all, even if it may be busy executing user code). But this has the
834 853 problem that if the kernel is locked inside extension code, it wouldn't execute
835 854 the python heartbeat code. But it turns out that we can implement a basic
836 855 heartbeat with pure ZMQ, without using any Python messaging at all.
837 856
838 857 The monitor sends out a single zmq message (right now, it is a str of the
839 858 monitor's lifetime in seconds), and gets the same message right back, prefixed
840 859 with the zmq identity of the XREQ socket in the heartbeat process. This can be
841 860 a uuid, or even a full message, but there doesn't seem to be a need for packing
842 861 up a message when the sender and receiver are the exact same Python object.
843 862
844 863 The model is this::
845 864
846 865 monitor.send(str(self.lifetime)) # '1.2345678910'
847 866
848 867 and the monitor receives some number of messages of the form::
849 868
850 869 ['uuid-abcd-dead-beef', '1.2345678910']
851 870
852 871 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
853 872 the rest is the message sent by the monitor. No Python code ever has any
854 873 access to the message between the monitor's send, and the monitor's recv.
855 874
856 875
857 876 ToDo
858 877 ====
859 878
860 879 Missing things include:
861 880
862 881 * Important: finish thinking through the payload concept and API.
863 882
864 883 * Important: ensure that we have a good solution for magics like %edit. It's
865 884 likely that with the payload concept we can build a full solution, but not
866 885 100% clear yet.
867 886
868 887 * Finishing the details of the heartbeat protocol.
869 888
870 889 * Signal handling: specify what kind of information kernel should broadcast (or
871 890 not) when it receives signals.
872 891
873 892 .. include:: ../links.rst
General Comments 0
You need to be logged in to leave comments. Login now