##// END OF EJS Templates
Merge branch 'newkernel' into qtnewkernel
epatters -
r2895:01ca9ced merge
parent child Browse files
Show More
@@ -0,0 +1,140 b''
1 #!/usr/bin/env python
2 # coding: utf-8
3 """
4 Support for creating GUI apps and starting event loops.
5
6 IPython's GUI integration allows interative plotting and GUI usage in IPython
7 session. IPython has two different types of GUI integration:
8
9 1. The terminal based IPython supports GUI event loops through Python's
10 PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically
11 whenever raw_input is waiting for a user to type code. We implement GUI
12 support in the terminal by setting PyOS_InputHook to a function that
13 iterates the event loop for a short while. It is important to note that
14 in this situation, the real GUI event loop is NOT run in the normal
15 manner, so you can't use the normal means to detect that it is running.
16 2. In the two process IPython kernel/frontend, the GUI event loop is run in
17 the kernel. In this case, the event loop is run in the normal manner by
18 calling the function or method of the GUI toolkit that starts the event
19 loop.
20
21 In addition to starting the GUI event loops in one of these two ways, IPython
22 will *always* create an appropriate GUI application object when GUi
23 integration is enabled.
24
25 If you want your GUI apps to run in IPython you need to do two things:
26
27 1. Test to see if there is already an existing main application object. If
28 there is, you should use it. If there is not an existing application object
29 you should create one.
30 2. Test to see if the GUI event loop is running. If it is, you should not
31 start it. If the event loop is not running you may start it.
32
33 This module contains functions for each toolkit that perform these things
34 in a consistent manner. Because of how PyOS_InputHook runs the event loop
35 you cannot detect if the event loop is running using the traditional calls
36 (such as ``wx.GetApp.IsMainLoopRunning()`` in wxPython). If PyOS_InputHook is
37 set These methods will return a false negative. That is, they will say the
38 event loop is not running, when is actually is. To work around this limitation
39 we proposed the following informal protocol:
40
41 * Whenever someone starts the event loop, they *must* set the ``_in_event_loop``
42 attribute of the main application object to ``True``. This should be done
43 regardless of how the event loop is actually run.
44 * Whenever someone stops the event loop, they *must* set the ``_in_event_loop``
45 attribute of the main application object to ``False``.
46 * If you want to see if the event loop is running, you *must* use ``hasattr``
47 to see if ``_in_event_loop`` attribute has been set. If it is set, you
48 *must* use its value. If it has not been set, you can query the toolkit
49 in the normal manner.
50
51 The functions below implement this logic for each GUI toolkit. If you need
52 to create custom application subclasses, you will likely have to modify this
53 code for your own purposes. This code can be copied into your own project
54 so you don't have to depend on IPython.
55
56 """
57
58 #-----------------------------------------------------------------------------
59 # Copyright (C) 2008-2010 The IPython Development Team
60 #
61 # Distributed under the terms of the BSD License. The full license is in
62 # the file COPYING, distributed as part of this software.
63 #-----------------------------------------------------------------------------
64
65 #-----------------------------------------------------------------------------
66 # Imports
67 #-----------------------------------------------------------------------------
68
69 #-----------------------------------------------------------------------------
70 # wx
71 #-----------------------------------------------------------------------------
72
73 def get_app_wx(*args, **kwargs):
74 """Create a new wx app or return an exiting one."""
75 import wx
76 app = wx.GetApp()
77 if app is None:
78 app = wx.PySimpleApp(*args, **kwargs)
79 return app
80
81 def is_event_loop_running_wx(app=None):
82 """Is the wx event loop running."""
83 if app is None:
84 app = get_app_wx()
85 if hasattr(app, '_in_event_loop'):
86 return app._in_event_loop
87 else:
88 return app.IsMainLoopRunning()
89
90 def start_event_loop_wx(app=None):
91 """Start the wx event loop in a consistent manner."""
92 if app is None:
93 app = get_app_wx()
94 if not is_event_loop_running_wx(app):
95 app._in_event_loop = True
96 app.MainLoop()
97 app._in_event_loop = False
98 else:
99 app._in_event_loop = True
100
101 #-----------------------------------------------------------------------------
102 # qt4
103 #-----------------------------------------------------------------------------
104
105 def get_app_qt4(*args, **kwargs):
106 """Create a new qt4 app or return an existing one."""
107 from PyQt4 import QtGui
108 app = QtGui.QApplication.instance()
109 if app is None:
110 app = QtGui.QApplication(*args, **kwargs)
111 return app
112
113 def is_event_loop_running_qt4(app=None):
114 """Is the qt4 event loop running."""
115 if app is None:
116 app = get_app_qt4()
117 if hasattr(app, '_in_event_loop'):
118 return app._in_event_loop
119 else:
120 # Does qt4 provide a other way to detect this?
121 return False
122
123 def start_event_loop_qt4(app=None):
124 """Start the qt4 event loop in a consistent manner."""
125 if app is None:
126 app = get_app_qt4()
127 if not is_event_loop_running_qt4(app):
128 app._in_event_loop = True
129 app.exec_()
130 app._in_event_loop = False
131 else:
132 app._in_event_loop = True
133
134 #-----------------------------------------------------------------------------
135 # Tk
136 #-----------------------------------------------------------------------------
137
138 #-----------------------------------------------------------------------------
139 # gtk
140 #-----------------------------------------------------------------------------
@@ -1,30 +1,39 b''
1 """Produce SVG versions of active plots for display by the rich Qt frontend.
2 """
3 #-----------------------------------------------------------------------------
4 # Imports
5 #-----------------------------------------------------------------------------
6
1 # Standard library imports
7 # Standard library imports
2 from cStringIO import StringIO
8 from cStringIO import StringIO
3
9
4 # System library imports.
10 # System library imports.
5 from matplotlib.backends.backend_svg import new_figure_manager
11 from matplotlib.backends.backend_svg import new_figure_manager
6 from matplotlib._pylab_helpers import Gcf
12 from matplotlib._pylab_helpers import Gcf
7
13
8 # Local imports.
14 # Local imports.
9 from backend_payload import add_plot_payload
15 from backend_payload import add_plot_payload
10
16
17 #-----------------------------------------------------------------------------
18 # Functions
19 #-----------------------------------------------------------------------------
11
20
12 def show():
21 def show():
13 """ Deliver a SVG payload.
22 """ Deliver a SVG payload.
14 """
23 """
15 figure_manager = Gcf.get_active()
24 for figure_manager in Gcf.get_all_fig_managers():
16 if figure_manager is not None:
17 # Make the background transparent.
25 # Make the background transparent.
18 # figure_manager.canvas.figure.patch.set_alpha(0.0)
26 # figure_manager.canvas.figure.patch.set_alpha(0.0)
19 # Set the background to white instead so it looks good on black.
27 # Set the background to white instead so it looks good on black.
20 figure_manager.canvas.figure.set_facecolor('white')
28 figure_manager.canvas.figure.set_facecolor('white')
21 figure_manager.canvas.figure.set_edgecolor('white')
29 figure_manager.canvas.figure.set_edgecolor('white')
22 data = svg_from_canvas(figure_manager.canvas)
30 data = svg_from_canvas(figure_manager.canvas)
23 add_plot_payload('svg', data)
31 add_plot_payload('svg', data)
24
32
33
25 def svg_from_canvas(canvas):
34 def svg_from_canvas(canvas):
26 """ Return a string containing the SVG representation of a FigureCanvasSvg.
35 """ Return a string containing the SVG representation of a FigureCanvasSvg.
27 """
36 """
28 string_io = StringIO()
37 string_io = StringIO()
29 canvas.print_svg(string_io)
38 canvas.print_svg(string_io)
30 return string_io.getvalue()
39 return string_io.getvalue()
@@ -1,388 +1,427 b''
1 """A ZMQ-based subclass of InteractiveShell.
2
3 This code is meant to ease the refactoring of the base InteractiveShell into
4 something with a cleaner architecture for 2-process use, without actually
5 breaking InteractiveShell itself. So we're doing something a bit ugly, where
6 we subclass and override what we want to fix. Once this is working well, we
7 can go back to the base class and refactor the code for a cleaner inheritance
8 implementation that doesn't rely on so much monkeypatching.
9
10 But this lets us maintain a fully working IPython as we develop the new
11 machinery. This should thus be thought of as scaffolding.
12 """
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 from __future__ import print_function
17
18 # Stdlib
1 import inspect
19 import inspect
20 import os
2 import re
21 import re
3 import sys
22 import sys
23
4 from subprocess import Popen, PIPE
24 from subprocess import Popen, PIPE
5
25
26 # Our own
6 from IPython.core.interactiveshell import (
27 from IPython.core.interactiveshell import (
7 InteractiveShell, InteractiveShellABC
28 InteractiveShell, InteractiveShellABC
8 )
29 )
9 from IPython.core.displayhook import DisplayHook
30 from IPython.core.displayhook import DisplayHook
10 from IPython.core.macro import Macro
31 from IPython.core.macro import Macro
11 from IPython.utils.path import get_py_filename
32 from IPython.utils.path import get_py_filename
12 from IPython.utils.text import StringTypes
33 from IPython.utils.text import StringTypes
13 from IPython.utils.traitlets import Instance, Type, Dict
34 from IPython.utils.traitlets import Instance, Type, Dict
14 from IPython.utils.warn import warn
35 from IPython.utils.warn import warn
15 from IPython.zmq.session import extract_header
36 from IPython.zmq.session import extract_header
16 from IPython.core.payloadpage import install_payload_page
37 from IPython.core.payloadpage import install_payload_page
17 from session import Session
38 from session import Session
18
39
40 #-----------------------------------------------------------------------------
41 # Globals and side-effects
42 #-----------------------------------------------------------------------------
43
19 # Install the payload version of page.
44 # Install the payload version of page.
20 install_payload_page()
45 install_payload_page()
21
46
47 #-----------------------------------------------------------------------------
48 # Functions and classes
49 #-----------------------------------------------------------------------------
22
50
23 class ZMQDisplayHook(DisplayHook):
51 class ZMQDisplayHook(DisplayHook):
24
52
25 session = Instance(Session)
53 session = Instance(Session)
26 pub_socket = Instance('zmq.Socket')
54 pub_socket = Instance('zmq.Socket')
27 parent_header = Dict({})
55 parent_header = Dict({})
28
56
29 def set_parent(self, parent):
57 def set_parent(self, parent):
30 """Set the parent for outbound messages."""
58 """Set the parent for outbound messages."""
31 self.parent_header = extract_header(parent)
59 self.parent_header = extract_header(parent)
32
60
33 def start_displayhook(self):
61 def start_displayhook(self):
34 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
62 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
35
63
36 def write_output_prompt(self):
64 def write_output_prompt(self):
37 """Write the output prompt."""
65 """Write the output prompt."""
38 if self.do_full_cache:
66 if self.do_full_cache:
39 self.msg['content']['output_sep'] = self.output_sep
67 self.msg['content']['output_sep'] = self.output_sep
40 self.msg['content']['prompt_string'] = str(self.prompt_out)
68 self.msg['content']['prompt_string'] = str(self.prompt_out)
41 self.msg['content']['prompt_number'] = self.prompt_count
69 self.msg['content']['prompt_number'] = self.prompt_count
42 self.msg['content']['output_sep2'] = self.output_sep2
70 self.msg['content']['output_sep2'] = self.output_sep2
43
71
44 def write_result_repr(self, result_repr):
72 def write_result_repr(self, result_repr):
45 self.msg['content']['data'] = result_repr
73 self.msg['content']['data'] = result_repr
46
74
47 def finish_displayhook(self):
75 def finish_displayhook(self):
48 """Finish up all displayhook activities."""
76 """Finish up all displayhook activities."""
49 self.pub_socket.send_json(self.msg)
77 self.pub_socket.send_json(self.msg)
50 self.msg = None
78 self.msg = None
51
79
52
80
53 class ZMQInteractiveShell(InteractiveShell):
81 class ZMQInteractiveShell(InteractiveShell):
54 """A subclass of InteractiveShell for ZMQ."""
82 """A subclass of InteractiveShell for ZMQ."""
55
83
56 displayhook_class = Type(ZMQDisplayHook)
84 displayhook_class = Type(ZMQDisplayHook)
57
85
58 def system(self, cmd):
86 def system(self, cmd):
59 cmd = self.var_expand(cmd, depth=2)
87 cmd = self.var_expand(cmd, depth=2).strip()
88
89 # Runnning a bacgkrounded process from within the gui isn't supported
90 # because we do p.wait() at the end. So instead of silently blocking
91 # we simply refuse to run in this mode, to avoid surprising the user.
92 if cmd.endswith('&'):
93 raise OSError("Background processes not supported.")
94
60 sys.stdout.flush()
95 sys.stdout.flush()
61 sys.stderr.flush()
96 sys.stderr.flush()
62 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
97 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
63 for line in p.stdout.read().split('\n'):
98 for line in p.stdout.read().split('\n'):
64 if len(line) > 0:
99 if len(line) > 0:
65 print line
100 print(line)
66 for line in p.stderr.read().split('\n'):
101 for line in p.stderr.read().split('\n'):
67 if len(line) > 0:
102 if len(line) > 0:
68 print line
103 print(line, file=sys.stderr)
69 p.wait()
104 p.wait()
70
105
71 def init_io(self):
106 def init_io(self):
72 # This will just use sys.stdout and sys.stderr. If you want to
107 # This will just use sys.stdout and sys.stderr. If you want to
73 # override sys.stdout and sys.stderr themselves, you need to do that
108 # override sys.stdout and sys.stderr themselves, you need to do that
74 # *before* instantiating this class, because Term holds onto
109 # *before* instantiating this class, because Term holds onto
75 # references to the underlying streams.
110 # references to the underlying streams.
76 import IPython.utils.io
111 import IPython.utils.io
77 Term = IPython.utils.io.IOTerm()
112 Term = IPython.utils.io.IOTerm()
78 IPython.utils.io.Term = Term
113 IPython.utils.io.Term = Term
79
114
80 def magic_edit(self,parameter_s='',last_call=['','']):
115 def magic_edit(self,parameter_s='',last_call=['','']):
81 """Bring up an editor and execute the resulting code.
116 """Bring up an editor and execute the resulting code.
82
117
83 Usage:
118 Usage:
84 %edit [options] [args]
119 %edit [options] [args]
85
120
86 %edit runs IPython's editor hook. The default version of this hook is
121 %edit runs IPython's editor hook. The default version of this hook is
87 set to call the __IPYTHON__.rc.editor command. This is read from your
122 set to call the __IPYTHON__.rc.editor command. This is read from your
88 environment variable $EDITOR. If this isn't found, it will default to
123 environment variable $EDITOR. If this isn't found, it will default to
89 vi under Linux/Unix and to notepad under Windows. See the end of this
124 vi under Linux/Unix and to notepad under Windows. See the end of this
90 docstring for how to change the editor hook.
125 docstring for how to change the editor hook.
91
126
92 You can also set the value of this editor via the command line option
127 You can also set the value of this editor via the command line option
93 '-editor' or in your ipythonrc file. This is useful if you wish to use
128 '-editor' or in your ipythonrc file. This is useful if you wish to use
94 specifically for IPython an editor different from your typical default
129 specifically for IPython an editor different from your typical default
95 (and for Windows users who typically don't set environment variables).
130 (and for Windows users who typically don't set environment variables).
96
131
97 This command allows you to conveniently edit multi-line code right in
132 This command allows you to conveniently edit multi-line code right in
98 your IPython session.
133 your IPython session.
99
134
100 If called without arguments, %edit opens up an empty editor with a
135 If called without arguments, %edit opens up an empty editor with a
101 temporary file and will execute the contents of this file when you
136 temporary file and will execute the contents of this file when you
102 close it (don't forget to save it!).
137 close it (don't forget to save it!).
103
138
104
139
105 Options:
140 Options:
106
141
107 -n <number>: open the editor at a specified line number. By default,
142 -n <number>: open the editor at a specified line number. By default,
108 the IPython editor hook uses the unix syntax 'editor +N filename', but
143 the IPython editor hook uses the unix syntax 'editor +N filename', but
109 you can configure this by providing your own modified hook if your
144 you can configure this by providing your own modified hook if your
110 favorite editor supports line-number specifications with a different
145 favorite editor supports line-number specifications with a different
111 syntax.
146 syntax.
112
147
113 -p: this will call the editor with the same data as the previous time
148 -p: this will call the editor with the same data as the previous time
114 it was used, regardless of how long ago (in your current session) it
149 it was used, regardless of how long ago (in your current session) it
115 was.
150 was.
116
151
117 -r: use 'raw' input. This option only applies to input taken from the
152 -r: use 'raw' input. This option only applies to input taken from the
118 user's history. By default, the 'processed' history is used, so that
153 user's history. By default, the 'processed' history is used, so that
119 magics are loaded in their transformed version to valid Python. If
154 magics are loaded in their transformed version to valid Python. If
120 this option is given, the raw input as typed as the command line is
155 this option is given, the raw input as typed as the command line is
121 used instead. When you exit the editor, it will be executed by
156 used instead. When you exit the editor, it will be executed by
122 IPython's own processor.
157 IPython's own processor.
123
158
124 -x: do not execute the edited code immediately upon exit. This is
159 -x: do not execute the edited code immediately upon exit. This is
125 mainly useful if you are editing programs which need to be called with
160 mainly useful if you are editing programs which need to be called with
126 command line arguments, which you can then do using %run.
161 command line arguments, which you can then do using %run.
127
162
128
163
129 Arguments:
164 Arguments:
130
165
131 If arguments are given, the following possibilites exist:
166 If arguments are given, the following possibilites exist:
132
167
133 - The arguments are numbers or pairs of colon-separated numbers (like
168 - The arguments are numbers or pairs of colon-separated numbers (like
134 1 4:8 9). These are interpreted as lines of previous input to be
169 1 4:8 9). These are interpreted as lines of previous input to be
135 loaded into the editor. The syntax is the same of the %macro command.
170 loaded into the editor. The syntax is the same of the %macro command.
136
171
137 - If the argument doesn't start with a number, it is evaluated as a
172 - If the argument doesn't start with a number, it is evaluated as a
138 variable and its contents loaded into the editor. You can thus edit
173 variable and its contents loaded into the editor. You can thus edit
139 any string which contains python code (including the result of
174 any string which contains python code (including the result of
140 previous edits).
175 previous edits).
141
176
142 - If the argument is the name of an object (other than a string),
177 - If the argument is the name of an object (other than a string),
143 IPython will try to locate the file where it was defined and open the
178 IPython will try to locate the file where it was defined and open the
144 editor at the point where it is defined. You can use `%edit function`
179 editor at the point where it is defined. You can use `%edit function`
145 to load an editor exactly at the point where 'function' is defined,
180 to load an editor exactly at the point where 'function' is defined,
146 edit it and have the file be executed automatically.
181 edit it and have the file be executed automatically.
147
182
148 If the object is a macro (see %macro for details), this opens up your
183 If the object is a macro (see %macro for details), this opens up your
149 specified editor with a temporary file containing the macro's data.
184 specified editor with a temporary file containing the macro's data.
150 Upon exit, the macro is reloaded with the contents of the file.
185 Upon exit, the macro is reloaded with the contents of the file.
151
186
152 Note: opening at an exact line is only supported under Unix, and some
187 Note: opening at an exact line is only supported under Unix, and some
153 editors (like kedit and gedit up to Gnome 2.8) do not understand the
188 editors (like kedit and gedit up to Gnome 2.8) do not understand the
154 '+NUMBER' parameter necessary for this feature. Good editors like
189 '+NUMBER' parameter necessary for this feature. Good editors like
155 (X)Emacs, vi, jed, pico and joe all do.
190 (X)Emacs, vi, jed, pico and joe all do.
156
191
157 - If the argument is not found as a variable, IPython will look for a
192 - If the argument is not found as a variable, IPython will look for a
158 file with that name (adding .py if necessary) and load it into the
193 file with that name (adding .py if necessary) and load it into the
159 editor. It will execute its contents with execfile() when you exit,
194 editor. It will execute its contents with execfile() when you exit,
160 loading any code in the file into your interactive namespace.
195 loading any code in the file into your interactive namespace.
161
196
162 After executing your code, %edit will return as output the code you
197 After executing your code, %edit will return as output the code you
163 typed in the editor (except when it was an existing file). This way
198 typed in the editor (except when it was an existing file). This way
164 you can reload the code in further invocations of %edit as a variable,
199 you can reload the code in further invocations of %edit as a variable,
165 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
200 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
166 the output.
201 the output.
167
202
168 Note that %edit is also available through the alias %ed.
203 Note that %edit is also available through the alias %ed.
169
204
170 This is an example of creating a simple function inside the editor and
205 This is an example of creating a simple function inside the editor and
171 then modifying it. First, start up the editor:
206 then modifying it. First, start up the editor:
172
207
173 In [1]: ed
208 In [1]: ed
174 Editing... done. Executing edited code...
209 Editing... done. Executing edited code...
175 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
210 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
176
211
177 We can then call the function foo():
212 We can then call the function foo():
178
213
179 In [2]: foo()
214 In [2]: foo()
180 foo() was defined in an editing session
215 foo() was defined in an editing session
181
216
182 Now we edit foo. IPython automatically loads the editor with the
217 Now we edit foo. IPython automatically loads the editor with the
183 (temporary) file where foo() was previously defined:
218 (temporary) file where foo() was previously defined:
184
219
185 In [3]: ed foo
220 In [3]: ed foo
186 Editing... done. Executing edited code...
221 Editing... done. Executing edited code...
187
222
188 And if we call foo() again we get the modified version:
223 And if we call foo() again we get the modified version:
189
224
190 In [4]: foo()
225 In [4]: foo()
191 foo() has now been changed!
226 foo() has now been changed!
192
227
193 Here is an example of how to edit a code snippet successive
228 Here is an example of how to edit a code snippet successive
194 times. First we call the editor:
229 times. First we call the editor:
195
230
196 In [5]: ed
231 In [5]: ed
197 Editing... done. Executing edited code...
232 Editing... done. Executing edited code...
198 hello
233 hello
199 Out[5]: "print 'hello'n"
234 Out[5]: "print 'hello'n"
200
235
201 Now we call it again with the previous output (stored in _):
236 Now we call it again with the previous output (stored in _):
202
237
203 In [6]: ed _
238 In [6]: ed _
204 Editing... done. Executing edited code...
239 Editing... done. Executing edited code...
205 hello world
240 hello world
206 Out[6]: "print 'hello world'n"
241 Out[6]: "print 'hello world'n"
207
242
208 Now we call it with the output #8 (stored in _8, also as Out[8]):
243 Now we call it with the output #8 (stored in _8, also as Out[8]):
209
244
210 In [7]: ed _8
245 In [7]: ed _8
211 Editing... done. Executing edited code...
246 Editing... done. Executing edited code...
212 hello again
247 hello again
213 Out[7]: "print 'hello again'n"
248 Out[7]: "print 'hello again'n"
214
249
215
250
216 Changing the default editor hook:
251 Changing the default editor hook:
217
252
218 If you wish to write your own editor hook, you can put it in a
253 If you wish to write your own editor hook, you can put it in a
219 configuration file which you load at startup time. The default hook
254 configuration file which you load at startup time. The default hook
220 is defined in the IPython.core.hooks module, and you can use that as a
255 is defined in the IPython.core.hooks module, and you can use that as a
221 starting example for further modifications. That file also has
256 starting example for further modifications. That file also has
222 general instructions on how to set a new hook for use once you've
257 general instructions on how to set a new hook for use once you've
223 defined it."""
258 defined it."""
224
259
225 # FIXME: This function has become a convoluted mess. It needs a
260 # FIXME: This function has become a convoluted mess. It needs a
226 # ground-up rewrite with clean, simple logic.
261 # ground-up rewrite with clean, simple logic.
227
262
228 def make_filename(arg):
263 def make_filename(arg):
229 "Make a filename from the given args"
264 "Make a filename from the given args"
230 try:
265 try:
231 filename = get_py_filename(arg)
266 filename = get_py_filename(arg)
232 except IOError:
267 except IOError:
233 if args.endswith('.py'):
268 if args.endswith('.py'):
234 filename = arg
269 filename = arg
235 else:
270 else:
236 filename = None
271 filename = None
237 return filename
272 return filename
238
273
239 # custom exceptions
274 # custom exceptions
240 class DataIsObject(Exception): pass
275 class DataIsObject(Exception): pass
241
276
242 opts,args = self.parse_options(parameter_s,'prn:')
277 opts,args = self.parse_options(parameter_s,'prn:')
243 # Set a few locals from the options for convenience:
278 # Set a few locals from the options for convenience:
244 opts_p = opts.has_key('p')
279 opts_p = opts.has_key('p')
245 opts_r = opts.has_key('r')
280 opts_r = opts.has_key('r')
246
281
247 # Default line number value
282 # Default line number value
248 lineno = opts.get('n',None)
283 lineno = opts.get('n',None)
249 if lineno is not None:
284 if lineno is not None:
250 try:
285 try:
251 lineno = int(lineno)
286 lineno = int(lineno)
252 except:
287 except:
253 warn("The -n argument must be an integer.")
288 warn("The -n argument must be an integer.")
254 return
289 return
255
290
256 if opts_p:
291 if opts_p:
257 args = '_%s' % last_call[0]
292 args = '_%s' % last_call[0]
258 if not self.shell.user_ns.has_key(args):
293 if not self.shell.user_ns.has_key(args):
259 args = last_call[1]
294 args = last_call[1]
260
295
261 # use last_call to remember the state of the previous call, but don't
296 # use last_call to remember the state of the previous call, but don't
262 # let it be clobbered by successive '-p' calls.
297 # let it be clobbered by successive '-p' calls.
263 try:
298 try:
264 last_call[0] = self.shell.displayhook.prompt_count
299 last_call[0] = self.shell.displayhook.prompt_count
265 if not opts_p:
300 if not opts_p:
266 last_call[1] = parameter_s
301 last_call[1] = parameter_s
267 except:
302 except:
268 pass
303 pass
269
304
270 # by default this is done with temp files, except when the given
305 # by default this is done with temp files, except when the given
271 # arg is a filename
306 # arg is a filename
272 use_temp = 1
307 use_temp = 1
273
308
274 if re.match(r'\d',args):
309 if re.match(r'\d',args):
275 # Mode where user specifies ranges of lines, like in %macro.
310 # Mode where user specifies ranges of lines, like in %macro.
276 # This means that you can't edit files whose names begin with
311 # This means that you can't edit files whose names begin with
277 # numbers this way. Tough.
312 # numbers this way. Tough.
278 ranges = args.split()
313 ranges = args.split()
279 data = ''.join(self.extract_input_slices(ranges,opts_r))
314 data = ''.join(self.extract_input_slices(ranges,opts_r))
280 elif args.endswith('.py'):
315 elif args.endswith('.py'):
281 filename = make_filename(args)
316 filename = make_filename(args)
282 data = ''
317 data = ''
283 use_temp = 0
318 use_temp = 0
284 elif args:
319 elif args:
285 try:
320 try:
286 # Load the parameter given as a variable. If not a string,
321 # Load the parameter given as a variable. If not a string,
287 # process it as an object instead (below)
322 # process it as an object instead (below)
288
323
289 #print '*** args',args,'type',type(args) # dbg
324 #print '*** args',args,'type',type(args) # dbg
290 data = eval(args,self.shell.user_ns)
325 data = eval(args,self.shell.user_ns)
291 if not type(data) in StringTypes:
326 if not type(data) in StringTypes:
292 raise DataIsObject
327 raise DataIsObject
293
328
294 except (NameError,SyntaxError):
329 except (NameError,SyntaxError):
295 # given argument is not a variable, try as a filename
330 # given argument is not a variable, try as a filename
296 filename = make_filename(args)
331 filename = make_filename(args)
297 if filename is None:
332 if filename is None:
298 warn("Argument given (%s) can't be found as a variable "
333 warn("Argument given (%s) can't be found as a variable "
299 "or as a filename." % args)
334 "or as a filename." % args)
300 return
335 return
301
336
302 data = ''
337 data = ''
303 use_temp = 0
338 use_temp = 0
304 except DataIsObject:
339 except DataIsObject:
305
340
306 # macros have a special edit function
341 # macros have a special edit function
307 if isinstance(data,Macro):
342 if isinstance(data,Macro):
308 self._edit_macro(args,data)
343 self._edit_macro(args,data)
309 return
344 return
310
345
311 # For objects, try to edit the file where they are defined
346 # For objects, try to edit the file where they are defined
312 try:
347 try:
313 filename = inspect.getabsfile(data)
348 filename = inspect.getabsfile(data)
314 if 'fakemodule' in filename.lower() and inspect.isclass(data):
349 if 'fakemodule' in filename.lower() and inspect.isclass(data):
315 # class created by %edit? Try to find source
350 # class created by %edit? Try to find source
316 # by looking for method definitions instead, the
351 # by looking for method definitions instead, the
317 # __module__ in those classes is FakeModule.
352 # __module__ in those classes is FakeModule.
318 attrs = [getattr(data, aname) for aname in dir(data)]
353 attrs = [getattr(data, aname) for aname in dir(data)]
319 for attr in attrs:
354 for attr in attrs:
320 if not inspect.ismethod(attr):
355 if not inspect.ismethod(attr):
321 continue
356 continue
322 filename = inspect.getabsfile(attr)
357 filename = inspect.getabsfile(attr)
323 if filename and 'fakemodule' not in filename.lower():
358 if filename and 'fakemodule' not in filename.lower():
324 # change the attribute to be the edit target instead
359 # change the attribute to be the edit target instead
325 data = attr
360 data = attr
326 break
361 break
327
362
328 datafile = 1
363 datafile = 1
329 except TypeError:
364 except TypeError:
330 filename = make_filename(args)
365 filename = make_filename(args)
331 datafile = 1
366 datafile = 1
332 warn('Could not find file where `%s` is defined.\n'
367 warn('Could not find file where `%s` is defined.\n'
333 'Opening a file named `%s`' % (args,filename))
368 'Opening a file named `%s`' % (args,filename))
334 # Now, make sure we can actually read the source (if it was in
369 # Now, make sure we can actually read the source (if it was in
335 # a temp file it's gone by now).
370 # a temp file it's gone by now).
336 if datafile:
371 if datafile:
337 try:
372 try:
338 if lineno is None:
373 if lineno is None:
339 lineno = inspect.getsourcelines(data)[1]
374 lineno = inspect.getsourcelines(data)[1]
340 except IOError:
375 except IOError:
341 filename = make_filename(args)
376 filename = make_filename(args)
342 if filename is None:
377 if filename is None:
343 warn('The file `%s` where `%s` was defined cannot '
378 warn('The file `%s` where `%s` was defined cannot '
344 'be read.' % (filename,data))
379 'be read.' % (filename,data))
345 return
380 return
346 use_temp = 0
381 use_temp = 0
347 else:
382 else:
348 data = ''
383 data = ''
349
384
350 if use_temp:
385 if use_temp:
351 filename = self.shell.mktempfile(data)
386 filename = self.shell.mktempfile(data)
352 print 'IPython will make a temporary file named:',filename
387 print('IPython will make a temporary file named:', filename)
388
389 # Make sure we send to the client an absolute path, in case the working
390 # directory of client and kernel don't match
391 filename = os.path.abspath(filename)
353
392
354 payload = {
393 payload = {
355 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
394 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
356 'filename' : filename,
395 'filename' : filename,
357 'line_number' : lineno
396 'line_number' : lineno
358 }
397 }
359 self.payload_manager.write_payload(payload)
398 self.payload_manager.write_payload(payload)
360
399
361
400
362 def _showtraceback(self, etype, evalue, stb):
401 def _showtraceback(self, etype, evalue, stb):
363
402
364 exc_content = {
403 exc_content = {
365 u'status' : u'error',
404 u'status' : u'error',
366 u'traceback' : stb,
405 u'traceback' : stb,
367 u'ename' : unicode(etype.__name__),
406 u'ename' : unicode(etype.__name__),
368 u'evalue' : unicode(evalue)
407 u'evalue' : unicode(evalue)
369 }
408 }
370
409
371 dh = self.displayhook
410 dh = self.displayhook
372 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
411 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
373 # Send exception info over pub socket for other clients than the caller
412 # Send exception info over pub socket for other clients than the caller
374 # to pick up
413 # to pick up
375 dh.pub_socket.send_json(exc_msg)
414 dh.pub_socket.send_json(exc_msg)
376
415
377 # FIXME - Hack: store exception info in shell object. Right now, the
416 # FIXME - Hack: store exception info in shell object. Right now, the
378 # caller is reading this info after the fact, we need to fix this logic
417 # caller is reading this info after the fact, we need to fix this logic
379 # to remove this hack.
418 # to remove this hack.
380 self._reply_content = exc_content
419 self._reply_content = exc_content
381 # /FIXME
420 # /FIXME
382
421
383 return exc_content
422 return exc_content
384
423
385 def runlines(self, lines, clean=False):
424 def runlines(self, lines, clean=False):
386 return InteractiveShell.runlines(self, lines, clean)
425 return InteractiveShell.runlines(self, lines, clean)
387
426
388 InteractiveShellABC.register(ZMQInteractiveShell)
427 InteractiveShellABC.register(ZMQInteractiveShell)
@@ -1,104 +1,104 b''
1 # Makefile for Sphinx documentation
1 # Makefile for Sphinx documentation
2 #
2 #
3
3
4 # You can set these variables from the command line.
4 # You can set these variables from the command line.
5 SPHINXOPTS =
5 SPHINXOPTS =
6 SPHINXBUILD = sphinx-build
6 SPHINXBUILD = sphinx-build
7 PAPER =
7 PAPER =
8 SRCDIR = source
8 SRCDIR = source
9
9
10 # Internal variables.
10 # Internal variables.
11 PAPEROPT_a4 = -D latex_paper_size=a4
11 PAPEROPT_a4 = -D latex_paper_size=a4
12 PAPEROPT_letter = -D latex_paper_size=letter
12 PAPEROPT_letter = -D latex_paper_size=letter
13 ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR)
13 ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR)
14
14
15 .PHONY: help clean html web pickle htmlhelp latex changes linkcheck api
15 .PHONY: help clean html web pickle htmlhelp latex changes linkcheck api
16
16
17 default: html
17 default: html
18
18
19 help:
19 help:
20 @echo "Please use \`make <target>' where <target> is one of"
20 @echo "Please use \`make <target>' where <target> is one of"
21 @echo " html to make standalone HTML files"
21 @echo " html to make standalone HTML files"
22 @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
22 @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
23 @echo " htmlhelp to make HTML files and a HTML help project"
23 @echo " htmlhelp to make HTML files and a HTML help project"
24 @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
24 @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
25 @echo " changes to make an overview over all changed/added/deprecated items"
25 @echo " changes to make an overview over all changed/added/deprecated items"
26 @echo " linkcheck to check all external links for integrity"
26 @echo " linkcheck to check all external links for integrity"
27 @echo
27 @echo
28 @echo "Compound utility targets:"
28 @echo "Compound utility targets:"
29 @echo "pdf latex and then runs the PDF generation"
29 @echo "pdf latex and then runs the PDF generation"
30 @echo "all html and pdf"
30 @echo "all html and pdf"
31 @echo "dist all, and then puts the results in dist/"
31 @echo "dist all, and then puts the results in dist/"
32 @echo "gitwash-update update git workflow from source repo"
32 @echo "gitwash-update update git workflow from source repo"
33
33
34 clean:
34 clean:
35 -rm -rf build/* dist/* $(SRCDIR)/api/generated
35 -rm -rf build/* dist/* $(SRCDIR)/api/generated
36
36
37 pdf: latex
37 pdf: latex
38 cd build/latex && make all-pdf
38 cd build/latex && make all-pdf
39
39
40 all: html pdf
40 all: html pdf
41
41
42 dist: all
42 dist: all
43 mkdir -p dist
43 mkdir -p dist
44 rm -rf dist/*
44 rm -rf dist/*
45 ln build/latex/ipython.pdf dist/
45 ln build/latex/ipython.pdf dist/
46 cp -al build/html dist/
46 cp -al build/html dist/
47 @echo "Build finished. Final docs are in dist/"
47 @echo "Build finished. Final docs are in dist/"
48
48
49 html: api
49 html: api
50 mkdir -p build/html build/doctrees
50 mkdir -p build/html build/doctrees
51 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
51 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
52 @echo
52 @echo
53 @echo "Build finished. The HTML pages are in build/html."
53 @echo "Build finished. The HTML pages are in build/html."
54
54
55 api: source/api/generated/gen.txt
55 api: source/api/generated/gen.txt
56
56
57 source/api/generated/gen.txt:
57 source/api/generated/gen.txt:
58 python autogen_api.py
58 python autogen_api.py
59 @echo "Build API docs finished."
59 @echo "Build API docs finished."
60
60
61 pickle:
61 pickle:
62 mkdir -p build/pickle build/doctrees
62 mkdir -p build/pickle build/doctrees
63 $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
63 $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
64 @echo
64 @echo
65 @echo "Build finished; now you can process the pickle files or run"
65 @echo "Build finished; now you can process the pickle files or run"
66 @echo " sphinx-web build/pickle"
66 @echo " sphinx-web build/pickle"
67 @echo "to start the sphinx-web server."
67 @echo "to start the sphinx-web server."
68
68
69 web: pickle
69 web: pickle
70
70
71 htmlhelp:
71 htmlhelp:
72 mkdir -p build/htmlhelp build/doctrees
72 mkdir -p build/htmlhelp build/doctrees
73 $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
73 $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
74 @echo
74 @echo
75 @echo "Build finished; now you can run HTML Help Workshop with the" \
75 @echo "Build finished; now you can run HTML Help Workshop with the" \
76 ".hhp project file in build/htmlhelp."
76 ".hhp project file in build/htmlhelp."
77
77
78 latex: api
78 latex: api
79 mkdir -p build/latex build/doctrees
79 mkdir -p build/latex build/doctrees
80 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
80 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
81 @echo
81 @echo
82 @echo "Build finished; the LaTeX files are in build/latex."
82 @echo "Build finished; the LaTeX files are in build/latex."
83 @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
83 @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
84 "run these through (pdf)latex."
84 "run these through (pdf)latex."
85
85
86 changes:
86 changes:
87 mkdir -p build/changes build/doctrees
87 mkdir -p build/changes build/doctrees
88 $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
88 $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
89 @echo
89 @echo
90 @echo "The overview file is in build/changes."
90 @echo "The overview file is in build/changes."
91
91
92 linkcheck:
92 linkcheck:
93 mkdir -p build/linkcheck build/doctrees
93 mkdir -p build/linkcheck build/doctrees
94 $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
94 $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
95 @echo
95 @echo
96 @echo "Link check complete; look for any errors in the above output " \
96 @echo "Link check complete; look for any errors in the above output " \
97 "or in build/linkcheck/output.txt."
97 "or in build/linkcheck/output.txt."
98
98
99 gitwash-update:
99 gitwash-update:
100 python ../tools/gitwash_dumper.py source/development ipython
100 python ../tools/gitwash_dumper.py source/development ipython
101 cd source/development/gitwash && rename 's/.rst/.txt/' *.rst
101 cd source/development/gitwash && rename 's/.rst/.txt/' *.rst
102
102
103 nightly: dist
103 nightly: dist
104 rsync -avH --delete dist/ ipython:www/doc/nightly No newline at end of file
104 rsync -avH --delete dist/ ipython:www/doc/nightly
@@ -1,587 +1,708 b''
1 .. _messaging:
1 .. _messaging:
2
2
3 ======================
3 ======================
4 Messaging in IPython
4 Messaging in IPython
5 ======================
5 ======================
6
6
7
7
8 Introduction
8 Introduction
9 ============
9 ============
10
10
11 This document explains the basic communications design and messaging
11 This document explains the basic communications design and messaging
12 specification for how the various IPython objects interact over a network
12 specification for how the various IPython objects interact over a network
13 transport. The current implementation uses the ZeroMQ_ library for messaging
13 transport. The current implementation uses the ZeroMQ_ library for messaging
14 within and between hosts.
14 within and between hosts.
15
15
16 .. Note::
16 .. Note::
17
17
18 This document should be considered the authoritative description of the
18 This document should be considered the authoritative description of the
19 IPython messaging protocol, and all developers are strongly encouraged to
19 IPython messaging protocol, and all developers are strongly encouraged to
20 keep it updated as the implementation evolves, so that we have a single
20 keep it updated as the implementation evolves, so that we have a single
21 common reference for all protocol details.
21 common reference for all protocol details.
22
22
23 The basic design is explained in the following diagram:
23 The basic design is explained in the following diagram:
24
24
25 .. image:: frontend-kernel.png
25 .. image:: frontend-kernel.png
26 :width: 450px
26 :width: 450px
27 :alt: IPython kernel/frontend messaging architecture.
27 :alt: IPython kernel/frontend messaging architecture.
28 :align: center
28 :align: center
29 :target: ../_images/frontend-kernel.png
29 :target: ../_images/frontend-kernel.png
30
30
31 A single kernel can be simultaneously connected to one or more frontends. The
31 A single kernel can be simultaneously connected to one or more frontends. The
32 kernel has three sockets that serve the following functions:
32 kernel has three sockets that serve the following functions:
33
33
34 1. REQ: this socket is connected to a *single* frontend at a time, and it allows
34 1. REQ: this socket is connected to a *single* frontend at a time, and it allows
35 the kernel to request input from a frontend when :func:`raw_input` is called.
35 the kernel to request input from a frontend when :func:`raw_input` is called.
36 The frontend holding the matching REP socket acts as a 'virtual keyboard'
36 The frontend holding the matching REP socket acts as a 'virtual keyboard'
37 for the kernel while this communication is happening (illustrated in the
37 for the kernel while this communication is happening (illustrated in the
38 figure by the black outline around the central keyboard). In practice,
38 figure by the black outline around the central keyboard). In practice,
39 frontends may display such kernel requests using a special input widget or
39 frontends may display such kernel requests using a special input widget or
40 otherwise indicating that the user is to type input for the kernel instead
40 otherwise indicating that the user is to type input for the kernel instead
41 of normal commands in the frontend.
41 of normal commands in the frontend.
42
42
43 2. XREP: this single sockets allows multiple incoming connections from
43 2. XREP: this single sockets allows multiple incoming connections from
44 frontends, and this is the socket where requests for code execution, object
44 frontends, and this is the socket where requests for code execution, object
45 information, prompts, etc. are made to the kernel by any frontend. The
45 information, prompts, etc. are made to the kernel by any frontend. The
46 communication on this socket is a sequence of request/reply actions from
46 communication on this socket is a sequence of request/reply actions from
47 each frontend and the kernel.
47 each frontend and the kernel.
48
48
49 3. PUB: this socket is the 'broadcast channel' where the kernel publishes all
49 3. PUB: this socket is the 'broadcast channel' where the kernel publishes all
50 side effects (stdout, stderr, etc.) as well as the requests coming from any
50 side effects (stdout, stderr, etc.) as well as the requests coming from any
51 client over the XREP socket and its own requests on the REP socket. There
51 client over the XREP socket and its own requests on the REP socket. There
52 are a number of actions in Python which generate side effects: :func:`print`
52 are a number of actions in Python which generate side effects: :func:`print`
53 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
53 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
54 a multi-client scenario, we want all frontends to be able to know what each
54 a multi-client scenario, we want all frontends to be able to know what each
55 other has sent to the kernel (this can be useful in collaborative scenarios,
55 other has sent to the kernel (this can be useful in collaborative scenarios,
56 for example). This socket allows both side effects and the information
56 for example). This socket allows both side effects and the information
57 about communications taking place with one client over the XREQ/XREP channel
57 about communications taking place with one client over the XREQ/XREP channel
58 to be made available to all clients in a uniform manner.
58 to be made available to all clients in a uniform manner.
59
59
60 All messages are tagged with enough information (details below) for clients
60 All messages are tagged with enough information (details below) for clients
61 to know which messages come from their own interaction with the kernel and
61 to know which messages come from their own interaction with the kernel and
62 which ones are from other clients, so they can display each type
62 which ones are from other clients, so they can display each type
63 appropriately.
63 appropriately.
64
64
65 The actual format of the messages allowed on each of these channels is
65 The actual format of the messages allowed on each of these channels is
66 specified below. Messages are dicts of dicts with string keys and values that
66 specified below. Messages are dicts of dicts with string keys and values that
67 are reasonably representable in JSON. Our current implementation uses JSON
67 are reasonably representable in JSON. Our current implementation uses JSON
68 explicitly as its message format, but this shouldn't be considered a permanent
68 explicitly as its message format, but this shouldn't be considered a permanent
69 feature. As we've discovered that JSON has non-trivial performance issues due
69 feature. As we've discovered that JSON has non-trivial performance issues due
70 to excessive copying, we may in the future move to a pure pickle-based raw
70 to excessive copying, we may in the future move to a pure pickle-based raw
71 message format. However, it should be possible to easily convert from the raw
71 message format. However, it should be possible to easily convert from the raw
72 objects to JSON, since we may have non-python clients (e.g. a web frontend).
72 objects to JSON, since we may have non-python clients (e.g. a web frontend).
73 As long as it's easy to make a JSON version of the objects that is a faithful
73 As long as it's easy to make a JSON version of the objects that is a faithful
74 representation of all the data, we can communicate with such clients.
74 representation of all the data, we can communicate with such clients.
75
75
76 .. Note::
76 .. Note::
77
77
78 Not all of these have yet been fully fleshed out, but the key ones are, see
78 Not all of these have yet been fully fleshed out, but the key ones are, see
79 kernel and frontend files for actual implementation details.
79 kernel and frontend files for actual implementation details.
80
80
81
81
82 Python functional API
82 Python functional API
83 =====================
83 =====================
84
84
85 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
85 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
86 should develop, at a few key points, functional forms of all the requests that
86 should develop, at a few key points, functional forms of all the requests that
87 take arguments in this manner and automatically construct the necessary dict
87 take arguments in this manner and automatically construct the necessary dict
88 for sending.
88 for sending.
89
89
90
90
91 General Message Format
91 General Message Format
92 ======================
92 ======================
93
93
94 All messages send or received by any IPython process should have the following
94 All messages send or received by any IPython process should have the following
95 generic structure::
95 generic structure::
96
96
97 {
97 {
98 # The message header contains a pair of unique identifiers for the
98 # The message header contains a pair of unique identifiers for the
99 # originating session and the actual message id, in addition to the
99 # originating session and the actual message id, in addition to the
100 # username for the process that generated the message. This is useful in
100 # username for the process that generated the message. This is useful in
101 # collaborative settings where multiple users may be interacting with the
101 # collaborative settings where multiple users may be interacting with the
102 # same kernel simultaneously, so that frontends can label the various
102 # same kernel simultaneously, so that frontends can label the various
103 # messages in a meaningful way.
103 # messages in a meaningful way.
104 'header' : { 'msg_id' : uuid,
104 'header' : { 'msg_id' : uuid,
105 'username' : str,
105 'username' : str,
106 'session' : uuid
106 'session' : uuid
107 },
107 },
108
108
109 # In a chain of messages, the header from the parent is copied so that
109 # In a chain of messages, the header from the parent is copied so that
110 # clients can track where messages come from.
110 # clients can track where messages come from.
111 'parent_header' : dict,
111 'parent_header' : dict,
112
112
113 # All recognized message type strings are listed below.
113 # All recognized message type strings are listed below.
114 'msg_type' : str,
114 'msg_type' : str,
115
115
116 # The actual content of the message must be a dict, whose structure
116 # The actual content of the message must be a dict, whose structure
117 # depends on the message type.x
117 # depends on the message type.x
118 'content' : dict,
118 'content' : dict,
119 }
119 }
120
120
121 For each message type, the actual content will differ and all existing message
121 For each message type, the actual content will differ and all existing message
122 types are specified in what follows of this document.
122 types are specified in what follows of this document.
123
123
124
124
125 Messages on the XREP/XREQ socket
125 Messages on the XREP/XREQ socket
126 ================================
126 ================================
127
127
128 .. _execute:
128 .. _execute:
129
129
130 Execute
130 Execute
131 -------
131 -------
132
132
133 The execution request contains a single string, but this may be a multiline
133 This message type is used by frontends to ask the kernel to execute code on
134 string. The kernel is responsible for splitting this into possibly more than
134 behalf of the user, in a namespace reserved to the user's variables (and thus
135 one block and deciding whether to compile these in 'single' or 'exec' mode.
135 separate from the kernel's own internal code and variables).
136 We're still sorting out this policy. The current inputsplitter is capable of
137 splitting the input for blocks that can all be run as 'single', but in the long
138 run it may prove cleaner to only use 'single' mode for truly single-line
139 inputs, and run all multiline input in 'exec' mode. This would preserve the
140 natural behavior of single-line inputs while allowing long cells to behave more
141 likea a script. This design will be refined as we complete the implementation.
142
136
143 Message type: ``execute_request``::
137 Message type: ``execute_request``::
144
138
145 content = {
139 content = {
146 # Source code to be executed by the kernel, one or more lines.
140 # Source code to be executed by the kernel, one or more lines.
147 'code' : str,
141 'code' : str,
148
142
149 # A boolean flag which, if True, signals the kernel to execute this
143 # A boolean flag which, if True, signals the kernel to execute this
150 # code as quietly as possible. This means that the kernel will compile
144 # code as quietly as possible. This means that the kernel will compile
151 # the code with 'exec' instead of 'single' (so sys.displayhook will not
145 # the code witIPython/core/tests/h 'exec' instead of 'single' (so
152 # fire), and will *not*:
146 # sys.displayhook will not fire), and will *not*:
153 # - broadcast exceptions on the PUB socket
147 # - broadcast exceptions on the PUB socket
154 # - do any logging
148 # - do any logging
155 # - populate any history
149 # - populate any history
150 #
156 # The default is False.
151 # The default is False.
157 'silent' : bool,
152 'silent' : bool,
153
154 # A list of variable names from the user's namespace to be retrieved. What
155 # returns is a JSON string of the variable's repr(), not a python object.
156 'user_variables' : list,
157
158 # Similarly, a dict mapping names to expressions to be evaluated in the
159 # user's dict.
160 'user_expressions' : dict,
158 }
161 }
159
162
160 Upon execution, the kernel *always* sends a reply, with a status code
163 The ``code`` field contains a single string, but this may be a multiline
161 indicating what happened and additional data depending on the outcome.
164 string. The kernel is responsible for splitting this into possibly more than
165 one block and deciding whether to compile these in 'single' or 'exec' mode.
166 We're still sorting out this policy. The current inputsplitter is capable of
167 splitting the input for blocks that can all be run as 'single', but in the long
168 run it may prove cleaner to only use 'single' mode for truly single-line
169 inputs, and run all multiline input in 'exec' mode. This would preserve the
170 natural behavior of single-line inputs while allowing long cells to behave more
171 likea a script. This design will be refined as we complete the implementation.
172
173 The ``user_`` fields deserve a detailed explanation. In the past, IPython had
174 the notion of a prompt string that allowed arbitrary code to be evaluated, and
175 this was put to good use by many in creating prompts that displayed system
176 status, path information, and even more esoteric uses like remote instrument
177 status aqcuired over the network. But now that IPython has a clean separation
178 between the kernel and the clients, the notion of embedding 'prompt'
179 maninpulations into the kernel itself feels awkward. Prompts should be a
180 frontend-side feature, and it should be even possible for different frontends
181 to display different prompts while interacting with the same kernel.
182
183 We have therefore abandoned the idea of a 'prompt string' to be evaluated by
184 the kernel, and instead provide the ability to retrieve from the user's
185 namespace information after the execution of the main ``code``, with two fields
186 of the execution request:
187
188 - ``user_variables``: If only variables from the user's namespace are needed, a
189 list of variable names can be passed and a dict with these names as keys and
190 their :func:`repr()` as values will be returned.
191
192 - ``user_expressions``: For more complex expressions that require function
193 evaluations, a dict can be provided with string keys and arbitrary python
194 expressions as values. The return message will contain also a dict with the
195 same keys and the :func:`repr()` of the evaluated expressions as value.
196
197 With this information, frontends can display any status information they wish
198 in the form that best suits each frontend (a status line, a popup, inline for a
199 terminal, etc).
200
201 .. Note::
202
203 In order to obtain the current execution counter for the purposes of
204 displaying input prompts, frontends simply make an execution request with an
205 empty code string and ``silent=True``.
206
207 Execution semantics
208 Upon completion of the execution request, the kernel *always* sends a
209 reply, with a status code indicating what happened and additional data
210 depending on the outcome.
211
212 The ``code`` field is executed first, and then the ``user_variables`` and
213 ``user_expressions`` are computed. This ensures that any error in the
214 latter don't harm the main code execution.
215
216 Any error in retrieving the ``user_variables`` or evaluating the
217 ``user_expressions`` will result in a simple error message in the return
218 fields of the form::
219
220 [ERROR] ExceptionType: Exception message
221
222 The user can simply send the same variable name or expression for
223 evaluation to see a regular traceback.
224
225 Execution counter (old prompt number)
226 The kernel has a single, monotonically increasing counter of all execution
227 requests that are made with ``silent=False``. This counter is used to
228 populate the ``In[n]``, ``Out[n]`` and ``_n`` variables, so clients will
229 likely want to display it in some form to the user, which will typically
230 (but not necessarily) be done in the prompts. The value of this counter
231 will be returned as the ``execution_count`` field of all ``execute_reply```
232 messages.
162
233
163 Message type: ``execute_reply``::
234 Message type: ``execute_reply``::
164
235
165 content = {
236 content = {
166 # One of: 'ok' OR 'error' OR 'abort'
237 # One of: 'ok' OR 'error' OR 'abort'
167 'status' : str,
238 'status' : str,
168
239
169 # This has the same structure as the output of a prompt request, but is
240 # The global kernel counter that increases by one with each non-silent
170 # for the client to set up the *next* prompt (with identical limitations
241 # executed request. This will typically be used by clients to display
171 # to a prompt request)
242 # prompt numbers to the user. If the request was a silent one, this will
172 'next_prompt' : {
243 # be the current value of the counter in the kernel.
173 'prompt_string' : str,
244 'execution_count' : int,
174 'prompt_number' : int,
245
175 'input_sep' : str
246 # If the state_template was provided, this will contain the evaluated
176 },
247 # form of the template.
177
248 'state' : str,
178 # The prompt number of the actual execution for this code, which may be
179 # different from the one used when the code was typed, which was the
180 # 'next_prompt' field of the *previous* request. They will differ in the
181 # case where there is more than one client talking simultaneously to a
182 # kernel, since the numbers can go out of sync. GUI clients can use this
183 # to correct the previously written number in-place, terminal ones may
184 # re-print a corrected one if desired.
185 'prompt_number' : int,
186 }
249 }
187
250
188 When status is 'ok', the following extra fields are present::
251 When status is 'ok', the following extra fields are present::
189
252
190 {
253 {
191 # The kernel will often transform the input provided to it. This
254 # The kernel will often transform the input provided to it. If the
192 # contains the transformed code, which is what was actually executed.
255 # '---->' transform had been applied, this is filled, otherwise it's the
256 # empty string. So transformations like magics don't appear here, only
257 # autocall ones.
258
193 'transformed_code' : str,
259 'transformed_code' : str,
194
260
195 # The execution payload is a dict with string keys that may have been
261 # The execution payload is a dict with string keys that may have been
196 # produced by the code being executed. It is retrieved by the kernel at
262 # produced by the code being executed. It is retrieved by the kernel at
197 # the end of the execution and sent back to the front end, which can take
263 # the end of the execution and sent back to the front end, which can take
198 # action on it as needed. See main text for further details.
264 # action on it as needed. See main text for further details.
199 'payload' : dict,
265 'payload' : dict,
200 }
266 }
201
267
202 .. admonition:: Execution payloads
268 .. admonition:: Execution payloads
203
269
204 The notion of an 'execution payload' is different from a return value of a
270 The notion of an 'execution payload' is different from a return value of a
205 given set of code, which normally is just displayed on the pyout stream
271 given set of code, which normally is just displayed on the pyout stream
206 through the PUB socket. The idea of a payload is to allow special types of
272 through the PUB socket. The idea of a payload is to allow special types of
207 code, typically magics, to populate a data container in the IPython kernel
273 code, typically magics, to populate a data container in the IPython kernel
208 that will be shipped back to the caller via this channel. The kernel will
274 that will be shipped back to the caller via this channel. The kernel will
209 have an API for this, probably something along the lines of::
275 have an API for this, probably something along the lines of::
210
276
211 ip.exec_payload_add(key, value)
277 ip.exec_payload_add(key, value)
212
278
213 though this API is still in the design stages. The data returned in this
279 though this API is still in the design stages. The data returned in this
214 payload will allow frontends to present special views of what just happened.
280 payload will allow frontends to present special views of what just happened.
215
281
216
282
217 When status is 'error', the following extra fields are present::
283 When status is 'error', the following extra fields are present::
218
284
219 {
285 {
220 'exc_name' : str, # Exception name, as a string
286 'exc_name' : str, # Exception name, as a string
221 'exc_value' : str, # Exception value, as a string
287 'exc_value' : str, # Exception value, as a string
222
288
223 # The traceback will contain a list of frames, represented each as a
289 # The traceback will contain a list of frames, represented each as a
224 # string. For now we'll stick to the existing design of ultraTB, which
290 # string. For now we'll stick to the existing design of ultraTB, which
225 # controls exception level of detail statefully. But eventually we'll
291 # controls exception level of detail statefully. But eventually we'll
226 # want to grow into a model where more information is collected and
292 # want to grow into a model where more information is collected and
227 # packed into the traceback object, with clients deciding how little or
293 # packed into the traceback object, with clients deciding how little or
228 # how much of it to unpack. But for now, let's start with a simple list
294 # how much of it to unpack. But for now, let's start with a simple list
229 # of strings, since that requires only minimal changes to ultratb as
295 # of strings, since that requires only minimal changes to ultratb as
230 # written.
296 # written.
231 'traceback' : list,
297 'traceback' : list,
232 }
298 }
233
299
234
300
235 When status is 'abort', there are for now no additional data fields. This
301 When status is 'abort', there are for now no additional data fields. This
236 happens when the kernel was interrupted by a signal.
302 happens when the kernel was interrupted by a signal.
237
303
304 Kernel attribute access
305 -----------------------
238
306
239 Prompt
307 While this protocol does not specify full RPC access to arbitrary methods of
240 ------
308 the kernel object, the kernel does allow read (and in some cases write) access
309 to certain attributes.
241
310
242 A simple request for a current prompt string.
311 The policy for which attributes can be read is: any attribute of the kernel, or
312 its sub-objects, that belongs to a :class:`Configurable` object and has been
313 declared at the class-level with Traits validation, is in principle accessible
314 as long as its name does not begin with a leading underscore. The attribute
315 itself will have metadata indicating whether it allows remote read and/or write
316 access. The message spec follows for attribute read and write requests.
243
317
244 Message type: ``prompt_request``::
318 Message type: ``getattr_request``::
245
319
246 content = {}
320 content = {
321 # The (possibly dotted) name of the attribute
322 'name' : str,
323 }
324
325 When a ``getattr_request`` fails, there are two possible error types:
326
327 - AttributeError: this type of error was raised when trying to access the
328 given name by the kernel itself. This means that the attribute likely
329 doesn't exist.
330
331 - AccessError: the attribute exists but its value is not readable remotely.
247
332
248 In the reply, the prompt string comes back with the prompt number placeholder
333
249 *unevaluated*. The message format is:
334 Message type: ``getattr_reply``::
250
335
251 Message type: ``prompt_reply``::
336 content = {
337 # One of ['ok', 'AttributeError', 'AccessError'].
338 'status' : str,
339 # If status is 'ok', a JSON object.
340 'value' : object,
341 }
342
343 Message type: ``setattr_request``::
252
344
253 content = {
345 content = {
254 'prompt_string' : str,
346 # The (possibly dotted) name of the attribute
255 'prompt_number' : int,
347 'name' : str,
256 'input_sep' : str
348
349 # A JSON-encoded object, that will be validated by the Traits
350 # information in the kernel
351 'value' : object,
257 }
352 }
258
353
259 Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but
354 When a ``setattr_request`` fails, there are also two possible error types with
260 they should be aware that the actual prompt number for that input could change
355 similar meanings as those of the ``getattr_request`` case, but for writing.
261 later, in the case where multiple clients are interacting with a single
356
262 kernel.
357 Message type: ``setattr_reply``::
358
359 content = {
360 # One of ['ok', 'AttributeError', 'AccessError'].
361 'status' : str,
362 }
263
363
264
364
265 Object information
365 Object information
266 ------------------
366 ------------------
267
367
268 One of IPython's most used capabilities is the introspection of Python objects
368 One of IPython's most used capabilities is the introspection of Python objects
269 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
369 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
270 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
370 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
271 enough that it warrants an explicit message type, especially because frontends
371 enough that it warrants an explicit message type, especially because frontends
272 may want to get object information in response to user keystrokes (like Tab or
372 may want to get object information in response to user keystrokes (like Tab or
273 F1) besides from the user explicitly typing code like ``x??``.
373 F1) besides from the user explicitly typing code like ``x??``.
274
374
275 Message type: ``object_info_request``::
375 Message type: ``object_info_request``::
276
376
277 content = {
377 content = {
278 # The (possibly dotted) name of the object to be searched in all
378 # The (possibly dotted) name of the object to be searched in all
279 # relevant namespaces
379 # relevant namespaces
280 'name' : str,
380 'name' : str,
281
381
282 # The level of detail desired. The default (0) is equivalent to typing
382 # The level of detail desired. The default (0) is equivalent to typing
283 # 'x?' at the prompt, 1 is equivalent to 'x??'.
383 # 'x?' at the prompt, 1 is equivalent to 'x??'.
284 'detail_level' : int,
384 'detail_level' : int,
285 }
385 }
286
386
287 The returned information will be a dictionary with keys very similar to the
387 The returned information will be a dictionary with keys very similar to the
288 field names that IPython prints at the terminal.
388 field names that IPython prints at the terminal.
289
389
290 Message type: ``object_info_reply``::
390 Message type: ``object_info_reply``::
291
391
292 content = {
392 content = {
293 # Flags for magics and system aliases
393 # Flags for magics and system aliases
294 'ismagic' : bool,
394 'ismagic' : bool,
295 'isalias' : bool,
395 'isalias' : bool,
296
396
297 # The name of the namespace where the object was found ('builtin',
397 # The name of the namespace where the object was found ('builtin',
298 # 'magics', 'alias', 'interactive', etc.)
398 # 'magics', 'alias', 'interactive', etc.)
299 'namespace' : str,
399 'namespace' : str,
300
400
301 # The type name will be type.__name__ for normal Python objects, but it
401 # The type name will be type.__name__ for normal Python objects, but it
302 # can also be a string like 'Magic function' or 'System alias'
402 # can also be a string like 'Magic function' or 'System alias'
303 'type_name' : str,
403 'type_name' : str,
304
404
305 'string_form' : str,
405 'string_form' : str,
306
406
307 # For objects with a __class__ attribute this will be set
407 # For objects with a __class__ attribute this will be set
308 'base_class' : str,
408 'base_class' : str,
309
409
310 # For objects with a __len__ attribute this will be set
410 # For objects with a __len__ attribute this will be set
311 'length' : int,
411 'length' : int,
312
412
313 # If the object is a function, class or method whose file we can find,
413 # If the object is a function, class or method whose file we can find,
314 # we give its full path
414 # we give its full path
315 'file' : str,
415 'file' : str,
316
416
317 # For pure Python callable objects, we can reconstruct the object
417 # For pure Python callable objects, we can reconstruct the object
318 # definition line which provides its call signature
418 # definition line which provides its call signature. For convenience this
419 # is returned as a single 'definition' field, but below the raw parts that
420 # compose it are also returned as the argspec field.
319 'definition' : str,
421 'definition' : str,
320
422
423 # The individual parts that together form the definition string. Clients
424 # with rich display capabilities may use this to provide a richer and more
425 # precise representation of the definition line (e.g. by highlighting
426 # arguments based on the user's cursor position). For non-callable
427 # objects, this field is empty.
428 'argspec' : { # The names of all the arguments
429 args : list,
430 # The name of the varargs (*args), if any
431 varargs : str,
432 # The name of the varkw (**kw), if any
433 varkw : str,
434 # The values (as strings) of all default arguments. Note
435 # that these must be matched *in reverse* with the 'args'
436 # list above, since the first positional args have no default
437 # value at all.
438 func_defaults : list,
439 },
440
321 # For instances, provide the constructor signature (the definition of
441 # For instances, provide the constructor signature (the definition of
322 # the __init__ method):
442 # the __init__ method):
323 'init_definition' : str,
443 'init_definition' : str,
324
444
325 # Docstrings: for any object (function, method, module, package) with a
445 # Docstrings: for any object (function, method, module, package) with a
326 # docstring, we show it. But in addition, we may provide additional
446 # docstring, we show it. But in addition, we may provide additional
327 # docstrings. For example, for instances we will show the constructor
447 # docstrings. For example, for instances we will show the constructor
328 # and class docstrings as well, if available.
448 # and class docstrings as well, if available.
329 'docstring' : str,
449 'docstring' : str,
330
450
331 # For instances, provide the constructor and class docstrings
451 # For instances, provide the constructor and class docstrings
332 'init_docstring' : str,
452 'init_docstring' : str,
333 'class_docstring' : str,
453 'class_docstring' : str,
334
454
335 # If detail_level was 1, we also try to find the source code that
455 # If detail_level was 1, we also try to find the source code that
336 # defines the object, if possible. The string 'None' will indicate
456 # defines the object, if possible. The string 'None' will indicate
337 # that no source was found.
457 # that no source was found.
338 'source' : str,
458 'source' : str,
339 }
459 }
340
460
341
461
342 Complete
462 Complete
343 --------
463 --------
344
464
345 Message type: ``complete_request``::
465 Message type: ``complete_request``::
346
466
347 content = {
467 content = {
348 # The text to be completed, such as 'a.is'
468 # The text to be completed, such as 'a.is'
349 'text' : str,
469 'text' : str,
350
470
351 # The full line, such as 'print a.is'. This allows completers to
471 # The full line, such as 'print a.is'. This allows completers to
352 # make decisions that may require information about more than just the
472 # make decisions that may require information about more than just the
353 # current word.
473 # current word.
354 'line' : str,
474 'line' : str,
355
475
356 # The entire block of text where the line is. This may be useful in the
476 # The entire block of text where the line is. This may be useful in the
357 # case of multiline completions where more context may be needed. Note: if
477 # case of multiline completions where more context may be needed. Note: if
358 # in practice this field proves unnecessary, remove it to lighten the
478 # in practice this field proves unnecessary, remove it to lighten the
359 # messages.
479 # messages.
360
480
361 'block' : str,
481 'block' : str,
362
482
363 # The position of the cursor where the user hit 'TAB' on the line.
483 # The position of the cursor where the user hit 'TAB' on the line.
364 'cursor_pos' : int,
484 'cursor_pos' : int,
365 }
485 }
366
486
367 Message type: ``complete_reply``::
487 Message type: ``complete_reply``::
368
488
369 content = {
489 content = {
370 # The list of all matches to the completion request, such as
490 # The list of all matches to the completion request, such as
371 # ['a.isalnum', 'a.isalpha'] for the above example.
491 # ['a.isalnum', 'a.isalpha'] for the above example.
372 'matches' : list
492 'matches' : list
373 }
493 }
374
494
375
495
376 History
496 History
377 -------
497 -------
378
498
379 For clients to explicitly request history from a kernel. The kernel has all
499 For clients to explicitly request history from a kernel. The kernel has all
380 the actual execution history stored in a single location, so clients can
500 the actual execution history stored in a single location, so clients can
381 request it from the kernel when needed.
501 request it from the kernel when needed.
382
502
383 Message type: ``history_request``::
503 Message type: ``history_request``::
384
504
385 content = {
505 content = {
386
506
387 # If True, also return output history in the resulting dict.
507 # If True, also return output history in the resulting dict.
388 'output' : bool,
508 'output' : bool,
389
509
390 # If True, return the raw input history, else the transformed input.
510 # If True, return the raw input history, else the transformed input.
391 'raw' : bool,
511 'raw' : bool,
392
512
393 # This parameter can be one of: A number, a pair of numbers, None
513 # This parameter can be one of: A number, a pair of numbers, None
394 # If not given, last 40 are returned.
514 # If not given, last 40 are returned.
395 # - number n: return the last n entries.
515 # - number n: return the last n entries.
396 # - pair n1, n2: return entries in the range(n1, n2).
516 # - pair n1, n2: return entries in the range(n1, n2).
397 # - None: return all history
517 # - None: return all history
398 'index' : n or (n1, n2) or None,
518 'index' : n or (n1, n2) or None,
399 }
519 }
400
520
401 Message type: ``history_reply``::
521 Message type: ``history_reply``::
402
522
403 content = {
523 content = {
404 # A dict with prompt numbers as keys and either (input, output) or input
524 # A dict with prompt numbers as keys and either (input, output) or input
405 # as the value depending on whether output was True or False,
525 # as the value depending on whether output was True or False,
406 # respectively.
526 # respectively.
407 'history' : dict,
527 'history' : dict,
408 }
528 }
529
409 Messages on the PUB/SUB socket
530 Messages on the PUB/SUB socket
410 ==============================
531 ==============================
411
532
412 Streams (stdout, stderr, etc)
533 Streams (stdout, stderr, etc)
413 ------------------------------
534 ------------------------------
414
535
415 Message type: ``stream``::
536 Message type: ``stream``::
416
537
417 content = {
538 content = {
418 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
539 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
419 'name' : str,
540 'name' : str,
420
541
421 # The data is an arbitrary string to be written to that stream
542 # The data is an arbitrary string to be written to that stream
422 'data' : str,
543 'data' : str,
423 }
544 }
424
545
425 When a kernel receives a raw_input call, it should also broadcast it on the pub
546 When a kernel receives a raw_input call, it should also broadcast it on the pub
426 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
547 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
427 to monitor/display kernel interactions and possibly replay them to their user
548 to monitor/display kernel interactions and possibly replay them to their user
428 or otherwise expose them.
549 or otherwise expose them.
429
550
430 Python inputs
551 Python inputs
431 -------------
552 -------------
432
553
433 These messages are the re-broadcast of the ``execute_request``.
554 These messages are the re-broadcast of the ``execute_request``.
434
555
435 Message type: ``pyin``::
556 Message type: ``pyin``::
436
557
437 content = {
558 content = {
438 # Source code to be executed, one or more lines
559 # Source code to be executed, one or more lines
439 'code' : str
560 'code' : str
440 }
561 }
441
562
442 Python outputs
563 Python outputs
443 --------------
564 --------------
444
565
445 When Python produces output from code that has been compiled in with the
566 When Python produces output from code that has been compiled in with the
446 'single' flag to :func:`compile`, any expression that produces a value (such as
567 'single' flag to :func:`compile`, any expression that produces a value (such as
447 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
568 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
448 this value whatever it wants. The default behavior of ``sys.displayhook`` in
569 this value whatever it wants. The default behavior of ``sys.displayhook`` in
449 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
570 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
450 the value as long as it is not ``None`` (which isn't printed at all). In our
571 the value as long as it is not ``None`` (which isn't printed at all). In our
451 case, the kernel instantiates as ``sys.displayhook`` an object which has
572 case, the kernel instantiates as ``sys.displayhook`` an object which has
452 similar behavior, but which instead of printing to stdout, broadcasts these
573 similar behavior, but which instead of printing to stdout, broadcasts these
453 values as ``pyout`` messages for clients to display appropriately.
574 values as ``pyout`` messages for clients to display appropriately.
454
575
455 Message type: ``pyout``::
576 Message type: ``pyout``::
456
577
457 content = {
578 content = {
458 # The data is typically the repr() of the object.
579 # The data is typically the repr() of the object.
459 'data' : str,
580 'data' : str,
460
581
461 # The prompt number for this execution is also provided so that clients
582 # The counter for this execution is also provided so that clients can
462 # can display it, since IPython automatically creates variables called
583 # display it, since IPython automatically creates variables called _N (for
463 # _N (for prompt N).
584 # prompt N).
464 'prompt_number' : int,
585 'execution_count' : int,
465 }
586 }
466
587
467 Python errors
588 Python errors
468 -------------
589 -------------
469
590
470 When an error occurs during code execution
591 When an error occurs during code execution
471
592
472 Message type: ``pyerr``::
593 Message type: ``pyerr``::
473
594
474 content = {
595 content = {
475 # Similar content to the execute_reply messages for the 'error' case,
596 # Similar content to the execute_reply messages for the 'error' case,
476 # except the 'status' field is omitted.
597 # except the 'status' field is omitted.
477 }
598 }
478
599
479 Kernel crashes
600 Kernel crashes
480 --------------
601 --------------
481
602
482 When the kernel has an unexpected exception, caught by the last-resort
603 When the kernel has an unexpected exception, caught by the last-resort
483 sys.excepthook, we should broadcast the crash handler's output before exiting.
604 sys.excepthook, we should broadcast the crash handler's output before exiting.
484 This will allow clients to notice that a kernel died, inform the user and
605 This will allow clients to notice that a kernel died, inform the user and
485 propose further actions.
606 propose further actions.
486
607
487 Message type: ``crash``::
608 Message type: ``crash``::
488
609
489 content = {
610 content = {
490 # Similarly to the 'error' case for execute_reply messages, this will
611 # Similarly to the 'error' case for execute_reply messages, this will
491 # contain exc_name, exc_type and traceback fields.
612 # contain exc_name, exc_type and traceback fields.
492
613
493 # An additional field with supplementary information such as where to
614 # An additional field with supplementary information such as where to
494 # send the crash message
615 # send the crash message
495 'info' : str,
616 'info' : str,
496 }
617 }
497
618
498
619
499 Future ideas
620 Future ideas
500 ------------
621 ------------
501
622
502 Other potential message types, currently unimplemented, listed below as ideas.
623 Other potential message types, currently unimplemented, listed below as ideas.
503
624
504 Message type: ``file``::
625 Message type: ``file``::
505
626
506 content = {
627 content = {
507 'path' : 'cool.jpg',
628 'path' : 'cool.jpg',
508 'mimetype' : str,
629 'mimetype' : str,
509 'data' : str,
630 'data' : str,
510 }
631 }
511
632
512
633
513 Messages on the REQ/REP socket
634 Messages on the REQ/REP socket
514 ==============================
635 ==============================
515
636
516 This is a socket that goes in the opposite direction: from the kernel to a
637 This is a socket that goes in the opposite direction: from the kernel to a
517 *single* frontend, and its purpose is to allow ``raw_input`` and similar
638 *single* frontend, and its purpose is to allow ``raw_input`` and similar
518 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
639 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
519 client. For now we will keep these messages as simple as possible, since they
640 client. For now we will keep these messages as simple as possible, since they
520 basically only mean to convey the ``raw_input(prompt)`` call.
641 basically only mean to convey the ``raw_input(prompt)`` call.
521
642
522 Message type: ``input_request``::
643 Message type: ``input_request``::
523
644
524 content = { 'prompt' : str }
645 content = { 'prompt' : str }
525
646
526 Message type: ``input_reply``::
647 Message type: ``input_reply``::
527
648
528 content = { 'value' : str }
649 content = { 'value' : str }
529
650
530 .. Note::
651 .. Note::
531
652
532 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
653 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
533 practice the kernel should behave like an interactive program. When a
654 practice the kernel should behave like an interactive program. When a
534 program is opened on the console, the keyboard effectively takes over the
655 program is opened on the console, the keyboard effectively takes over the
535 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
656 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
536 Since the IPython kernel effectively behaves like a console program (albeit
657 Since the IPython kernel effectively behaves like a console program (albeit
537 one whose "keyboard" is actually living in a separate process and
658 one whose "keyboard" is actually living in a separate process and
538 transported over the zmq connection), raw ``stdin`` isn't expected to be
659 transported over the zmq connection), raw ``stdin`` isn't expected to be
539 available.
660 available.
540
661
541
662
542 Heartbeat for kernels
663 Heartbeat for kernels
543 =====================
664 =====================
544
665
545 Initially we had considered using messages like those above over ZMQ for a
666 Initially we had considered using messages like those above over ZMQ for a
546 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
667 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
547 alive at all, even if it may be busy executing user code). But this has the
668 alive at all, even if it may be busy executing user code). But this has the
548 problem that if the kernel is locked inside extension code, it wouldn't execute
669 problem that if the kernel is locked inside extension code, it wouldn't execute
549 the python heartbeat code. But it turns out that we can implement a basic
670 the python heartbeat code. But it turns out that we can implement a basic
550 heartbeat with pure ZMQ, without using any Python messaging at all.
671 heartbeat with pure ZMQ, without using any Python messaging at all.
551
672
552 The monitor sends out a single zmq message (right now, it is a str of the
673 The monitor sends out a single zmq message (right now, it is a str of the
553 monitor's lifetime in seconds), and gets the same message right back, prefixed
674 monitor's lifetime in seconds), and gets the same message right back, prefixed
554 with the zmq identity of the XREQ socket in the heartbeat process. This can be
675 with the zmq identity of the XREQ socket in the heartbeat process. This can be
555 a uuid, or even a full message, but there doesn't seem to be a need for packing
676 a uuid, or even a full message, but there doesn't seem to be a need for packing
556 up a message when the sender and receiver are the exact same Python object.
677 up a message when the sender and receiver are the exact same Python object.
557
678
558 The model is this::
679 The model is this::
559
680
560 monitor.send(str(self.lifetime)) # '1.2345678910'
681 monitor.send(str(self.lifetime)) # '1.2345678910'
561
682
562 and the monitor receives some number of messages of the form::
683 and the monitor receives some number of messages of the form::
563
684
564 ['uuid-abcd-dead-beef', '1.2345678910']
685 ['uuid-abcd-dead-beef', '1.2345678910']
565
686
566 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
687 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
567 the rest is the message sent by the monitor. No Python code ever has any
688 the rest is the message sent by the monitor. No Python code ever has any
568 access to the message between the monitor's send, and the monitor's recv.
689 access to the message between the monitor's send, and the monitor's recv.
569
690
570
691
571 ToDo
692 ToDo
572 ====
693 ====
573
694
574 Missing things include:
695 Missing things include:
575
696
576 * Important: finish thinking through the payload concept and API.
697 * Important: finish thinking through the payload concept and API.
577
698
578 * Important: ensure that we have a good solution for magics like %edit. It's
699 * Important: ensure that we have a good solution for magics like %edit. It's
579 likely that with the payload concept we can build a full solution, but not
700 likely that with the payload concept we can build a full solution, but not
580 100% clear yet.
701 100% clear yet.
581
702
582 * Finishing the details of the heartbeat protocol.
703 * Finishing the details of the heartbeat protocol.
583
704
584 * Signal handling: specify what kind of information kernel should broadcast (or
705 * Signal handling: specify what kind of information kernel should broadcast (or
585 not) when it receives signals.
706 not) when it receives signals.
586
707
587 .. include:: ../links.rst
708 .. include:: ../links.rst
General Comments 0
You need to be logged in to leave comments. Login now