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