##// END OF EJS Templates
Rework messaging to better conform to our spec....
Fernando Perez -
Show More
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,40 b''
1 """Test suite for our zeromq-based messaging specification.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING.txt, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 import sys
11 import time
12
13 import nose.tools as nt
14
15 from ..blockingkernelmanager import BlockingKernelManager
16
17 from IPython.utils import io
18
19 def setup():
20 global KM
21 KM = BlockingKernelManager()
22
23 KM.start_kernel()
24 KM.start_channels()
25 # Give the kernel a chance to come up.
26 time.sleep(1)
27
28 def teardown():
29 io.rprint('Entering teardown...') # dbg
30 io.rprint('Stopping channels and kernel...') # dbg
31 KM.stop_channels()
32 KM.kill_kernel()
33
34
35 # Actual tests
36
37 def test_execute():
38 KM.xreq_channel.execute(code='x=1')
39 KM.xreq_channel.execute(code='print 1')
40
@@ -1,2156 +1,2195 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Main IPython class."""
2 """Main IPython class."""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 # Copyright (C) 2008-2010 The IPython Development Team
7 # Copyright (C) 2008-2010 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 from __future__ import with_statement
17 from __future__ import with_statement
18 from __future__ import absolute_import
18 from __future__ import absolute_import
19
19
20 import __builtin__
20 import __builtin__
21 import abc
21 import abc
22 import codeop
22 import codeop
23 import exceptions
23 import exceptions
24 import new
24 import new
25 import os
25 import os
26 import re
26 import re
27 import string
27 import string
28 import sys
28 import sys
29 import tempfile
29 import tempfile
30 from contextlib import nested
30 from contextlib import nested
31
31
32 from IPython.config.configurable import Configurable
32 from IPython.config.configurable import Configurable
33 from IPython.core import debugger, oinspect
33 from IPython.core import debugger, oinspect
34 from IPython.core import history as ipcorehist
34 from IPython.core import history as ipcorehist
35 from IPython.core import page
35 from IPython.core import page
36 from IPython.core import prefilter
36 from IPython.core import prefilter
37 from IPython.core import shadowns
37 from IPython.core import shadowns
38 from IPython.core import ultratb
38 from IPython.core import ultratb
39 from IPython.core.alias import AliasManager
39 from IPython.core.alias import AliasManager
40 from IPython.core.builtin_trap import BuiltinTrap
40 from IPython.core.builtin_trap import BuiltinTrap
41 from IPython.core.display_trap import DisplayTrap
41 from IPython.core.display_trap import DisplayTrap
42 from IPython.core.displayhook import DisplayHook
42 from IPython.core.displayhook import DisplayHook
43 from IPython.core.error import UsageError
43 from IPython.core.error import UsageError
44 from IPython.core.extensions import ExtensionManager
44 from IPython.core.extensions import ExtensionManager
45 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
46 from IPython.core.inputlist import InputList
46 from IPython.core.inputlist import InputList
47 from IPython.core.logger import Logger
47 from IPython.core.logger import Logger
48 from IPython.core.magic import Magic
48 from IPython.core.magic import Magic
49 from IPython.core.payload import PayloadManager
49 from IPython.core.payload import PayloadManager
50 from IPython.core.plugin import PluginManager
50 from IPython.core.plugin import PluginManager
51 from IPython.core.prefilter import PrefilterManager
51 from IPython.core.prefilter import PrefilterManager
52 from IPython.external.Itpl import ItplNS
52 from IPython.external.Itpl import ItplNS
53 from IPython.utils import PyColorize
53 from IPython.utils import PyColorize
54 from IPython.utils import io
54 from IPython.utils import io
55 from IPython.utils import pickleshare
55 from IPython.utils import pickleshare
56 from IPython.utils.doctestreload import doctest_reload
56 from IPython.utils.doctestreload import doctest_reload
57 from IPython.utils.io import ask_yes_no, rprint
57 from IPython.utils.io import ask_yes_no, rprint
58 from IPython.utils.ipstruct import Struct
58 from IPython.utils.ipstruct import Struct
59 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
59 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
60 from IPython.utils.process import system, getoutput
60 from IPython.utils.process import system, getoutput
61 from IPython.utils.strdispatch import StrDispatch
61 from IPython.utils.strdispatch import StrDispatch
62 from IPython.utils.syspathcontext import prepended_to_syspath
62 from IPython.utils.syspathcontext import prepended_to_syspath
63 from IPython.utils.text import num_ini_spaces
63 from IPython.utils.text import num_ini_spaces
64 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
64 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
65 List, Unicode, Instance, Type)
65 List, Unicode, Instance, Type)
66 from IPython.utils.warn import warn, error, fatal
66 from IPython.utils.warn import warn, error, fatal
67 import IPython.core.hooks
67 import IPython.core.hooks
68
68
69 # from IPython.utils import growl
69 # from IPython.utils import growl
70 # growl.start("IPython")
70 # growl.start("IPython")
71
71
72 #-----------------------------------------------------------------------------
72 #-----------------------------------------------------------------------------
73 # Globals
73 # Globals
74 #-----------------------------------------------------------------------------
74 #-----------------------------------------------------------------------------
75
75
76 # compiled regexps for autoindent management
76 # compiled regexps for autoindent management
77 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
77 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Utilities
80 # Utilities
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82
82
83 # store the builtin raw_input globally, and use this always, in case user code
83 # store the builtin raw_input globally, and use this always, in case user code
84 # overwrites it (like wx.py.PyShell does)
84 # overwrites it (like wx.py.PyShell does)
85 raw_input_original = raw_input
85 raw_input_original = raw_input
86
86
87 def softspace(file, newvalue):
87 def softspace(file, newvalue):
88 """Copied from code.py, to remove the dependency"""
88 """Copied from code.py, to remove the dependency"""
89
89
90 oldvalue = 0
90 oldvalue = 0
91 try:
91 try:
92 oldvalue = file.softspace
92 oldvalue = file.softspace
93 except AttributeError:
93 except AttributeError:
94 pass
94 pass
95 try:
95 try:
96 file.softspace = newvalue
96 file.softspace = newvalue
97 except (AttributeError, TypeError):
97 except (AttributeError, TypeError):
98 # "attribute-less object" or "read-only attributes"
98 # "attribute-less object" or "read-only attributes"
99 pass
99 pass
100 return oldvalue
100 return oldvalue
101
101
102
102
103 def no_op(*a, **kw): pass
103 def no_op(*a, **kw): pass
104
104
105 class SpaceInInput(exceptions.Exception): pass
105 class SpaceInInput(exceptions.Exception): pass
106
106
107 class Bunch: pass
107 class Bunch: pass
108
108
109
109
110 def get_default_colors():
110 def get_default_colors():
111 if sys.platform=='darwin':
111 if sys.platform=='darwin':
112 return "LightBG"
112 return "LightBG"
113 elif os.name=='nt':
113 elif os.name=='nt':
114 return 'Linux'
114 return 'Linux'
115 else:
115 else:
116 return 'Linux'
116 return 'Linux'
117
117
118
118
119 class SeparateStr(Str):
119 class SeparateStr(Str):
120 """A Str subclass to validate separate_in, separate_out, etc.
120 """A Str subclass to validate separate_in, separate_out, etc.
121
121
122 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
122 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
123 """
123 """
124
124
125 def validate(self, obj, value):
125 def validate(self, obj, value):
126 if value == '0': value = ''
126 if value == '0': value = ''
127 value = value.replace('\\n','\n')
127 value = value.replace('\\n','\n')
128 return super(SeparateStr, self).validate(obj, value)
128 return super(SeparateStr, self).validate(obj, value)
129
129
130 class MultipleInstanceError(Exception):
130 class MultipleInstanceError(Exception):
131 pass
131 pass
132
132
133
133
134 #-----------------------------------------------------------------------------
134 #-----------------------------------------------------------------------------
135 # Main IPython class
135 # Main IPython class
136 #-----------------------------------------------------------------------------
136 #-----------------------------------------------------------------------------
137
137
138
138
139 class InteractiveShell(Configurable, Magic):
139 class InteractiveShell(Configurable, Magic):
140 """An enhanced, interactive shell for Python."""
140 """An enhanced, interactive shell for Python."""
141
141
142 _instance = None
142 _instance = None
143 autocall = Enum((0,1,2), default_value=1, config=True)
143 autocall = Enum((0,1,2), default_value=1, config=True)
144 # TODO: remove all autoindent logic and put into frontends.
144 # TODO: remove all autoindent logic and put into frontends.
145 # We can't do this yet because even runlines uses the autoindent.
145 # We can't do this yet because even runlines uses the autoindent.
146 autoindent = CBool(True, config=True)
146 autoindent = CBool(True, config=True)
147 automagic = CBool(True, config=True)
147 automagic = CBool(True, config=True)
148 cache_size = Int(1000, config=True)
148 cache_size = Int(1000, config=True)
149 color_info = CBool(True, config=True)
149 color_info = CBool(True, config=True)
150 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
150 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
151 default_value=get_default_colors(), config=True)
151 default_value=get_default_colors(), config=True)
152 debug = CBool(False, config=True)
152 debug = CBool(False, config=True)
153 deep_reload = CBool(False, config=True)
153 deep_reload = CBool(False, config=True)
154 displayhook_class = Type(DisplayHook)
154 displayhook_class = Type(DisplayHook)
155 filename = Str("<ipython console>")
155 filename = Str("<ipython console>")
156 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
156 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
157 logstart = CBool(False, config=True)
157 logstart = CBool(False, config=True)
158 logfile = Str('', config=True)
158 logfile = Str('', config=True)
159 logappend = Str('', config=True)
159 logappend = Str('', config=True)
160 object_info_string_level = Enum((0,1,2), default_value=0,
160 object_info_string_level = Enum((0,1,2), default_value=0,
161 config=True)
161 config=True)
162 pdb = CBool(False, config=True)
162 pdb = CBool(False, config=True)
163 pprint = CBool(True, config=True)
163 pprint = CBool(True, config=True)
164 profile = Str('', config=True)
164 profile = Str('', config=True)
165 prompt_in1 = Str('In [\\#]: ', config=True)
165 prompt_in1 = Str('In [\\#]: ', config=True)
166 prompt_in2 = Str(' .\\D.: ', config=True)
166 prompt_in2 = Str(' .\\D.: ', config=True)
167 prompt_out = Str('Out[\\#]: ', config=True)
167 prompt_out = Str('Out[\\#]: ', config=True)
168 prompts_pad_left = CBool(True, config=True)
168 prompts_pad_left = CBool(True, config=True)
169 quiet = CBool(False, config=True)
169 quiet = CBool(False, config=True)
170
170
171 # The readline stuff will eventually be moved to the terminal subclass
171 # The readline stuff will eventually be moved to the terminal subclass
172 # but for now, we can't do that as readline is welded in everywhere.
172 # but for now, we can't do that as readline is welded in everywhere.
173 readline_use = CBool(True, config=True)
173 readline_use = CBool(True, config=True)
174 readline_merge_completions = CBool(True, config=True)
174 readline_merge_completions = CBool(True, config=True)
175 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
175 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
176 readline_remove_delims = Str('-/~', config=True)
176 readline_remove_delims = Str('-/~', config=True)
177 readline_parse_and_bind = List([
177 readline_parse_and_bind = List([
178 'tab: complete',
178 'tab: complete',
179 '"\C-l": clear-screen',
179 '"\C-l": clear-screen',
180 'set show-all-if-ambiguous on',
180 'set show-all-if-ambiguous on',
181 '"\C-o": tab-insert',
181 '"\C-o": tab-insert',
182 '"\M-i": " "',
182 '"\M-i": " "',
183 '"\M-o": "\d\d\d\d"',
183 '"\M-o": "\d\d\d\d"',
184 '"\M-I": "\d\d\d\d"',
184 '"\M-I": "\d\d\d\d"',
185 '"\C-r": reverse-search-history',
185 '"\C-r": reverse-search-history',
186 '"\C-s": forward-search-history',
186 '"\C-s": forward-search-history',
187 '"\C-p": history-search-backward',
187 '"\C-p": history-search-backward',
188 '"\C-n": history-search-forward',
188 '"\C-n": history-search-forward',
189 '"\e[A": history-search-backward',
189 '"\e[A": history-search-backward',
190 '"\e[B": history-search-forward',
190 '"\e[B": history-search-forward',
191 '"\C-k": kill-line',
191 '"\C-k": kill-line',
192 '"\C-u": unix-line-discard',
192 '"\C-u": unix-line-discard',
193 ], allow_none=False, config=True)
193 ], allow_none=False, config=True)
194
194
195 # TODO: this part of prompt management should be moved to the frontends.
195 # TODO: this part of prompt management should be moved to the frontends.
196 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
196 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
197 separate_in = SeparateStr('\n', config=True)
197 separate_in = SeparateStr('\n', config=True)
198 separate_out = SeparateStr('', config=True)
198 separate_out = SeparateStr('', config=True)
199 separate_out2 = SeparateStr('', config=True)
199 separate_out2 = SeparateStr('', config=True)
200 wildcards_case_sensitive = CBool(True, config=True)
200 wildcards_case_sensitive = CBool(True, config=True)
201 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
201 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
202 default_value='Context', config=True)
202 default_value='Context', config=True)
203
203
204 # Subcomponents of InteractiveShell
204 # Subcomponents of InteractiveShell
205 alias_manager = Instance('IPython.core.alias.AliasManager')
205 alias_manager = Instance('IPython.core.alias.AliasManager')
206 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
206 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
207 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
207 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
208 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
208 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
209 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
209 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
210 plugin_manager = Instance('IPython.core.plugin.PluginManager')
210 plugin_manager = Instance('IPython.core.plugin.PluginManager')
211 payload_manager = Instance('IPython.core.payload.PayloadManager')
211 payload_manager = Instance('IPython.core.payload.PayloadManager')
212
212
213 def __init__(self, config=None, ipython_dir=None,
213 def __init__(self, config=None, ipython_dir=None,
214 user_ns=None, user_global_ns=None,
214 user_ns=None, user_global_ns=None,
215 custom_exceptions=((),None)):
215 custom_exceptions=((),None)):
216
216
217 # This is where traits with a config_key argument are updated
217 # This is where traits with a config_key argument are updated
218 # from the values on config.
218 # from the values on config.
219 super(InteractiveShell, self).__init__(config=config)
219 super(InteractiveShell, self).__init__(config=config)
220
220
221 # These are relatively independent and stateless
221 # These are relatively independent and stateless
222 self.init_ipython_dir(ipython_dir)
222 self.init_ipython_dir(ipython_dir)
223 self.init_instance_attrs()
223 self.init_instance_attrs()
224
224
225 # Create namespaces (user_ns, user_global_ns, etc.)
225 # Create namespaces (user_ns, user_global_ns, etc.)
226 self.init_create_namespaces(user_ns, user_global_ns)
226 self.init_create_namespaces(user_ns, user_global_ns)
227 # This has to be done after init_create_namespaces because it uses
227 # This has to be done after init_create_namespaces because it uses
228 # something in self.user_ns, but before init_sys_modules, which
228 # something in self.user_ns, but before init_sys_modules, which
229 # is the first thing to modify sys.
229 # is the first thing to modify sys.
230 # TODO: When we override sys.stdout and sys.stderr before this class
230 # TODO: When we override sys.stdout and sys.stderr before this class
231 # is created, we are saving the overridden ones here. Not sure if this
231 # is created, we are saving the overridden ones here. Not sure if this
232 # is what we want to do.
232 # is what we want to do.
233 self.save_sys_module_state()
233 self.save_sys_module_state()
234 self.init_sys_modules()
234 self.init_sys_modules()
235
235
236 self.init_history()
236 self.init_history()
237 self.init_encoding()
237 self.init_encoding()
238 self.init_prefilter()
238 self.init_prefilter()
239
239
240 Magic.__init__(self, self)
240 Magic.__init__(self, self)
241
241
242 self.init_syntax_highlighting()
242 self.init_syntax_highlighting()
243 self.init_hooks()
243 self.init_hooks()
244 self.init_pushd_popd_magic()
244 self.init_pushd_popd_magic()
245 # self.init_traceback_handlers use to be here, but we moved it below
245 # self.init_traceback_handlers use to be here, but we moved it below
246 # because it and init_io have to come after init_readline.
246 # because it and init_io have to come after init_readline.
247 self.init_user_ns()
247 self.init_user_ns()
248 self.init_logger()
248 self.init_logger()
249 self.init_alias()
249 self.init_alias()
250 self.init_builtins()
250 self.init_builtins()
251
251
252 # pre_config_initialization
252 # pre_config_initialization
253 self.init_shadow_hist()
253 self.init_shadow_hist()
254
254
255 # The next section should contain averything that was in ipmaker.
255 # The next section should contain averything that was in ipmaker.
256 self.init_logstart()
256 self.init_logstart()
257
257
258 # The following was in post_config_initialization
258 # The following was in post_config_initialization
259 self.init_inspector()
259 self.init_inspector()
260 # init_readline() must come before init_io(), because init_io uses
260 # init_readline() must come before init_io(), because init_io uses
261 # readline related things.
261 # readline related things.
262 self.init_readline()
262 self.init_readline()
263 # TODO: init_io() needs to happen before init_traceback handlers
263 # TODO: init_io() needs to happen before init_traceback handlers
264 # because the traceback handlers hardcode the stdout/stderr streams.
264 # because the traceback handlers hardcode the stdout/stderr streams.
265 # This logic in in debugger.Pdb and should eventually be changed.
265 # This logic in in debugger.Pdb and should eventually be changed.
266 self.init_io()
266 self.init_io()
267 self.init_traceback_handlers(custom_exceptions)
267 self.init_traceback_handlers(custom_exceptions)
268 self.init_prompts()
268 self.init_prompts()
269 self.init_displayhook()
269 self.init_displayhook()
270 self.init_reload_doctest()
270 self.init_reload_doctest()
271 self.init_magics()
271 self.init_magics()
272 self.init_pdb()
272 self.init_pdb()
273 self.init_extension_manager()
273 self.init_extension_manager()
274 self.init_plugin_manager()
274 self.init_plugin_manager()
275 self.init_payload()
275 self.init_payload()
276 self.hooks.late_startup_hook()
276 self.hooks.late_startup_hook()
277
277
278 @classmethod
278 @classmethod
279 def instance(cls, *args, **kwargs):
279 def instance(cls, *args, **kwargs):
280 """Returns a global InteractiveShell instance."""
280 """Returns a global InteractiveShell instance."""
281 if cls._instance is None:
281 if cls._instance is None:
282 inst = cls(*args, **kwargs)
282 inst = cls(*args, **kwargs)
283 # Now make sure that the instance will also be returned by
283 # Now make sure that the instance will also be returned by
284 # the subclasses instance attribute.
284 # the subclasses instance attribute.
285 for subclass in cls.mro():
285 for subclass in cls.mro():
286 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
286 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
287 subclass._instance = inst
287 subclass._instance = inst
288 else:
288 else:
289 break
289 break
290 if isinstance(cls._instance, cls):
290 if isinstance(cls._instance, cls):
291 return cls._instance
291 return cls._instance
292 else:
292 else:
293 raise MultipleInstanceError(
293 raise MultipleInstanceError(
294 'Multiple incompatible subclass instances of '
294 'Multiple incompatible subclass instances of '
295 'InteractiveShell are being created.'
295 'InteractiveShell are being created.'
296 )
296 )
297
297
298 @classmethod
298 @classmethod
299 def initialized(cls):
299 def initialized(cls):
300 return hasattr(cls, "_instance")
300 return hasattr(cls, "_instance")
301
301
302 def get_ipython(self):
302 def get_ipython(self):
303 """Return the currently running IPython instance."""
303 """Return the currently running IPython instance."""
304 return self
304 return self
305
305
306 #-------------------------------------------------------------------------
306 #-------------------------------------------------------------------------
307 # Trait changed handlers
307 # Trait changed handlers
308 #-------------------------------------------------------------------------
308 #-------------------------------------------------------------------------
309
309
310 def _ipython_dir_changed(self, name, new):
310 def _ipython_dir_changed(self, name, new):
311 if not os.path.isdir(new):
311 if not os.path.isdir(new):
312 os.makedirs(new, mode = 0777)
312 os.makedirs(new, mode = 0777)
313
313
314 def set_autoindent(self,value=None):
314 def set_autoindent(self,value=None):
315 """Set the autoindent flag, checking for readline support.
315 """Set the autoindent flag, checking for readline support.
316
316
317 If called with no arguments, it acts as a toggle."""
317 If called with no arguments, it acts as a toggle."""
318
318
319 if not self.has_readline:
319 if not self.has_readline:
320 if os.name == 'posix':
320 if os.name == 'posix':
321 warn("The auto-indent feature requires the readline library")
321 warn("The auto-indent feature requires the readline library")
322 self.autoindent = 0
322 self.autoindent = 0
323 return
323 return
324 if value is None:
324 if value is None:
325 self.autoindent = not self.autoindent
325 self.autoindent = not self.autoindent
326 else:
326 else:
327 self.autoindent = value
327 self.autoindent = value
328
328
329 #-------------------------------------------------------------------------
329 #-------------------------------------------------------------------------
330 # init_* methods called by __init__
330 # init_* methods called by __init__
331 #-------------------------------------------------------------------------
331 #-------------------------------------------------------------------------
332
332
333 def init_ipython_dir(self, ipython_dir):
333 def init_ipython_dir(self, ipython_dir):
334 if ipython_dir is not None:
334 if ipython_dir is not None:
335 self.ipython_dir = ipython_dir
335 self.ipython_dir = ipython_dir
336 self.config.Global.ipython_dir = self.ipython_dir
336 self.config.Global.ipython_dir = self.ipython_dir
337 return
337 return
338
338
339 if hasattr(self.config.Global, 'ipython_dir'):
339 if hasattr(self.config.Global, 'ipython_dir'):
340 self.ipython_dir = self.config.Global.ipython_dir
340 self.ipython_dir = self.config.Global.ipython_dir
341 else:
341 else:
342 self.ipython_dir = get_ipython_dir()
342 self.ipython_dir = get_ipython_dir()
343
343
344 # All children can just read this
344 # All children can just read this
345 self.config.Global.ipython_dir = self.ipython_dir
345 self.config.Global.ipython_dir = self.ipython_dir
346
346
347 def init_instance_attrs(self):
347 def init_instance_attrs(self):
348 self.more = False
348 self.more = False
349
349
350 # command compiler
350 # command compiler
351 self.compile = codeop.CommandCompiler()
351 self.compile = codeop.CommandCompiler()
352
352
353 # User input buffer
353 # User input buffer
354 self.buffer = []
354 self.buffer = []
355
355
356 # Make an empty namespace, which extension writers can rely on both
356 # Make an empty namespace, which extension writers can rely on both
357 # existing and NEVER being used by ipython itself. This gives them a
357 # existing and NEVER being used by ipython itself. This gives them a
358 # convenient location for storing additional information and state
358 # convenient location for storing additional information and state
359 # their extensions may require, without fear of collisions with other
359 # their extensions may require, without fear of collisions with other
360 # ipython names that may develop later.
360 # ipython names that may develop later.
361 self.meta = Struct()
361 self.meta = Struct()
362
362
363 # Object variable to store code object waiting execution. This is
363 # Object variable to store code object waiting execution. This is
364 # used mainly by the multithreaded shells, but it can come in handy in
364 # used mainly by the multithreaded shells, but it can come in handy in
365 # other situations. No need to use a Queue here, since it's a single
365 # other situations. No need to use a Queue here, since it's a single
366 # item which gets cleared once run.
366 # item which gets cleared once run.
367 self.code_to_run = None
367 self.code_to_run = None
368
368
369 # Temporary files used for various purposes. Deleted at exit.
369 # Temporary files used for various purposes. Deleted at exit.
370 self.tempfiles = []
370 self.tempfiles = []
371
371
372 # Keep track of readline usage (later set by init_readline)
372 # Keep track of readline usage (later set by init_readline)
373 self.has_readline = False
373 self.has_readline = False
374
374
375 # keep track of where we started running (mainly for crash post-mortem)
375 # keep track of where we started running (mainly for crash post-mortem)
376 # This is not being used anywhere currently.
376 # This is not being used anywhere currently.
377 self.starting_dir = os.getcwd()
377 self.starting_dir = os.getcwd()
378
378
379 # Indentation management
379 # Indentation management
380 self.indent_current_nsp = 0
380 self.indent_current_nsp = 0
381
381
382 def init_encoding(self):
382 def init_encoding(self):
383 # Get system encoding at startup time. Certain terminals (like Emacs
383 # Get system encoding at startup time. Certain terminals (like Emacs
384 # under Win32 have it set to None, and we need to have a known valid
384 # under Win32 have it set to None, and we need to have a known valid
385 # encoding to use in the raw_input() method
385 # encoding to use in the raw_input() method
386 try:
386 try:
387 self.stdin_encoding = sys.stdin.encoding or 'ascii'
387 self.stdin_encoding = sys.stdin.encoding or 'ascii'
388 except AttributeError:
388 except AttributeError:
389 self.stdin_encoding = 'ascii'
389 self.stdin_encoding = 'ascii'
390
390
391 def init_syntax_highlighting(self):
391 def init_syntax_highlighting(self):
392 # Python source parser/formatter for syntax highlighting
392 # Python source parser/formatter for syntax highlighting
393 pyformat = PyColorize.Parser().format
393 pyformat = PyColorize.Parser().format
394 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
394 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
395
395
396 def init_pushd_popd_magic(self):
396 def init_pushd_popd_magic(self):
397 # for pushd/popd management
397 # for pushd/popd management
398 try:
398 try:
399 self.home_dir = get_home_dir()
399 self.home_dir = get_home_dir()
400 except HomeDirError, msg:
400 except HomeDirError, msg:
401 fatal(msg)
401 fatal(msg)
402
402
403 self.dir_stack = []
403 self.dir_stack = []
404
404
405 def init_logger(self):
405 def init_logger(self):
406 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
406 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
407 # local shortcut, this is used a LOT
407 # local shortcut, this is used a LOT
408 self.log = self.logger.log
408 self.log = self.logger.log
409
409
410 def init_logstart(self):
410 def init_logstart(self):
411 if self.logappend:
411 if self.logappend:
412 self.magic_logstart(self.logappend + ' append')
412 self.magic_logstart(self.logappend + ' append')
413 elif self.logfile:
413 elif self.logfile:
414 self.magic_logstart(self.logfile)
414 self.magic_logstart(self.logfile)
415 elif self.logstart:
415 elif self.logstart:
416 self.magic_logstart()
416 self.magic_logstart()
417
417
418 def init_builtins(self):
418 def init_builtins(self):
419 self.builtin_trap = BuiltinTrap(shell=self)
419 self.builtin_trap = BuiltinTrap(shell=self)
420
420
421 def init_inspector(self):
421 def init_inspector(self):
422 # Object inspector
422 # Object inspector
423 self.inspector = oinspect.Inspector(oinspect.InspectColors,
423 self.inspector = oinspect.Inspector(oinspect.InspectColors,
424 PyColorize.ANSICodeColors,
424 PyColorize.ANSICodeColors,
425 'NoColor',
425 'NoColor',
426 self.object_info_string_level)
426 self.object_info_string_level)
427
427
428 def init_io(self):
428 def init_io(self):
429 import IPython.utils.io
429 import IPython.utils.io
430 if sys.platform == 'win32' and self.has_readline:
430 if sys.platform == 'win32' and self.has_readline:
431 Term = io.IOTerm(
431 Term = io.IOTerm(
432 cout=self.readline._outputfile,cerr=self.readline._outputfile
432 cout=self.readline._outputfile,cerr=self.readline._outputfile
433 )
433 )
434 else:
434 else:
435 Term = io.IOTerm()
435 Term = io.IOTerm()
436 io.Term = Term
436 io.Term = Term
437
437
438 def init_prompts(self):
438 def init_prompts(self):
439 # TODO: This is a pass for now because the prompts are managed inside
439 # TODO: This is a pass for now because the prompts are managed inside
440 # the DisplayHook. Once there is a separate prompt manager, this
440 # the DisplayHook. Once there is a separate prompt manager, this
441 # will initialize that object and all prompt related information.
441 # will initialize that object and all prompt related information.
442 pass
442 pass
443
443
444 def init_displayhook(self):
444 def init_displayhook(self):
445 # Initialize displayhook, set in/out prompts and printing system
445 # Initialize displayhook, set in/out prompts and printing system
446 self.displayhook = self.displayhook_class(
446 self.displayhook = self.displayhook_class(
447 shell=self,
447 shell=self,
448 cache_size=self.cache_size,
448 cache_size=self.cache_size,
449 input_sep = self.separate_in,
449 input_sep = self.separate_in,
450 output_sep = self.separate_out,
450 output_sep = self.separate_out,
451 output_sep2 = self.separate_out2,
451 output_sep2 = self.separate_out2,
452 ps1 = self.prompt_in1,
452 ps1 = self.prompt_in1,
453 ps2 = self.prompt_in2,
453 ps2 = self.prompt_in2,
454 ps_out = self.prompt_out,
454 ps_out = self.prompt_out,
455 pad_left = self.prompts_pad_left
455 pad_left = self.prompts_pad_left
456 )
456 )
457 # This is a context manager that installs/revmoes the displayhook at
457 # This is a context manager that installs/revmoes the displayhook at
458 # the appropriate time.
458 # the appropriate time.
459 self.display_trap = DisplayTrap(hook=self.displayhook)
459 self.display_trap = DisplayTrap(hook=self.displayhook)
460
460
461 def init_reload_doctest(self):
461 def init_reload_doctest(self):
462 # Do a proper resetting of doctest, including the necessary displayhook
462 # Do a proper resetting of doctest, including the necessary displayhook
463 # monkeypatching
463 # monkeypatching
464 try:
464 try:
465 doctest_reload()
465 doctest_reload()
466 except ImportError:
466 except ImportError:
467 warn("doctest module does not exist.")
467 warn("doctest module does not exist.")
468
468
469 #-------------------------------------------------------------------------
469 #-------------------------------------------------------------------------
470 # Things related to injections into the sys module
470 # Things related to injections into the sys module
471 #-------------------------------------------------------------------------
471 #-------------------------------------------------------------------------
472
472
473 def save_sys_module_state(self):
473 def save_sys_module_state(self):
474 """Save the state of hooks in the sys module.
474 """Save the state of hooks in the sys module.
475
475
476 This has to be called after self.user_ns is created.
476 This has to be called after self.user_ns is created.
477 """
477 """
478 self._orig_sys_module_state = {}
478 self._orig_sys_module_state = {}
479 self._orig_sys_module_state['stdin'] = sys.stdin
479 self._orig_sys_module_state['stdin'] = sys.stdin
480 self._orig_sys_module_state['stdout'] = sys.stdout
480 self._orig_sys_module_state['stdout'] = sys.stdout
481 self._orig_sys_module_state['stderr'] = sys.stderr
481 self._orig_sys_module_state['stderr'] = sys.stderr
482 self._orig_sys_module_state['excepthook'] = sys.excepthook
482 self._orig_sys_module_state['excepthook'] = sys.excepthook
483 try:
483 try:
484 self._orig_sys_modules_main_name = self.user_ns['__name__']
484 self._orig_sys_modules_main_name = self.user_ns['__name__']
485 except KeyError:
485 except KeyError:
486 pass
486 pass
487
487
488 def restore_sys_module_state(self):
488 def restore_sys_module_state(self):
489 """Restore the state of the sys module."""
489 """Restore the state of the sys module."""
490 try:
490 try:
491 for k, v in self._orig_sys_module_state.items():
491 for k, v in self._orig_sys_module_state.items():
492 setattr(sys, k, v)
492 setattr(sys, k, v)
493 except AttributeError:
493 except AttributeError:
494 pass
494 pass
495 try:
495 try:
496 delattr(sys, 'ipcompleter')
496 delattr(sys, 'ipcompleter')
497 except AttributeError:
497 except AttributeError:
498 pass
498 pass
499 # Reset what what done in self.init_sys_modules
499 # Reset what what done in self.init_sys_modules
500 try:
500 try:
501 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
501 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
502 except (AttributeError, KeyError):
502 except (AttributeError, KeyError):
503 pass
503 pass
504
504
505 #-------------------------------------------------------------------------
505 #-------------------------------------------------------------------------
506 # Things related to hooks
506 # Things related to hooks
507 #-------------------------------------------------------------------------
507 #-------------------------------------------------------------------------
508
508
509 def init_hooks(self):
509 def init_hooks(self):
510 # hooks holds pointers used for user-side customizations
510 # hooks holds pointers used for user-side customizations
511 self.hooks = Struct()
511 self.hooks = Struct()
512
512
513 self.strdispatchers = {}
513 self.strdispatchers = {}
514
514
515 # Set all default hooks, defined in the IPython.hooks module.
515 # Set all default hooks, defined in the IPython.hooks module.
516 hooks = IPython.core.hooks
516 hooks = IPython.core.hooks
517 for hook_name in hooks.__all__:
517 for hook_name in hooks.__all__:
518 # default hooks have priority 100, i.e. low; user hooks should have
518 # default hooks have priority 100, i.e. low; user hooks should have
519 # 0-100 priority
519 # 0-100 priority
520 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
520 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
521
521
522 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
522 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
523 """set_hook(name,hook) -> sets an internal IPython hook.
523 """set_hook(name,hook) -> sets an internal IPython hook.
524
524
525 IPython exposes some of its internal API as user-modifiable hooks. By
525 IPython exposes some of its internal API as user-modifiable hooks. By
526 adding your function to one of these hooks, you can modify IPython's
526 adding your function to one of these hooks, you can modify IPython's
527 behavior to call at runtime your own routines."""
527 behavior to call at runtime your own routines."""
528
528
529 # At some point in the future, this should validate the hook before it
529 # At some point in the future, this should validate the hook before it
530 # accepts it. Probably at least check that the hook takes the number
530 # accepts it. Probably at least check that the hook takes the number
531 # of args it's supposed to.
531 # of args it's supposed to.
532
532
533 f = new.instancemethod(hook,self,self.__class__)
533 f = new.instancemethod(hook,self,self.__class__)
534
534
535 # check if the hook is for strdispatcher first
535 # check if the hook is for strdispatcher first
536 if str_key is not None:
536 if str_key is not None:
537 sdp = self.strdispatchers.get(name, StrDispatch())
537 sdp = self.strdispatchers.get(name, StrDispatch())
538 sdp.add_s(str_key, f, priority )
538 sdp.add_s(str_key, f, priority )
539 self.strdispatchers[name] = sdp
539 self.strdispatchers[name] = sdp
540 return
540 return
541 if re_key is not None:
541 if re_key is not None:
542 sdp = self.strdispatchers.get(name, StrDispatch())
542 sdp = self.strdispatchers.get(name, StrDispatch())
543 sdp.add_re(re.compile(re_key), f, priority )
543 sdp.add_re(re.compile(re_key), f, priority )
544 self.strdispatchers[name] = sdp
544 self.strdispatchers[name] = sdp
545 return
545 return
546
546
547 dp = getattr(self.hooks, name, None)
547 dp = getattr(self.hooks, name, None)
548 if name not in IPython.core.hooks.__all__:
548 if name not in IPython.core.hooks.__all__:
549 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
549 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
550 if not dp:
550 if not dp:
551 dp = IPython.core.hooks.CommandChainDispatcher()
551 dp = IPython.core.hooks.CommandChainDispatcher()
552
552
553 try:
553 try:
554 dp.add(f,priority)
554 dp.add(f,priority)
555 except AttributeError:
555 except AttributeError:
556 # it was not commandchain, plain old func - replace
556 # it was not commandchain, plain old func - replace
557 dp = f
557 dp = f
558
558
559 setattr(self.hooks,name, dp)
559 setattr(self.hooks,name, dp)
560
560
561 #-------------------------------------------------------------------------
561 #-------------------------------------------------------------------------
562 # Things related to the "main" module
562 # Things related to the "main" module
563 #-------------------------------------------------------------------------
563 #-------------------------------------------------------------------------
564
564
565 def new_main_mod(self,ns=None):
565 def new_main_mod(self,ns=None):
566 """Return a new 'main' module object for user code execution.
566 """Return a new 'main' module object for user code execution.
567 """
567 """
568 main_mod = self._user_main_module
568 main_mod = self._user_main_module
569 init_fakemod_dict(main_mod,ns)
569 init_fakemod_dict(main_mod,ns)
570 return main_mod
570 return main_mod
571
571
572 def cache_main_mod(self,ns,fname):
572 def cache_main_mod(self,ns,fname):
573 """Cache a main module's namespace.
573 """Cache a main module's namespace.
574
574
575 When scripts are executed via %run, we must keep a reference to the
575 When scripts are executed via %run, we must keep a reference to the
576 namespace of their __main__ module (a FakeModule instance) around so
576 namespace of their __main__ module (a FakeModule instance) around so
577 that Python doesn't clear it, rendering objects defined therein
577 that Python doesn't clear it, rendering objects defined therein
578 useless.
578 useless.
579
579
580 This method keeps said reference in a private dict, keyed by the
580 This method keeps said reference in a private dict, keyed by the
581 absolute path of the module object (which corresponds to the script
581 absolute path of the module object (which corresponds to the script
582 path). This way, for multiple executions of the same script we only
582 path). This way, for multiple executions of the same script we only
583 keep one copy of the namespace (the last one), thus preventing memory
583 keep one copy of the namespace (the last one), thus preventing memory
584 leaks from old references while allowing the objects from the last
584 leaks from old references while allowing the objects from the last
585 execution to be accessible.
585 execution to be accessible.
586
586
587 Note: we can not allow the actual FakeModule instances to be deleted,
587 Note: we can not allow the actual FakeModule instances to be deleted,
588 because of how Python tears down modules (it hard-sets all their
588 because of how Python tears down modules (it hard-sets all their
589 references to None without regard for reference counts). This method
589 references to None without regard for reference counts). This method
590 must therefore make a *copy* of the given namespace, to allow the
590 must therefore make a *copy* of the given namespace, to allow the
591 original module's __dict__ to be cleared and reused.
591 original module's __dict__ to be cleared and reused.
592
592
593
593
594 Parameters
594 Parameters
595 ----------
595 ----------
596 ns : a namespace (a dict, typically)
596 ns : a namespace (a dict, typically)
597
597
598 fname : str
598 fname : str
599 Filename associated with the namespace.
599 Filename associated with the namespace.
600
600
601 Examples
601 Examples
602 --------
602 --------
603
603
604 In [10]: import IPython
604 In [10]: import IPython
605
605
606 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
606 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
607
607
608 In [12]: IPython.__file__ in _ip._main_ns_cache
608 In [12]: IPython.__file__ in _ip._main_ns_cache
609 Out[12]: True
609 Out[12]: True
610 """
610 """
611 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
611 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
612
612
613 def clear_main_mod_cache(self):
613 def clear_main_mod_cache(self):
614 """Clear the cache of main modules.
614 """Clear the cache of main modules.
615
615
616 Mainly for use by utilities like %reset.
616 Mainly for use by utilities like %reset.
617
617
618 Examples
618 Examples
619 --------
619 --------
620
620
621 In [15]: import IPython
621 In [15]: import IPython
622
622
623 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
623 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
624
624
625 In [17]: len(_ip._main_ns_cache) > 0
625 In [17]: len(_ip._main_ns_cache) > 0
626 Out[17]: True
626 Out[17]: True
627
627
628 In [18]: _ip.clear_main_mod_cache()
628 In [18]: _ip.clear_main_mod_cache()
629
629
630 In [19]: len(_ip._main_ns_cache) == 0
630 In [19]: len(_ip._main_ns_cache) == 0
631 Out[19]: True
631 Out[19]: True
632 """
632 """
633 self._main_ns_cache.clear()
633 self._main_ns_cache.clear()
634
634
635 #-------------------------------------------------------------------------
635 #-------------------------------------------------------------------------
636 # Things related to debugging
636 # Things related to debugging
637 #-------------------------------------------------------------------------
637 #-------------------------------------------------------------------------
638
638
639 def init_pdb(self):
639 def init_pdb(self):
640 # Set calling of pdb on exceptions
640 # Set calling of pdb on exceptions
641 # self.call_pdb is a property
641 # self.call_pdb is a property
642 self.call_pdb = self.pdb
642 self.call_pdb = self.pdb
643
643
644 def _get_call_pdb(self):
644 def _get_call_pdb(self):
645 return self._call_pdb
645 return self._call_pdb
646
646
647 def _set_call_pdb(self,val):
647 def _set_call_pdb(self,val):
648
648
649 if val not in (0,1,False,True):
649 if val not in (0,1,False,True):
650 raise ValueError,'new call_pdb value must be boolean'
650 raise ValueError,'new call_pdb value must be boolean'
651
651
652 # store value in instance
652 # store value in instance
653 self._call_pdb = val
653 self._call_pdb = val
654
654
655 # notify the actual exception handlers
655 # notify the actual exception handlers
656 self.InteractiveTB.call_pdb = val
656 self.InteractiveTB.call_pdb = val
657
657
658 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
658 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
659 'Control auto-activation of pdb at exceptions')
659 'Control auto-activation of pdb at exceptions')
660
660
661 def debugger(self,force=False):
661 def debugger(self,force=False):
662 """Call the pydb/pdb debugger.
662 """Call the pydb/pdb debugger.
663
663
664 Keywords:
664 Keywords:
665
665
666 - force(False): by default, this routine checks the instance call_pdb
666 - force(False): by default, this routine checks the instance call_pdb
667 flag and does not actually invoke the debugger if the flag is false.
667 flag and does not actually invoke the debugger if the flag is false.
668 The 'force' option forces the debugger to activate even if the flag
668 The 'force' option forces the debugger to activate even if the flag
669 is false.
669 is false.
670 """
670 """
671
671
672 if not (force or self.call_pdb):
672 if not (force or self.call_pdb):
673 return
673 return
674
674
675 if not hasattr(sys,'last_traceback'):
675 if not hasattr(sys,'last_traceback'):
676 error('No traceback has been produced, nothing to debug.')
676 error('No traceback has been produced, nothing to debug.')
677 return
677 return
678
678
679 # use pydb if available
679 # use pydb if available
680 if debugger.has_pydb:
680 if debugger.has_pydb:
681 from pydb import pm
681 from pydb import pm
682 else:
682 else:
683 # fallback to our internal debugger
683 # fallback to our internal debugger
684 pm = lambda : self.InteractiveTB.debugger(force=True)
684 pm = lambda : self.InteractiveTB.debugger(force=True)
685 self.history_saving_wrapper(pm)()
685 self.history_saving_wrapper(pm)()
686
686
687 #-------------------------------------------------------------------------
687 #-------------------------------------------------------------------------
688 # Things related to IPython's various namespaces
688 # Things related to IPython's various namespaces
689 #-------------------------------------------------------------------------
689 #-------------------------------------------------------------------------
690
690
691 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
691 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
692 # Create the namespace where the user will operate. user_ns is
692 # Create the namespace where the user will operate. user_ns is
693 # normally the only one used, and it is passed to the exec calls as
693 # normally the only one used, and it is passed to the exec calls as
694 # the locals argument. But we do carry a user_global_ns namespace
694 # the locals argument. But we do carry a user_global_ns namespace
695 # given as the exec 'globals' argument, This is useful in embedding
695 # given as the exec 'globals' argument, This is useful in embedding
696 # situations where the ipython shell opens in a context where the
696 # situations where the ipython shell opens in a context where the
697 # distinction between locals and globals is meaningful. For
697 # distinction between locals and globals is meaningful. For
698 # non-embedded contexts, it is just the same object as the user_ns dict.
698 # non-embedded contexts, it is just the same object as the user_ns dict.
699
699
700 # FIXME. For some strange reason, __builtins__ is showing up at user
700 # FIXME. For some strange reason, __builtins__ is showing up at user
701 # level as a dict instead of a module. This is a manual fix, but I
701 # level as a dict instead of a module. This is a manual fix, but I
702 # should really track down where the problem is coming from. Alex
702 # should really track down where the problem is coming from. Alex
703 # Schmolck reported this problem first.
703 # Schmolck reported this problem first.
704
704
705 # A useful post by Alex Martelli on this topic:
705 # A useful post by Alex Martelli on this topic:
706 # Re: inconsistent value from __builtins__
706 # Re: inconsistent value from __builtins__
707 # Von: Alex Martelli <aleaxit@yahoo.com>
707 # Von: Alex Martelli <aleaxit@yahoo.com>
708 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
708 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
709 # Gruppen: comp.lang.python
709 # Gruppen: comp.lang.python
710
710
711 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
711 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
712 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
712 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
713 # > <type 'dict'>
713 # > <type 'dict'>
714 # > >>> print type(__builtins__)
714 # > >>> print type(__builtins__)
715 # > <type 'module'>
715 # > <type 'module'>
716 # > Is this difference in return value intentional?
716 # > Is this difference in return value intentional?
717
717
718 # Well, it's documented that '__builtins__' can be either a dictionary
718 # Well, it's documented that '__builtins__' can be either a dictionary
719 # or a module, and it's been that way for a long time. Whether it's
719 # or a module, and it's been that way for a long time. Whether it's
720 # intentional (or sensible), I don't know. In any case, the idea is
720 # intentional (or sensible), I don't know. In any case, the idea is
721 # that if you need to access the built-in namespace directly, you
721 # that if you need to access the built-in namespace directly, you
722 # should start with "import __builtin__" (note, no 's') which will
722 # should start with "import __builtin__" (note, no 's') which will
723 # definitely give you a module. Yeah, it's somewhat confusing:-(.
723 # definitely give you a module. Yeah, it's somewhat confusing:-(.
724
724
725 # These routines return properly built dicts as needed by the rest of
725 # These routines return properly built dicts as needed by the rest of
726 # the code, and can also be used by extension writers to generate
726 # the code, and can also be used by extension writers to generate
727 # properly initialized namespaces.
727 # properly initialized namespaces.
728 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
728 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
729
729
730 # Assign namespaces
730 # Assign namespaces
731 # This is the namespace where all normal user variables live
731 # This is the namespace where all normal user variables live
732 self.user_ns = user_ns
732 self.user_ns = user_ns
733 self.user_global_ns = user_global_ns
733 self.user_global_ns = user_global_ns
734
734
735 # An auxiliary namespace that checks what parts of the user_ns were
735 # An auxiliary namespace that checks what parts of the user_ns were
736 # loaded at startup, so we can list later only variables defined in
736 # loaded at startup, so we can list later only variables defined in
737 # actual interactive use. Since it is always a subset of user_ns, it
737 # actual interactive use. Since it is always a subset of user_ns, it
738 # doesn't need to be separately tracked in the ns_table.
738 # doesn't need to be separately tracked in the ns_table.
739 self.user_ns_hidden = {}
739 self.user_ns_hidden = {}
740
740
741 # A namespace to keep track of internal data structures to prevent
741 # A namespace to keep track of internal data structures to prevent
742 # them from cluttering user-visible stuff. Will be updated later
742 # them from cluttering user-visible stuff. Will be updated later
743 self.internal_ns = {}
743 self.internal_ns = {}
744
744
745 # Now that FakeModule produces a real module, we've run into a nasty
745 # Now that FakeModule produces a real module, we've run into a nasty
746 # problem: after script execution (via %run), the module where the user
746 # problem: after script execution (via %run), the module where the user
747 # code ran is deleted. Now that this object is a true module (needed
747 # code ran is deleted. Now that this object is a true module (needed
748 # so docetst and other tools work correctly), the Python module
748 # so docetst and other tools work correctly), the Python module
749 # teardown mechanism runs over it, and sets to None every variable
749 # teardown mechanism runs over it, and sets to None every variable
750 # present in that module. Top-level references to objects from the
750 # present in that module. Top-level references to objects from the
751 # script survive, because the user_ns is updated with them. However,
751 # script survive, because the user_ns is updated with them. However,
752 # calling functions defined in the script that use other things from
752 # calling functions defined in the script that use other things from
753 # the script will fail, because the function's closure had references
753 # the script will fail, because the function's closure had references
754 # to the original objects, which are now all None. So we must protect
754 # to the original objects, which are now all None. So we must protect
755 # these modules from deletion by keeping a cache.
755 # these modules from deletion by keeping a cache.
756 #
756 #
757 # To avoid keeping stale modules around (we only need the one from the
757 # To avoid keeping stale modules around (we only need the one from the
758 # last run), we use a dict keyed with the full path to the script, so
758 # last run), we use a dict keyed with the full path to the script, so
759 # only the last version of the module is held in the cache. Note,
759 # only the last version of the module is held in the cache. Note,
760 # however, that we must cache the module *namespace contents* (their
760 # however, that we must cache the module *namespace contents* (their
761 # __dict__). Because if we try to cache the actual modules, old ones
761 # __dict__). Because if we try to cache the actual modules, old ones
762 # (uncached) could be destroyed while still holding references (such as
762 # (uncached) could be destroyed while still holding references (such as
763 # those held by GUI objects that tend to be long-lived)>
763 # those held by GUI objects that tend to be long-lived)>
764 #
764 #
765 # The %reset command will flush this cache. See the cache_main_mod()
765 # The %reset command will flush this cache. See the cache_main_mod()
766 # and clear_main_mod_cache() methods for details on use.
766 # and clear_main_mod_cache() methods for details on use.
767
767
768 # This is the cache used for 'main' namespaces
768 # This is the cache used for 'main' namespaces
769 self._main_ns_cache = {}
769 self._main_ns_cache = {}
770 # And this is the single instance of FakeModule whose __dict__ we keep
770 # And this is the single instance of FakeModule whose __dict__ we keep
771 # copying and clearing for reuse on each %run
771 # copying and clearing for reuse on each %run
772 self._user_main_module = FakeModule()
772 self._user_main_module = FakeModule()
773
773
774 # A table holding all the namespaces IPython deals with, so that
774 # A table holding all the namespaces IPython deals with, so that
775 # introspection facilities can search easily.
775 # introspection facilities can search easily.
776 self.ns_table = {'user':user_ns,
776 self.ns_table = {'user':user_ns,
777 'user_global':user_global_ns,
777 'user_global':user_global_ns,
778 'internal':self.internal_ns,
778 'internal':self.internal_ns,
779 'builtin':__builtin__.__dict__
779 'builtin':__builtin__.__dict__
780 }
780 }
781
781
782 # Similarly, track all namespaces where references can be held and that
782 # Similarly, track all namespaces where references can be held and that
783 # we can safely clear (so it can NOT include builtin). This one can be
783 # we can safely clear (so it can NOT include builtin). This one can be
784 # a simple list.
784 # a simple list.
785 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
785 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
786 self.internal_ns, self._main_ns_cache ]
786 self.internal_ns, self._main_ns_cache ]
787
787
788 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
788 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
789 """Return a valid local and global user interactive namespaces.
789 """Return a valid local and global user interactive namespaces.
790
790
791 This builds a dict with the minimal information needed to operate as a
791 This builds a dict with the minimal information needed to operate as a
792 valid IPython user namespace, which you can pass to the various
792 valid IPython user namespace, which you can pass to the various
793 embedding classes in ipython. The default implementation returns the
793 embedding classes in ipython. The default implementation returns the
794 same dict for both the locals and the globals to allow functions to
794 same dict for both the locals and the globals to allow functions to
795 refer to variables in the namespace. Customized implementations can
795 refer to variables in the namespace. Customized implementations can
796 return different dicts. The locals dictionary can actually be anything
796 return different dicts. The locals dictionary can actually be anything
797 following the basic mapping protocol of a dict, but the globals dict
797 following the basic mapping protocol of a dict, but the globals dict
798 must be a true dict, not even a subclass. It is recommended that any
798 must be a true dict, not even a subclass. It is recommended that any
799 custom object for the locals namespace synchronize with the globals
799 custom object for the locals namespace synchronize with the globals
800 dict somehow.
800 dict somehow.
801
801
802 Raises TypeError if the provided globals namespace is not a true dict.
802 Raises TypeError if the provided globals namespace is not a true dict.
803
803
804 Parameters
804 Parameters
805 ----------
805 ----------
806 user_ns : dict-like, optional
806 user_ns : dict-like, optional
807 The current user namespace. The items in this namespace should
807 The current user namespace. The items in this namespace should
808 be included in the output. If None, an appropriate blank
808 be included in the output. If None, an appropriate blank
809 namespace should be created.
809 namespace should be created.
810 user_global_ns : dict, optional
810 user_global_ns : dict, optional
811 The current user global namespace. The items in this namespace
811 The current user global namespace. The items in this namespace
812 should be included in the output. If None, an appropriate
812 should be included in the output. If None, an appropriate
813 blank namespace should be created.
813 blank namespace should be created.
814
814
815 Returns
815 Returns
816 -------
816 -------
817 A pair of dictionary-like object to be used as the local namespace
817 A pair of dictionary-like object to be used as the local namespace
818 of the interpreter and a dict to be used as the global namespace.
818 of the interpreter and a dict to be used as the global namespace.
819 """
819 """
820
820
821
821
822 # We must ensure that __builtin__ (without the final 's') is always
822 # We must ensure that __builtin__ (without the final 's') is always
823 # available and pointing to the __builtin__ *module*. For more details:
823 # available and pointing to the __builtin__ *module*. For more details:
824 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
824 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
825
825
826 if user_ns is None:
826 if user_ns is None:
827 # Set __name__ to __main__ to better match the behavior of the
827 # Set __name__ to __main__ to better match the behavior of the
828 # normal interpreter.
828 # normal interpreter.
829 user_ns = {'__name__' :'__main__',
829 user_ns = {'__name__' :'__main__',
830 '__builtin__' : __builtin__,
830 '__builtin__' : __builtin__,
831 '__builtins__' : __builtin__,
831 '__builtins__' : __builtin__,
832 }
832 }
833 else:
833 else:
834 user_ns.setdefault('__name__','__main__')
834 user_ns.setdefault('__name__','__main__')
835 user_ns.setdefault('__builtin__',__builtin__)
835 user_ns.setdefault('__builtin__',__builtin__)
836 user_ns.setdefault('__builtins__',__builtin__)
836 user_ns.setdefault('__builtins__',__builtin__)
837
837
838 if user_global_ns is None:
838 if user_global_ns is None:
839 user_global_ns = user_ns
839 user_global_ns = user_ns
840 if type(user_global_ns) is not dict:
840 if type(user_global_ns) is not dict:
841 raise TypeError("user_global_ns must be a true dict; got %r"
841 raise TypeError("user_global_ns must be a true dict; got %r"
842 % type(user_global_ns))
842 % type(user_global_ns))
843
843
844 return user_ns, user_global_ns
844 return user_ns, user_global_ns
845
845
846 def init_sys_modules(self):
846 def init_sys_modules(self):
847 # We need to insert into sys.modules something that looks like a
847 # We need to insert into sys.modules something that looks like a
848 # module but which accesses the IPython namespace, for shelve and
848 # module but which accesses the IPython namespace, for shelve and
849 # pickle to work interactively. Normally they rely on getting
849 # pickle to work interactively. Normally they rely on getting
850 # everything out of __main__, but for embedding purposes each IPython
850 # everything out of __main__, but for embedding purposes each IPython
851 # instance has its own private namespace, so we can't go shoving
851 # instance has its own private namespace, so we can't go shoving
852 # everything into __main__.
852 # everything into __main__.
853
853
854 # note, however, that we should only do this for non-embedded
854 # note, however, that we should only do this for non-embedded
855 # ipythons, which really mimic the __main__.__dict__ with their own
855 # ipythons, which really mimic the __main__.__dict__ with their own
856 # namespace. Embedded instances, on the other hand, should not do
856 # namespace. Embedded instances, on the other hand, should not do
857 # this because they need to manage the user local/global namespaces
857 # this because they need to manage the user local/global namespaces
858 # only, but they live within a 'normal' __main__ (meaning, they
858 # only, but they live within a 'normal' __main__ (meaning, they
859 # shouldn't overtake the execution environment of the script they're
859 # shouldn't overtake the execution environment of the script they're
860 # embedded in).
860 # embedded in).
861
861
862 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
862 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
863
863
864 try:
864 try:
865 main_name = self.user_ns['__name__']
865 main_name = self.user_ns['__name__']
866 except KeyError:
866 except KeyError:
867 raise KeyError('user_ns dictionary MUST have a "__name__" key')
867 raise KeyError('user_ns dictionary MUST have a "__name__" key')
868 else:
868 else:
869 sys.modules[main_name] = FakeModule(self.user_ns)
869 sys.modules[main_name] = FakeModule(self.user_ns)
870
870
871 def init_user_ns(self):
871 def init_user_ns(self):
872 """Initialize all user-visible namespaces to their minimum defaults.
872 """Initialize all user-visible namespaces to their minimum defaults.
873
873
874 Certain history lists are also initialized here, as they effectively
874 Certain history lists are also initialized here, as they effectively
875 act as user namespaces.
875 act as user namespaces.
876
876
877 Notes
877 Notes
878 -----
878 -----
879 All data structures here are only filled in, they are NOT reset by this
879 All data structures here are only filled in, they are NOT reset by this
880 method. If they were not empty before, data will simply be added to
880 method. If they were not empty before, data will simply be added to
881 therm.
881 therm.
882 """
882 """
883 # This function works in two parts: first we put a few things in
883 # This function works in two parts: first we put a few things in
884 # user_ns, and we sync that contents into user_ns_hidden so that these
884 # user_ns, and we sync that contents into user_ns_hidden so that these
885 # initial variables aren't shown by %who. After the sync, we add the
885 # initial variables aren't shown by %who. After the sync, we add the
886 # rest of what we *do* want the user to see with %who even on a new
886 # rest of what we *do* want the user to see with %who even on a new
887 # session (probably nothing, so theye really only see their own stuff)
887 # session (probably nothing, so theye really only see their own stuff)
888
888
889 # The user dict must *always* have a __builtin__ reference to the
889 # The user dict must *always* have a __builtin__ reference to the
890 # Python standard __builtin__ namespace, which must be imported.
890 # Python standard __builtin__ namespace, which must be imported.
891 # This is so that certain operations in prompt evaluation can be
891 # This is so that certain operations in prompt evaluation can be
892 # reliably executed with builtins. Note that we can NOT use
892 # reliably executed with builtins. Note that we can NOT use
893 # __builtins__ (note the 's'), because that can either be a dict or a
893 # __builtins__ (note the 's'), because that can either be a dict or a
894 # module, and can even mutate at runtime, depending on the context
894 # module, and can even mutate at runtime, depending on the context
895 # (Python makes no guarantees on it). In contrast, __builtin__ is
895 # (Python makes no guarantees on it). In contrast, __builtin__ is
896 # always a module object, though it must be explicitly imported.
896 # always a module object, though it must be explicitly imported.
897
897
898 # For more details:
898 # For more details:
899 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
899 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
900 ns = dict(__builtin__ = __builtin__)
900 ns = dict(__builtin__ = __builtin__)
901
901
902 # Put 'help' in the user namespace
902 # Put 'help' in the user namespace
903 try:
903 try:
904 from site import _Helper
904 from site import _Helper
905 ns['help'] = _Helper()
905 ns['help'] = _Helper()
906 except ImportError:
906 except ImportError:
907 warn('help() not available - check site.py')
907 warn('help() not available - check site.py')
908
908
909 # make global variables for user access to the histories
909 # make global variables for user access to the histories
910 ns['_ih'] = self.input_hist
910 ns['_ih'] = self.input_hist
911 ns['_oh'] = self.output_hist
911 ns['_oh'] = self.output_hist
912 ns['_dh'] = self.dir_hist
912 ns['_dh'] = self.dir_hist
913
913
914 ns['_sh'] = shadowns
914 ns['_sh'] = shadowns
915
915
916 # user aliases to input and output histories. These shouldn't show up
916 # user aliases to input and output histories. These shouldn't show up
917 # in %who, as they can have very large reprs.
917 # in %who, as they can have very large reprs.
918 ns['In'] = self.input_hist
918 ns['In'] = self.input_hist
919 ns['Out'] = self.output_hist
919 ns['Out'] = self.output_hist
920
920
921 # Store myself as the public api!!!
921 # Store myself as the public api!!!
922 ns['get_ipython'] = self.get_ipython
922 ns['get_ipython'] = self.get_ipython
923
923
924 # Sync what we've added so far to user_ns_hidden so these aren't seen
924 # Sync what we've added so far to user_ns_hidden so these aren't seen
925 # by %who
925 # by %who
926 self.user_ns_hidden.update(ns)
926 self.user_ns_hidden.update(ns)
927
927
928 # Anything put into ns now would show up in %who. Think twice before
928 # Anything put into ns now would show up in %who. Think twice before
929 # putting anything here, as we really want %who to show the user their
929 # putting anything here, as we really want %who to show the user their
930 # stuff, not our variables.
930 # stuff, not our variables.
931
931
932 # Finally, update the real user's namespace
932 # Finally, update the real user's namespace
933 self.user_ns.update(ns)
933 self.user_ns.update(ns)
934
934
935
935
936 def reset(self):
936 def reset(self):
937 """Clear all internal namespaces.
937 """Clear all internal namespaces.
938
938
939 Note that this is much more aggressive than %reset, since it clears
939 Note that this is much more aggressive than %reset, since it clears
940 fully all namespaces, as well as all input/output lists.
940 fully all namespaces, as well as all input/output lists.
941 """
941 """
942 for ns in self.ns_refs_table:
942 for ns in self.ns_refs_table:
943 ns.clear()
943 ns.clear()
944
944
945 self.alias_manager.clear_aliases()
945 self.alias_manager.clear_aliases()
946
946
947 # Clear input and output histories
947 # Clear input and output histories
948 self.input_hist[:] = []
948 self.input_hist[:] = []
949 self.input_hist_raw[:] = []
949 self.input_hist_raw[:] = []
950 self.output_hist.clear()
950 self.output_hist.clear()
951
951
952 # Restore the user namespaces to minimal usability
952 # Restore the user namespaces to minimal usability
953 self.init_user_ns()
953 self.init_user_ns()
954
954
955 # Restore the default and user aliases
955 # Restore the default and user aliases
956 self.alias_manager.init_aliases()
956 self.alias_manager.init_aliases()
957
957
958 def reset_selective(self, regex=None):
958 def reset_selective(self, regex=None):
959 """Clear selective variables from internal namespaces based on a specified regular expression.
959 """Clear selective variables from internal namespaces based on a specified regular expression.
960
960
961 Parameters
961 Parameters
962 ----------
962 ----------
963 regex : string or compiled pattern, optional
963 regex : string or compiled pattern, optional
964 A regular expression pattern that will be used in searching variable names in the users
964 A regular expression pattern that will be used in searching variable names in the users
965 namespaces.
965 namespaces.
966 """
966 """
967 if regex is not None:
967 if regex is not None:
968 try:
968 try:
969 m = re.compile(regex)
969 m = re.compile(regex)
970 except TypeError:
970 except TypeError:
971 raise TypeError('regex must be a string or compiled pattern')
971 raise TypeError('regex must be a string or compiled pattern')
972 # Search for keys in each namespace that match the given regex
972 # Search for keys in each namespace that match the given regex
973 # If a match is found, delete the key/value pair.
973 # If a match is found, delete the key/value pair.
974 for ns in self.ns_refs_table:
974 for ns in self.ns_refs_table:
975 for var in ns:
975 for var in ns:
976 if m.search(var):
976 if m.search(var):
977 del ns[var]
977 del ns[var]
978
978
979 def push(self, variables, interactive=True):
979 def push(self, variables, interactive=True):
980 """Inject a group of variables into the IPython user namespace.
980 """Inject a group of variables into the IPython user namespace.
981
981
982 Parameters
982 Parameters
983 ----------
983 ----------
984 variables : dict, str or list/tuple of str
984 variables : dict, str or list/tuple of str
985 The variables to inject into the user's namespace. If a dict,
985 The variables to inject into the user's namespace. If a dict,
986 a simple update is done. If a str, the string is assumed to
986 a simple update is done. If a str, the string is assumed to
987 have variable names separated by spaces. A list/tuple of str
987 have variable names separated by spaces. A list/tuple of str
988 can also be used to give the variable names. If just the variable
988 can also be used to give the variable names. If just the variable
989 names are give (list/tuple/str) then the variable values looked
989 names are give (list/tuple/str) then the variable values looked
990 up in the callers frame.
990 up in the callers frame.
991 interactive : bool
991 interactive : bool
992 If True (default), the variables will be listed with the ``who``
992 If True (default), the variables will be listed with the ``who``
993 magic.
993 magic.
994 """
994 """
995 vdict = None
995 vdict = None
996
996
997 # We need a dict of name/value pairs to do namespace updates.
997 # We need a dict of name/value pairs to do namespace updates.
998 if isinstance(variables, dict):
998 if isinstance(variables, dict):
999 vdict = variables
999 vdict = variables
1000 elif isinstance(variables, (basestring, list, tuple)):
1000 elif isinstance(variables, (basestring, list, tuple)):
1001 if isinstance(variables, basestring):
1001 if isinstance(variables, basestring):
1002 vlist = variables.split()
1002 vlist = variables.split()
1003 else:
1003 else:
1004 vlist = variables
1004 vlist = variables
1005 vdict = {}
1005 vdict = {}
1006 cf = sys._getframe(1)
1006 cf = sys._getframe(1)
1007 for name in vlist:
1007 for name in vlist:
1008 try:
1008 try:
1009 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1009 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1010 except:
1010 except:
1011 print ('Could not get variable %s from %s' %
1011 print ('Could not get variable %s from %s' %
1012 (name,cf.f_code.co_name))
1012 (name,cf.f_code.co_name))
1013 else:
1013 else:
1014 raise ValueError('variables must be a dict/str/list/tuple')
1014 raise ValueError('variables must be a dict/str/list/tuple')
1015
1015
1016 # Propagate variables to user namespace
1016 # Propagate variables to user namespace
1017 self.user_ns.update(vdict)
1017 self.user_ns.update(vdict)
1018
1018
1019 # And configure interactive visibility
1019 # And configure interactive visibility
1020 config_ns = self.user_ns_hidden
1020 config_ns = self.user_ns_hidden
1021 if interactive:
1021 if interactive:
1022 for name, val in vdict.iteritems():
1022 for name, val in vdict.iteritems():
1023 config_ns.pop(name, None)
1023 config_ns.pop(name, None)
1024 else:
1024 else:
1025 for name,val in vdict.iteritems():
1025 for name,val in vdict.iteritems():
1026 config_ns[name] = val
1026 config_ns[name] = val
1027
1027
1028 #-------------------------------------------------------------------------
1028 #-------------------------------------------------------------------------
1029 # Things related to history management
1029 # Things related to history management
1030 #-------------------------------------------------------------------------
1030 #-------------------------------------------------------------------------
1031
1031
1032 def init_history(self):
1032 def init_history(self):
1033 # List of input with multi-line handling.
1033 # List of input with multi-line handling.
1034 self.input_hist = InputList()
1034 self.input_hist = InputList()
1035 # This one will hold the 'raw' input history, without any
1035 # This one will hold the 'raw' input history, without any
1036 # pre-processing. This will allow users to retrieve the input just as
1036 # pre-processing. This will allow users to retrieve the input just as
1037 # it was exactly typed in by the user, with %hist -r.
1037 # it was exactly typed in by the user, with %hist -r.
1038 self.input_hist_raw = InputList()
1038 self.input_hist_raw = InputList()
1039
1039
1040 # list of visited directories
1040 # list of visited directories
1041 try:
1041 try:
1042 self.dir_hist = [os.getcwd()]
1042 self.dir_hist = [os.getcwd()]
1043 except OSError:
1043 except OSError:
1044 self.dir_hist = []
1044 self.dir_hist = []
1045
1045
1046 # dict of output history
1046 # dict of output history
1047 self.output_hist = {}
1047 self.output_hist = {}
1048
1048
1049 # Now the history file
1049 # Now the history file
1050 if self.profile:
1050 if self.profile:
1051 histfname = 'history-%s' % self.profile
1051 histfname = 'history-%s' % self.profile
1052 else:
1052 else:
1053 histfname = 'history'
1053 histfname = 'history'
1054 self.histfile = os.path.join(self.ipython_dir, histfname)
1054 self.histfile = os.path.join(self.ipython_dir, histfname)
1055
1055
1056 # Fill the history zero entry, user counter starts at 1
1056 # Fill the history zero entry, user counter starts at 1
1057 self.input_hist.append('\n')
1057 self.input_hist.append('\n')
1058 self.input_hist_raw.append('\n')
1058 self.input_hist_raw.append('\n')
1059
1059
1060 def init_shadow_hist(self):
1060 def init_shadow_hist(self):
1061 try:
1061 try:
1062 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1062 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1063 except exceptions.UnicodeDecodeError:
1063 except exceptions.UnicodeDecodeError:
1064 print "Your ipython_dir can't be decoded to unicode!"
1064 print "Your ipython_dir can't be decoded to unicode!"
1065 print "Please set HOME environment variable to something that"
1065 print "Please set HOME environment variable to something that"
1066 print r"only has ASCII characters, e.g. c:\home"
1066 print r"only has ASCII characters, e.g. c:\home"
1067 print "Now it is", self.ipython_dir
1067 print "Now it is", self.ipython_dir
1068 sys.exit()
1068 sys.exit()
1069 self.shadowhist = ipcorehist.ShadowHist(self.db)
1069 self.shadowhist = ipcorehist.ShadowHist(self.db)
1070
1070
1071 def savehist(self):
1071 def savehist(self):
1072 """Save input history to a file (via readline library)."""
1072 """Save input history to a file (via readline library)."""
1073
1073
1074 try:
1074 try:
1075 self.readline.write_history_file(self.histfile)
1075 self.readline.write_history_file(self.histfile)
1076 except:
1076 except:
1077 print 'Unable to save IPython command history to file: ' + \
1077 print 'Unable to save IPython command history to file: ' + \
1078 `self.histfile`
1078 `self.histfile`
1079
1079
1080 def reloadhist(self):
1080 def reloadhist(self):
1081 """Reload the input history from disk file."""
1081 """Reload the input history from disk file."""
1082
1082
1083 try:
1083 try:
1084 self.readline.clear_history()
1084 self.readline.clear_history()
1085 self.readline.read_history_file(self.shell.histfile)
1085 self.readline.read_history_file(self.shell.histfile)
1086 except AttributeError:
1086 except AttributeError:
1087 pass
1087 pass
1088
1088
1089 def history_saving_wrapper(self, func):
1089 def history_saving_wrapper(self, func):
1090 """ Wrap func for readline history saving
1090 """ Wrap func for readline history saving
1091
1091
1092 Convert func into callable that saves & restores
1092 Convert func into callable that saves & restores
1093 history around the call """
1093 history around the call """
1094
1094
1095 if self.has_readline:
1095 if self.has_readline:
1096 from IPython.utils import rlineimpl as readline
1096 from IPython.utils import rlineimpl as readline
1097 else:
1097 else:
1098 return func
1098 return func
1099
1099
1100 def wrapper():
1100 def wrapper():
1101 self.savehist()
1101 self.savehist()
1102 try:
1102 try:
1103 func()
1103 func()
1104 finally:
1104 finally:
1105 readline.read_history_file(self.histfile)
1105 readline.read_history_file(self.histfile)
1106 return wrapper
1106 return wrapper
1107
1107
1108 def get_history(self, index=None, raw=False, output=True):
1108 def get_history(self, index=None, raw=False, output=True):
1109 """Get the history list.
1109 """Get the history list.
1110
1110
1111 Get the input and output history.
1111 Get the input and output history.
1112
1112
1113 Parameters
1113 Parameters
1114 ----------
1114 ----------
1115 index : n or (n1, n2) or None
1115 index : n or (n1, n2) or None
1116 If n, then the last entries. If a tuple, then all in
1116 If n, then the last entries. If a tuple, then all in
1117 range(n1, n2). If None, then all entries. Raises IndexError if
1117 range(n1, n2). If None, then all entries. Raises IndexError if
1118 the format of index is incorrect.
1118 the format of index is incorrect.
1119 raw : bool
1119 raw : bool
1120 If True, return the raw input.
1120 If True, return the raw input.
1121 output : bool
1121 output : bool
1122 If True, then return the output as well.
1122 If True, then return the output as well.
1123
1123
1124 Returns
1124 Returns
1125 -------
1125 -------
1126 If output is True, then return a dict of tuples, keyed by the prompt
1126 If output is True, then return a dict of tuples, keyed by the prompt
1127 numbers and with values of (input, output). If output is False, then
1127 numbers and with values of (input, output). If output is False, then
1128 a dict, keyed by the prompt number with the values of input. Raises
1128 a dict, keyed by the prompt number with the values of input. Raises
1129 IndexError if no history is found.
1129 IndexError if no history is found.
1130 """
1130 """
1131 if raw:
1131 if raw:
1132 input_hist = self.input_hist_raw
1132 input_hist = self.input_hist_raw
1133 else:
1133 else:
1134 input_hist = self.input_hist
1134 input_hist = self.input_hist
1135 if output:
1135 if output:
1136 output_hist = self.user_ns['Out']
1136 output_hist = self.user_ns['Out']
1137 n = len(input_hist)
1137 n = len(input_hist)
1138 if index is None:
1138 if index is None:
1139 start=0; stop=n
1139 start=0; stop=n
1140 elif isinstance(index, int):
1140 elif isinstance(index, int):
1141 start=n-index; stop=n
1141 start=n-index; stop=n
1142 elif isinstance(index, tuple) and len(index) == 2:
1142 elif isinstance(index, tuple) and len(index) == 2:
1143 start=index[0]; stop=index[1]
1143 start=index[0]; stop=index[1]
1144 else:
1144 else:
1145 raise IndexError('Not a valid index for the input history: %r' % index)
1145 raise IndexError('Not a valid index for the input history: %r' % index)
1146 hist = {}
1146 hist = {}
1147 for i in range(start, stop):
1147 for i in range(start, stop):
1148 if output:
1148 if output:
1149 hist[i] = (input_hist[i], output_hist.get(i))
1149 hist[i] = (input_hist[i], output_hist.get(i))
1150 else:
1150 else:
1151 hist[i] = input_hist[i]
1151 hist[i] = input_hist[i]
1152 if len(hist)==0:
1152 if len(hist)==0:
1153 raise IndexError('No history for range of indices: %r' % index)
1153 raise IndexError('No history for range of indices: %r' % index)
1154 return hist
1154 return hist
1155
1155
1156 #-------------------------------------------------------------------------
1156 #-------------------------------------------------------------------------
1157 # Things related to exception handling and tracebacks (not debugging)
1157 # Things related to exception handling and tracebacks (not debugging)
1158 #-------------------------------------------------------------------------
1158 #-------------------------------------------------------------------------
1159
1159
1160 def init_traceback_handlers(self, custom_exceptions):
1160 def init_traceback_handlers(self, custom_exceptions):
1161 # Syntax error handler.
1161 # Syntax error handler.
1162 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1162 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1163
1163
1164 # The interactive one is initialized with an offset, meaning we always
1164 # The interactive one is initialized with an offset, meaning we always
1165 # want to remove the topmost item in the traceback, which is our own
1165 # want to remove the topmost item in the traceback, which is our own
1166 # internal code. Valid modes: ['Plain','Context','Verbose']
1166 # internal code. Valid modes: ['Plain','Context','Verbose']
1167 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1167 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1168 color_scheme='NoColor',
1168 color_scheme='NoColor',
1169 tb_offset = 1)
1169 tb_offset = 1)
1170
1170
1171 # The instance will store a pointer to the system-wide exception hook,
1171 # The instance will store a pointer to the system-wide exception hook,
1172 # so that runtime code (such as magics) can access it. This is because
1172 # so that runtime code (such as magics) can access it. This is because
1173 # during the read-eval loop, it may get temporarily overwritten.
1173 # during the read-eval loop, it may get temporarily overwritten.
1174 self.sys_excepthook = sys.excepthook
1174 self.sys_excepthook = sys.excepthook
1175
1175
1176 # and add any custom exception handlers the user may have specified
1176 # and add any custom exception handlers the user may have specified
1177 self.set_custom_exc(*custom_exceptions)
1177 self.set_custom_exc(*custom_exceptions)
1178
1178
1179 # Set the exception mode
1179 # Set the exception mode
1180 self.InteractiveTB.set_mode(mode=self.xmode)
1180 self.InteractiveTB.set_mode(mode=self.xmode)
1181
1181
1182 def set_custom_exc(self, exc_tuple, handler):
1182 def set_custom_exc(self, exc_tuple, handler):
1183 """set_custom_exc(exc_tuple,handler)
1183 """set_custom_exc(exc_tuple,handler)
1184
1184
1185 Set a custom exception handler, which will be called if any of the
1185 Set a custom exception handler, which will be called if any of the
1186 exceptions in exc_tuple occur in the mainloop (specifically, in the
1186 exceptions in exc_tuple occur in the mainloop (specifically, in the
1187 runcode() method.
1187 runcode() method.
1188
1188
1189 Inputs:
1189 Inputs:
1190
1190
1191 - exc_tuple: a *tuple* of valid exceptions to call the defined
1191 - exc_tuple: a *tuple* of valid exceptions to call the defined
1192 handler for. It is very important that you use a tuple, and NOT A
1192 handler for. It is very important that you use a tuple, and NOT A
1193 LIST here, because of the way Python's except statement works. If
1193 LIST here, because of the way Python's except statement works. If
1194 you only want to trap a single exception, use a singleton tuple:
1194 you only want to trap a single exception, use a singleton tuple:
1195
1195
1196 exc_tuple == (MyCustomException,)
1196 exc_tuple == (MyCustomException,)
1197
1197
1198 - handler: this must be defined as a function with the following
1198 - handler: this must be defined as a function with the following
1199 basic interface::
1199 basic interface::
1200
1200
1201 def my_handler(self, etype, value, tb, tb_offset=None)
1201 def my_handler(self, etype, value, tb, tb_offset=None)
1202 ...
1202 ...
1203 # The return value must be
1203 # The return value must be
1204 return structured_traceback
1204 return structured_traceback
1205
1205
1206 This will be made into an instance method (via new.instancemethod)
1206 This will be made into an instance method (via new.instancemethod)
1207 of IPython itself, and it will be called if any of the exceptions
1207 of IPython itself, and it will be called if any of the exceptions
1208 listed in the exc_tuple are caught. If the handler is None, an
1208 listed in the exc_tuple are caught. If the handler is None, an
1209 internal basic one is used, which just prints basic info.
1209 internal basic one is used, which just prints basic info.
1210
1210
1211 WARNING: by putting in your own exception handler into IPython's main
1211 WARNING: by putting in your own exception handler into IPython's main
1212 execution loop, you run a very good chance of nasty crashes. This
1212 execution loop, you run a very good chance of nasty crashes. This
1213 facility should only be used if you really know what you are doing."""
1213 facility should only be used if you really know what you are doing."""
1214
1214
1215 assert type(exc_tuple)==type(()) , \
1215 assert type(exc_tuple)==type(()) , \
1216 "The custom exceptions must be given AS A TUPLE."
1216 "The custom exceptions must be given AS A TUPLE."
1217
1217
1218 def dummy_handler(self,etype,value,tb):
1218 def dummy_handler(self,etype,value,tb):
1219 print '*** Simple custom exception handler ***'
1219 print '*** Simple custom exception handler ***'
1220 print 'Exception type :',etype
1220 print 'Exception type :',etype
1221 print 'Exception value:',value
1221 print 'Exception value:',value
1222 print 'Traceback :',tb
1222 print 'Traceback :',tb
1223 print 'Source code :','\n'.join(self.buffer)
1223 print 'Source code :','\n'.join(self.buffer)
1224
1224
1225 if handler is None: handler = dummy_handler
1225 if handler is None: handler = dummy_handler
1226
1226
1227 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1227 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1228 self.custom_exceptions = exc_tuple
1228 self.custom_exceptions = exc_tuple
1229
1229
1230 def excepthook(self, etype, value, tb):
1230 def excepthook(self, etype, value, tb):
1231 """One more defense for GUI apps that call sys.excepthook.
1231 """One more defense for GUI apps that call sys.excepthook.
1232
1232
1233 GUI frameworks like wxPython trap exceptions and call
1233 GUI frameworks like wxPython trap exceptions and call
1234 sys.excepthook themselves. I guess this is a feature that
1234 sys.excepthook themselves. I guess this is a feature that
1235 enables them to keep running after exceptions that would
1235 enables them to keep running after exceptions that would
1236 otherwise kill their mainloop. This is a bother for IPython
1236 otherwise kill their mainloop. This is a bother for IPython
1237 which excepts to catch all of the program exceptions with a try:
1237 which excepts to catch all of the program exceptions with a try:
1238 except: statement.
1238 except: statement.
1239
1239
1240 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1240 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1241 any app directly invokes sys.excepthook, it will look to the user like
1241 any app directly invokes sys.excepthook, it will look to the user like
1242 IPython crashed. In order to work around this, we can disable the
1242 IPython crashed. In order to work around this, we can disable the
1243 CrashHandler and replace it with this excepthook instead, which prints a
1243 CrashHandler and replace it with this excepthook instead, which prints a
1244 regular traceback using our InteractiveTB. In this fashion, apps which
1244 regular traceback using our InteractiveTB. In this fashion, apps which
1245 call sys.excepthook will generate a regular-looking exception from
1245 call sys.excepthook will generate a regular-looking exception from
1246 IPython, and the CrashHandler will only be triggered by real IPython
1246 IPython, and the CrashHandler will only be triggered by real IPython
1247 crashes.
1247 crashes.
1248
1248
1249 This hook should be used sparingly, only in places which are not likely
1249 This hook should be used sparingly, only in places which are not likely
1250 to be true IPython errors.
1250 to be true IPython errors.
1251 """
1251 """
1252 self.showtraceback((etype,value,tb),tb_offset=0)
1252 self.showtraceback((etype,value,tb),tb_offset=0)
1253
1253
1254 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1254 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1255 exception_only=False):
1255 exception_only=False):
1256 """Display the exception that just occurred.
1256 """Display the exception that just occurred.
1257
1257
1258 If nothing is known about the exception, this is the method which
1258 If nothing is known about the exception, this is the method which
1259 should be used throughout the code for presenting user tracebacks,
1259 should be used throughout the code for presenting user tracebacks,
1260 rather than directly invoking the InteractiveTB object.
1260 rather than directly invoking the InteractiveTB object.
1261
1261
1262 A specific showsyntaxerror() also exists, but this method can take
1262 A specific showsyntaxerror() also exists, but this method can take
1263 care of calling it if needed, so unless you are explicitly catching a
1263 care of calling it if needed, so unless you are explicitly catching a
1264 SyntaxError exception, don't try to analyze the stack manually and
1264 SyntaxError exception, don't try to analyze the stack manually and
1265 simply call this method."""
1265 simply call this method."""
1266
1266
1267 try:
1267 try:
1268 if exc_tuple is None:
1268 if exc_tuple is None:
1269 etype, value, tb = sys.exc_info()
1269 etype, value, tb = sys.exc_info()
1270 else:
1270 else:
1271 etype, value, tb = exc_tuple
1271 etype, value, tb = exc_tuple
1272
1272
1273 if etype is None:
1273 if etype is None:
1274 if hasattr(sys, 'last_type'):
1274 if hasattr(sys, 'last_type'):
1275 etype, value, tb = sys.last_type, sys.last_value, \
1275 etype, value, tb = sys.last_type, sys.last_value, \
1276 sys.last_traceback
1276 sys.last_traceback
1277 else:
1277 else:
1278 self.write_err('No traceback available to show.\n')
1278 self.write_err('No traceback available to show.\n')
1279 return
1279 return
1280
1280
1281 if etype is SyntaxError:
1281 if etype is SyntaxError:
1282 # Though this won't be called by syntax errors in the input
1282 # Though this won't be called by syntax errors in the input
1283 # line, there may be SyntaxError cases whith imported code.
1283 # line, there may be SyntaxError cases whith imported code.
1284 self.showsyntaxerror(filename)
1284 self.showsyntaxerror(filename)
1285 elif etype is UsageError:
1285 elif etype is UsageError:
1286 print "UsageError:", value
1286 print "UsageError:", value
1287 else:
1287 else:
1288 # WARNING: these variables are somewhat deprecated and not
1288 # WARNING: these variables are somewhat deprecated and not
1289 # necessarily safe to use in a threaded environment, but tools
1289 # necessarily safe to use in a threaded environment, but tools
1290 # like pdb depend on their existence, so let's set them. If we
1290 # like pdb depend on their existence, so let's set them. If we
1291 # find problems in the field, we'll need to revisit their use.
1291 # find problems in the field, we'll need to revisit their use.
1292 sys.last_type = etype
1292 sys.last_type = etype
1293 sys.last_value = value
1293 sys.last_value = value
1294 sys.last_traceback = tb
1294 sys.last_traceback = tb
1295
1295
1296 if etype in self.custom_exceptions:
1296 if etype in self.custom_exceptions:
1297 # FIXME: Old custom traceback objects may just return a
1297 # FIXME: Old custom traceback objects may just return a
1298 # string, in that case we just put it into a list
1298 # string, in that case we just put it into a list
1299 stb = self.CustomTB(etype, value, tb, tb_offset)
1299 stb = self.CustomTB(etype, value, tb, tb_offset)
1300 if isinstance(ctb, basestring):
1300 if isinstance(ctb, basestring):
1301 stb = [stb]
1301 stb = [stb]
1302 else:
1302 else:
1303 if exception_only:
1303 if exception_only:
1304 stb = ['An exception has occurred, use %tb to see '
1304 stb = ['An exception has occurred, use %tb to see '
1305 'the full traceback.\n']
1305 'the full traceback.\n']
1306 stb.extend(self.InteractiveTB.get_exception_only(etype,
1306 stb.extend(self.InteractiveTB.get_exception_only(etype,
1307 value))
1307 value))
1308 else:
1308 else:
1309 stb = self.InteractiveTB.structured_traceback(etype,
1309 stb = self.InteractiveTB.structured_traceback(etype,
1310 value, tb, tb_offset=tb_offset)
1310 value, tb, tb_offset=tb_offset)
1311 # FIXME: the pdb calling should be done by us, not by
1311 # FIXME: the pdb calling should be done by us, not by
1312 # the code computing the traceback.
1312 # the code computing the traceback.
1313 if self.InteractiveTB.call_pdb:
1313 if self.InteractiveTB.call_pdb:
1314 # pdb mucks up readline, fix it back
1314 # pdb mucks up readline, fix it back
1315 self.set_completer()
1315 self.set_completer()
1316
1316
1317 # Actually show the traceback
1317 # Actually show the traceback
1318 self._showtraceback(etype, value, stb)
1318 self._showtraceback(etype, value, stb)
1319
1319
1320 except KeyboardInterrupt:
1320 except KeyboardInterrupt:
1321 self.write_err("\nKeyboardInterrupt\n")
1321 self.write_err("\nKeyboardInterrupt\n")
1322
1322
1323 def _showtraceback(self, etype, evalue, stb):
1323 def _showtraceback(self, etype, evalue, stb):
1324 """Actually show a traceback.
1324 """Actually show a traceback.
1325
1325
1326 Subclasses may override this method to put the traceback on a different
1326 Subclasses may override this method to put the traceback on a different
1327 place, like a side channel.
1327 place, like a side channel.
1328 """
1328 """
1329 # FIXME: this should use the proper write channels, but our test suite
1329 # FIXME: this should use the proper write channels, but our test suite
1330 # relies on it coming out of stdout...
1330 # relies on it coming out of stdout...
1331 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1331 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1332
1332
1333 def showsyntaxerror(self, filename=None):
1333 def showsyntaxerror(self, filename=None):
1334 """Display the syntax error that just occurred.
1334 """Display the syntax error that just occurred.
1335
1335
1336 This doesn't display a stack trace because there isn't one.
1336 This doesn't display a stack trace because there isn't one.
1337
1337
1338 If a filename is given, it is stuffed in the exception instead
1338 If a filename is given, it is stuffed in the exception instead
1339 of what was there before (because Python's parser always uses
1339 of what was there before (because Python's parser always uses
1340 "<string>" when reading from a string).
1340 "<string>" when reading from a string).
1341 """
1341 """
1342 etype, value, last_traceback = sys.exc_info()
1342 etype, value, last_traceback = sys.exc_info()
1343
1343
1344 # See note about these variables in showtraceback() above
1344 # See note about these variables in showtraceback() above
1345 sys.last_type = etype
1345 sys.last_type = etype
1346 sys.last_value = value
1346 sys.last_value = value
1347 sys.last_traceback = last_traceback
1347 sys.last_traceback = last_traceback
1348
1348
1349 if filename and etype is SyntaxError:
1349 if filename and etype is SyntaxError:
1350 # Work hard to stuff the correct filename in the exception
1350 # Work hard to stuff the correct filename in the exception
1351 try:
1351 try:
1352 msg, (dummy_filename, lineno, offset, line) = value
1352 msg, (dummy_filename, lineno, offset, line) = value
1353 except:
1353 except:
1354 # Not the format we expect; leave it alone
1354 # Not the format we expect; leave it alone
1355 pass
1355 pass
1356 else:
1356 else:
1357 # Stuff in the right filename
1357 # Stuff in the right filename
1358 try:
1358 try:
1359 # Assume SyntaxError is a class exception
1359 # Assume SyntaxError is a class exception
1360 value = SyntaxError(msg, (filename, lineno, offset, line))
1360 value = SyntaxError(msg, (filename, lineno, offset, line))
1361 except:
1361 except:
1362 # If that failed, assume SyntaxError is a string
1362 # If that failed, assume SyntaxError is a string
1363 value = msg, (filename, lineno, offset, line)
1363 value = msg, (filename, lineno, offset, line)
1364 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1364 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1365 self._showtraceback(etype, value, stb)
1365 self._showtraceback(etype, value, stb)
1366
1366
1367 #-------------------------------------------------------------------------
1367 #-------------------------------------------------------------------------
1368 # Things related to tab completion
1368 # Things related to tab completion
1369 #-------------------------------------------------------------------------
1369 #-------------------------------------------------------------------------
1370
1370
1371 def complete(self, text, line=None, cursor_pos=None):
1371 def complete(self, text, line=None, cursor_pos=None):
1372 """Return the completed text and a list of completions.
1372 """Return the completed text and a list of completions.
1373
1373
1374 Parameters
1374 Parameters
1375 ----------
1375 ----------
1376
1376
1377 text : string
1377 text : string
1378 A string of text to be completed on. It can be given as empty and
1378 A string of text to be completed on. It can be given as empty and
1379 instead a line/position pair are given. In this case, the
1379 instead a line/position pair are given. In this case, the
1380 completer itself will split the line like readline does.
1380 completer itself will split the line like readline does.
1381
1381
1382 line : string, optional
1382 line : string, optional
1383 The complete line that text is part of.
1383 The complete line that text is part of.
1384
1384
1385 cursor_pos : int, optional
1385 cursor_pos : int, optional
1386 The position of the cursor on the input line.
1386 The position of the cursor on the input line.
1387
1387
1388 Returns
1388 Returns
1389 -------
1389 -------
1390 text : string
1390 text : string
1391 The actual text that was completed.
1391 The actual text that was completed.
1392
1392
1393 matches : list
1393 matches : list
1394 A sorted list with all possible completions.
1394 A sorted list with all possible completions.
1395
1395
1396 The optional arguments allow the completion to take more context into
1396 The optional arguments allow the completion to take more context into
1397 account, and are part of the low-level completion API.
1397 account, and are part of the low-level completion API.
1398
1398
1399 This is a wrapper around the completion mechanism, similar to what
1399 This is a wrapper around the completion mechanism, similar to what
1400 readline does at the command line when the TAB key is hit. By
1400 readline does at the command line when the TAB key is hit. By
1401 exposing it as a method, it can be used by other non-readline
1401 exposing it as a method, it can be used by other non-readline
1402 environments (such as GUIs) for text completion.
1402 environments (such as GUIs) for text completion.
1403
1403
1404 Simple usage example:
1404 Simple usage example:
1405
1405
1406 In [1]: x = 'hello'
1406 In [1]: x = 'hello'
1407
1407
1408 In [2]: _ip.complete('x.l')
1408 In [2]: _ip.complete('x.l')
1409 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1409 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1410 """
1410 """
1411
1411
1412 # Inject names into __builtin__ so we can complete on the added names.
1412 # Inject names into __builtin__ so we can complete on the added names.
1413 with self.builtin_trap:
1413 with self.builtin_trap:
1414 return self.Completer.complete(text, line, cursor_pos)
1414 return self.Completer.complete(text, line, cursor_pos)
1415
1415
1416 def set_custom_completer(self, completer, pos=0):
1416 def set_custom_completer(self, completer, pos=0):
1417 """Adds a new custom completer function.
1417 """Adds a new custom completer function.
1418
1418
1419 The position argument (defaults to 0) is the index in the completers
1419 The position argument (defaults to 0) is the index in the completers
1420 list where you want the completer to be inserted."""
1420 list where you want the completer to be inserted."""
1421
1421
1422 newcomp = new.instancemethod(completer,self.Completer,
1422 newcomp = new.instancemethod(completer,self.Completer,
1423 self.Completer.__class__)
1423 self.Completer.__class__)
1424 self.Completer.matchers.insert(pos,newcomp)
1424 self.Completer.matchers.insert(pos,newcomp)
1425
1425
1426 def set_completer(self):
1426 def set_completer(self):
1427 """Reset readline's completer to be our own."""
1427 """Reset readline's completer to be our own."""
1428 self.readline.set_completer(self.Completer.rlcomplete)
1428 self.readline.set_completer(self.Completer.rlcomplete)
1429
1429
1430 def set_completer_frame(self, frame=None):
1430 def set_completer_frame(self, frame=None):
1431 """Set the frame of the completer."""
1431 """Set the frame of the completer."""
1432 if frame:
1432 if frame:
1433 self.Completer.namespace = frame.f_locals
1433 self.Completer.namespace = frame.f_locals
1434 self.Completer.global_namespace = frame.f_globals
1434 self.Completer.global_namespace = frame.f_globals
1435 else:
1435 else:
1436 self.Completer.namespace = self.user_ns
1436 self.Completer.namespace = self.user_ns
1437 self.Completer.global_namespace = self.user_global_ns
1437 self.Completer.global_namespace = self.user_global_ns
1438
1438
1439 #-------------------------------------------------------------------------
1439 #-------------------------------------------------------------------------
1440 # Things related to readline
1440 # Things related to readline
1441 #-------------------------------------------------------------------------
1441 #-------------------------------------------------------------------------
1442
1442
1443 def init_readline(self):
1443 def init_readline(self):
1444 """Command history completion/saving/reloading."""
1444 """Command history completion/saving/reloading."""
1445
1445
1446 if self.readline_use:
1446 if self.readline_use:
1447 import IPython.utils.rlineimpl as readline
1447 import IPython.utils.rlineimpl as readline
1448
1448
1449 self.rl_next_input = None
1449 self.rl_next_input = None
1450 self.rl_do_indent = False
1450 self.rl_do_indent = False
1451
1451
1452 if not self.readline_use or not readline.have_readline:
1452 if not self.readline_use or not readline.have_readline:
1453 self.has_readline = False
1453 self.has_readline = False
1454 self.readline = None
1454 self.readline = None
1455 # Set a number of methods that depend on readline to be no-op
1455 # Set a number of methods that depend on readline to be no-op
1456 self.savehist = no_op
1456 self.savehist = no_op
1457 self.reloadhist = no_op
1457 self.reloadhist = no_op
1458 self.set_completer = no_op
1458 self.set_completer = no_op
1459 self.set_custom_completer = no_op
1459 self.set_custom_completer = no_op
1460 self.set_completer_frame = no_op
1460 self.set_completer_frame = no_op
1461 warn('Readline services not available or not loaded.')
1461 warn('Readline services not available or not loaded.')
1462 else:
1462 else:
1463 self.has_readline = True
1463 self.has_readline = True
1464 self.readline = readline
1464 self.readline = readline
1465 sys.modules['readline'] = readline
1465 sys.modules['readline'] = readline
1466 import atexit
1466 import atexit
1467 from IPython.core.completer import IPCompleter
1467 from IPython.core.completer import IPCompleter
1468 self.Completer = IPCompleter(self,
1468 self.Completer = IPCompleter(self,
1469 self.user_ns,
1469 self.user_ns,
1470 self.user_global_ns,
1470 self.user_global_ns,
1471 self.readline_omit__names,
1471 self.readline_omit__names,
1472 self.alias_manager.alias_table)
1472 self.alias_manager.alias_table)
1473 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1473 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1474 self.strdispatchers['complete_command'] = sdisp
1474 self.strdispatchers['complete_command'] = sdisp
1475 self.Completer.custom_completers = sdisp
1475 self.Completer.custom_completers = sdisp
1476 # Platform-specific configuration
1476 # Platform-specific configuration
1477 if os.name == 'nt':
1477 if os.name == 'nt':
1478 self.readline_startup_hook = readline.set_pre_input_hook
1478 self.readline_startup_hook = readline.set_pre_input_hook
1479 else:
1479 else:
1480 self.readline_startup_hook = readline.set_startup_hook
1480 self.readline_startup_hook = readline.set_startup_hook
1481
1481
1482 # Load user's initrc file (readline config)
1482 # Load user's initrc file (readline config)
1483 # Or if libedit is used, load editrc.
1483 # Or if libedit is used, load editrc.
1484 inputrc_name = os.environ.get('INPUTRC')
1484 inputrc_name = os.environ.get('INPUTRC')
1485 if inputrc_name is None:
1485 if inputrc_name is None:
1486 home_dir = get_home_dir()
1486 home_dir = get_home_dir()
1487 if home_dir is not None:
1487 if home_dir is not None:
1488 inputrc_name = '.inputrc'
1488 inputrc_name = '.inputrc'
1489 if readline.uses_libedit:
1489 if readline.uses_libedit:
1490 inputrc_name = '.editrc'
1490 inputrc_name = '.editrc'
1491 inputrc_name = os.path.join(home_dir, inputrc_name)
1491 inputrc_name = os.path.join(home_dir, inputrc_name)
1492 if os.path.isfile(inputrc_name):
1492 if os.path.isfile(inputrc_name):
1493 try:
1493 try:
1494 readline.read_init_file(inputrc_name)
1494 readline.read_init_file(inputrc_name)
1495 except:
1495 except:
1496 warn('Problems reading readline initialization file <%s>'
1496 warn('Problems reading readline initialization file <%s>'
1497 % inputrc_name)
1497 % inputrc_name)
1498
1498
1499 # save this in sys so embedded copies can restore it properly
1499 # save this in sys so embedded copies can restore it properly
1500 sys.ipcompleter = self.Completer.rlcomplete
1500 sys.ipcompleter = self.Completer.rlcomplete
1501 self.set_completer()
1501 self.set_completer()
1502
1502
1503 # Configure readline according to user's prefs
1503 # Configure readline according to user's prefs
1504 # This is only done if GNU readline is being used. If libedit
1504 # This is only done if GNU readline is being used. If libedit
1505 # is being used (as on Leopard) the readline config is
1505 # is being used (as on Leopard) the readline config is
1506 # not run as the syntax for libedit is different.
1506 # not run as the syntax for libedit is different.
1507 if not readline.uses_libedit:
1507 if not readline.uses_libedit:
1508 for rlcommand in self.readline_parse_and_bind:
1508 for rlcommand in self.readline_parse_and_bind:
1509 #print "loading rl:",rlcommand # dbg
1509 #print "loading rl:",rlcommand # dbg
1510 readline.parse_and_bind(rlcommand)
1510 readline.parse_and_bind(rlcommand)
1511
1511
1512 # Remove some chars from the delimiters list. If we encounter
1512 # Remove some chars from the delimiters list. If we encounter
1513 # unicode chars, discard them.
1513 # unicode chars, discard them.
1514 delims = readline.get_completer_delims().encode("ascii", "ignore")
1514 delims = readline.get_completer_delims().encode("ascii", "ignore")
1515 delims = delims.translate(string._idmap,
1515 delims = delims.translate(string._idmap,
1516 self.readline_remove_delims)
1516 self.readline_remove_delims)
1517 readline.set_completer_delims(delims)
1517 readline.set_completer_delims(delims)
1518 # otherwise we end up with a monster history after a while:
1518 # otherwise we end up with a monster history after a while:
1519 readline.set_history_length(1000)
1519 readline.set_history_length(1000)
1520 try:
1520 try:
1521 #print '*** Reading readline history' # dbg
1521 #print '*** Reading readline history' # dbg
1522 readline.read_history_file(self.histfile)
1522 readline.read_history_file(self.histfile)
1523 except IOError:
1523 except IOError:
1524 pass # It doesn't exist yet.
1524 pass # It doesn't exist yet.
1525
1525
1526 atexit.register(self.atexit_operations)
1526 atexit.register(self.atexit_operations)
1527 del atexit
1527 del atexit
1528
1528
1529 # Configure auto-indent for all platforms
1529 # Configure auto-indent for all platforms
1530 self.set_autoindent(self.autoindent)
1530 self.set_autoindent(self.autoindent)
1531
1531
1532 def set_next_input(self, s):
1532 def set_next_input(self, s):
1533 """ Sets the 'default' input string for the next command line.
1533 """ Sets the 'default' input string for the next command line.
1534
1534
1535 Requires readline.
1535 Requires readline.
1536
1536
1537 Example:
1537 Example:
1538
1538
1539 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1539 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1540 [D:\ipython]|2> Hello Word_ # cursor is here
1540 [D:\ipython]|2> Hello Word_ # cursor is here
1541 """
1541 """
1542
1542
1543 self.rl_next_input = s
1543 self.rl_next_input = s
1544
1544
1545 # Maybe move this to the terminal subclass?
1545 # Maybe move this to the terminal subclass?
1546 def pre_readline(self):
1546 def pre_readline(self):
1547 """readline hook to be used at the start of each line.
1547 """readline hook to be used at the start of each line.
1548
1548
1549 Currently it handles auto-indent only."""
1549 Currently it handles auto-indent only."""
1550
1550
1551 if self.rl_do_indent:
1551 if self.rl_do_indent:
1552 self.readline.insert_text(self._indent_current_str())
1552 self.readline.insert_text(self._indent_current_str())
1553 if self.rl_next_input is not None:
1553 if self.rl_next_input is not None:
1554 self.readline.insert_text(self.rl_next_input)
1554 self.readline.insert_text(self.rl_next_input)
1555 self.rl_next_input = None
1555 self.rl_next_input = None
1556
1556
1557 def _indent_current_str(self):
1557 def _indent_current_str(self):
1558 """return the current level of indentation as a string"""
1558 """return the current level of indentation as a string"""
1559 return self.indent_current_nsp * ' '
1559 return self.indent_current_nsp * ' '
1560
1560
1561 #-------------------------------------------------------------------------
1561 #-------------------------------------------------------------------------
1562 # Things related to magics
1562 # Things related to magics
1563 #-------------------------------------------------------------------------
1563 #-------------------------------------------------------------------------
1564
1564
1565 def init_magics(self):
1565 def init_magics(self):
1566 # FIXME: Move the color initialization to the DisplayHook, which
1566 # FIXME: Move the color initialization to the DisplayHook, which
1567 # should be split into a prompt manager and displayhook. We probably
1567 # should be split into a prompt manager and displayhook. We probably
1568 # even need a centralize colors management object.
1568 # even need a centralize colors management object.
1569 self.magic_colors(self.colors)
1569 self.magic_colors(self.colors)
1570 # History was moved to a separate module
1570 # History was moved to a separate module
1571 from . import history
1571 from . import history
1572 history.init_ipython(self)
1572 history.init_ipython(self)
1573
1573
1574 def magic(self,arg_s):
1574 def magic(self,arg_s):
1575 """Call a magic function by name.
1575 """Call a magic function by name.
1576
1576
1577 Input: a string containing the name of the magic function to call and any
1577 Input: a string containing the name of the magic function to call and any
1578 additional arguments to be passed to the magic.
1578 additional arguments to be passed to the magic.
1579
1579
1580 magic('name -opt foo bar') is equivalent to typing at the ipython
1580 magic('name -opt foo bar') is equivalent to typing at the ipython
1581 prompt:
1581 prompt:
1582
1582
1583 In[1]: %name -opt foo bar
1583 In[1]: %name -opt foo bar
1584
1584
1585 To call a magic without arguments, simply use magic('name').
1585 To call a magic without arguments, simply use magic('name').
1586
1586
1587 This provides a proper Python function to call IPython's magics in any
1587 This provides a proper Python function to call IPython's magics in any
1588 valid Python code you can type at the interpreter, including loops and
1588 valid Python code you can type at the interpreter, including loops and
1589 compound statements.
1589 compound statements.
1590 """
1590 """
1591 args = arg_s.split(' ',1)
1591 args = arg_s.split(' ',1)
1592 magic_name = args[0]
1592 magic_name = args[0]
1593 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1593 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1594
1594
1595 try:
1595 try:
1596 magic_args = args[1]
1596 magic_args = args[1]
1597 except IndexError:
1597 except IndexError:
1598 magic_args = ''
1598 magic_args = ''
1599 fn = getattr(self,'magic_'+magic_name,None)
1599 fn = getattr(self,'magic_'+magic_name,None)
1600 if fn is None:
1600 if fn is None:
1601 error("Magic function `%s` not found." % magic_name)
1601 error("Magic function `%s` not found." % magic_name)
1602 else:
1602 else:
1603 magic_args = self.var_expand(magic_args,1)
1603 magic_args = self.var_expand(magic_args,1)
1604 with nested(self.builtin_trap,):
1604 with nested(self.builtin_trap,):
1605 result = fn(magic_args)
1605 result = fn(magic_args)
1606 return result
1606 return result
1607
1607
1608 def define_magic(self, magicname, func):
1608 def define_magic(self, magicname, func):
1609 """Expose own function as magic function for ipython
1609 """Expose own function as magic function for ipython
1610
1610
1611 def foo_impl(self,parameter_s=''):
1611 def foo_impl(self,parameter_s=''):
1612 'My very own magic!. (Use docstrings, IPython reads them).'
1612 'My very own magic!. (Use docstrings, IPython reads them).'
1613 print 'Magic function. Passed parameter is between < >:'
1613 print 'Magic function. Passed parameter is between < >:'
1614 print '<%s>' % parameter_s
1614 print '<%s>' % parameter_s
1615 print 'The self object is:',self
1615 print 'The self object is:',self
1616
1616
1617 self.define_magic('foo',foo_impl)
1617 self.define_magic('foo',foo_impl)
1618 """
1618 """
1619
1619
1620 import new
1620 import new
1621 im = new.instancemethod(func,self, self.__class__)
1621 im = new.instancemethod(func,self, self.__class__)
1622 old = getattr(self, "magic_" + magicname, None)
1622 old = getattr(self, "magic_" + magicname, None)
1623 setattr(self, "magic_" + magicname, im)
1623 setattr(self, "magic_" + magicname, im)
1624 return old
1624 return old
1625
1625
1626 #-------------------------------------------------------------------------
1626 #-------------------------------------------------------------------------
1627 # Things related to macros
1627 # Things related to macros
1628 #-------------------------------------------------------------------------
1628 #-------------------------------------------------------------------------
1629
1629
1630 def define_macro(self, name, themacro):
1630 def define_macro(self, name, themacro):
1631 """Define a new macro
1631 """Define a new macro
1632
1632
1633 Parameters
1633 Parameters
1634 ----------
1634 ----------
1635 name : str
1635 name : str
1636 The name of the macro.
1636 The name of the macro.
1637 themacro : str or Macro
1637 themacro : str or Macro
1638 The action to do upon invoking the macro. If a string, a new
1638 The action to do upon invoking the macro. If a string, a new
1639 Macro object is created by passing the string to it.
1639 Macro object is created by passing the string to it.
1640 """
1640 """
1641
1641
1642 from IPython.core import macro
1642 from IPython.core import macro
1643
1643
1644 if isinstance(themacro, basestring):
1644 if isinstance(themacro, basestring):
1645 themacro = macro.Macro(themacro)
1645 themacro = macro.Macro(themacro)
1646 if not isinstance(themacro, macro.Macro):
1646 if not isinstance(themacro, macro.Macro):
1647 raise ValueError('A macro must be a string or a Macro instance.')
1647 raise ValueError('A macro must be a string or a Macro instance.')
1648 self.user_ns[name] = themacro
1648 self.user_ns[name] = themacro
1649
1649
1650 #-------------------------------------------------------------------------
1650 #-------------------------------------------------------------------------
1651 # Things related to the running of system commands
1651 # Things related to the running of system commands
1652 #-------------------------------------------------------------------------
1652 #-------------------------------------------------------------------------
1653
1653
1654 def system(self, cmd):
1654 def system(self, cmd):
1655 """Call the given cmd in a subprocess."""
1655 """Call the given cmd in a subprocess."""
1656 # We do not support backgrounding processes because we either use
1656 # We do not support backgrounding processes because we either use
1657 # pexpect or pipes to read from. Users can always just call
1657 # pexpect or pipes to read from. Users can always just call
1658 # os.system() if they really want a background process.
1658 # os.system() if they really want a background process.
1659 if cmd.endswith('&'):
1659 if cmd.endswith('&'):
1660 raise OSError("Background processes not supported.")
1660 raise OSError("Background processes not supported.")
1661
1661
1662 return system(self.var_expand(cmd, depth=2))
1662 return system(self.var_expand(cmd, depth=2))
1663
1663
1664 def getoutput(self, cmd):
1664 def getoutput(self, cmd):
1665 """Get output (possibly including stderr) from a subprocess."""
1665 """Get output (possibly including stderr) from a subprocess."""
1666 if cmd.endswith('&'):
1666 if cmd.endswith('&'):
1667 raise OSError("Background processes not supported.")
1667 raise OSError("Background processes not supported.")
1668 return getoutput(self.var_expand(cmd, depth=2))
1668 return getoutput(self.var_expand(cmd, depth=2))
1669
1669
1670 #-------------------------------------------------------------------------
1670 #-------------------------------------------------------------------------
1671 # Things related to aliases
1671 # Things related to aliases
1672 #-------------------------------------------------------------------------
1672 #-------------------------------------------------------------------------
1673
1673
1674 def init_alias(self):
1674 def init_alias(self):
1675 self.alias_manager = AliasManager(shell=self, config=self.config)
1675 self.alias_manager = AliasManager(shell=self, config=self.config)
1676 self.ns_table['alias'] = self.alias_manager.alias_table,
1676 self.ns_table['alias'] = self.alias_manager.alias_table,
1677
1677
1678 #-------------------------------------------------------------------------
1678 #-------------------------------------------------------------------------
1679 # Things related to extensions and plugins
1679 # Things related to extensions and plugins
1680 #-------------------------------------------------------------------------
1680 #-------------------------------------------------------------------------
1681
1681
1682 def init_extension_manager(self):
1682 def init_extension_manager(self):
1683 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1683 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1684
1684
1685 def init_plugin_manager(self):
1685 def init_plugin_manager(self):
1686 self.plugin_manager = PluginManager(config=self.config)
1686 self.plugin_manager = PluginManager(config=self.config)
1687
1687
1688 #-------------------------------------------------------------------------
1688 #-------------------------------------------------------------------------
1689 # Things related to payloads
1689 # Things related to payloads
1690 #-------------------------------------------------------------------------
1690 #-------------------------------------------------------------------------
1691
1691
1692 def init_payload(self):
1692 def init_payload(self):
1693 self.payload_manager = PayloadManager(config=self.config)
1693 self.payload_manager = PayloadManager(config=self.config)
1694
1694
1695 #-------------------------------------------------------------------------
1695 #-------------------------------------------------------------------------
1696 # Things related to the prefilter
1696 # Things related to the prefilter
1697 #-------------------------------------------------------------------------
1697 #-------------------------------------------------------------------------
1698
1698
1699 def init_prefilter(self):
1699 def init_prefilter(self):
1700 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1700 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1701 # Ultimately this will be refactored in the new interpreter code, but
1701 # Ultimately this will be refactored in the new interpreter code, but
1702 # for now, we should expose the main prefilter method (there's legacy
1702 # for now, we should expose the main prefilter method (there's legacy
1703 # code out there that may rely on this).
1703 # code out there that may rely on this).
1704 self.prefilter = self.prefilter_manager.prefilter_lines
1704 self.prefilter = self.prefilter_manager.prefilter_lines
1705
1705
1706 #-------------------------------------------------------------------------
1706 #-------------------------------------------------------------------------
1707 # Things related to extracting values/expressions from kernel and user_ns
1708 #-------------------------------------------------------------------------
1709
1710 def _simple_error(self):
1711 etype, value = sys.exc_info()[:2]
1712 return u'[ERROR] {e.__name__}: {v}'.format(e=etype, v=value)
1713
1714 def get_user_variables(self, names):
1715 """Get a list of variable names from the user's namespace.
1716
1717 The return value is a dict with the repr() of each value.
1718 """
1719 out = {}
1720 user_ns = self.user_ns
1721 for varname in names:
1722 try:
1723 value = repr(user_ns[varname])
1724 except:
1725 value = self._simple_error()
1726 out[varname] = value
1727 return out
1728
1729 def eval_expressions(self, expressions):
1730 """Evaluate a dict of expressions in the user's namespace.
1731
1732 The return value is a dict with the repr() of each value.
1733 """
1734 out = {}
1735 user_ns = self.user_ns
1736 global_ns = self.user_global_ns
1737 for key, expr in expressions.iteritems():
1738 try:
1739 value = repr(eval(expr, global_ns, user_ns))
1740 except:
1741 value = self._simple_error()
1742 out[key] = value
1743 return out
1744
1745 #-------------------------------------------------------------------------
1707 # Things related to the running of code
1746 # Things related to the running of code
1708 #-------------------------------------------------------------------------
1747 #-------------------------------------------------------------------------
1709
1748
1710 def ex(self, cmd):
1749 def ex(self, cmd):
1711 """Execute a normal python statement in user namespace."""
1750 """Execute a normal python statement in user namespace."""
1712 with nested(self.builtin_trap,):
1751 with nested(self.builtin_trap,):
1713 exec cmd in self.user_global_ns, self.user_ns
1752 exec cmd in self.user_global_ns, self.user_ns
1714
1753
1715 def ev(self, expr):
1754 def ev(self, expr):
1716 """Evaluate python expression expr in user namespace.
1755 """Evaluate python expression expr in user namespace.
1717
1756
1718 Returns the result of evaluation
1757 Returns the result of evaluation
1719 """
1758 """
1720 with nested(self.builtin_trap,):
1759 with nested(self.builtin_trap,):
1721 return eval(expr, self.user_global_ns, self.user_ns)
1760 return eval(expr, self.user_global_ns, self.user_ns)
1722
1761
1723 def safe_execfile(self, fname, *where, **kw):
1762 def safe_execfile(self, fname, *where, **kw):
1724 """A safe version of the builtin execfile().
1763 """A safe version of the builtin execfile().
1725
1764
1726 This version will never throw an exception, but instead print
1765 This version will never throw an exception, but instead print
1727 helpful error messages to the screen. This only works on pure
1766 helpful error messages to the screen. This only works on pure
1728 Python files with the .py extension.
1767 Python files with the .py extension.
1729
1768
1730 Parameters
1769 Parameters
1731 ----------
1770 ----------
1732 fname : string
1771 fname : string
1733 The name of the file to be executed.
1772 The name of the file to be executed.
1734 where : tuple
1773 where : tuple
1735 One or two namespaces, passed to execfile() as (globals,locals).
1774 One or two namespaces, passed to execfile() as (globals,locals).
1736 If only one is given, it is passed as both.
1775 If only one is given, it is passed as both.
1737 exit_ignore : bool (False)
1776 exit_ignore : bool (False)
1738 If True, then silence SystemExit for non-zero status (it is always
1777 If True, then silence SystemExit for non-zero status (it is always
1739 silenced for zero status, as it is so common).
1778 silenced for zero status, as it is so common).
1740 """
1779 """
1741 kw.setdefault('exit_ignore', False)
1780 kw.setdefault('exit_ignore', False)
1742
1781
1743 fname = os.path.abspath(os.path.expanduser(fname))
1782 fname = os.path.abspath(os.path.expanduser(fname))
1744
1783
1745 # Make sure we have a .py file
1784 # Make sure we have a .py file
1746 if not fname.endswith('.py'):
1785 if not fname.endswith('.py'):
1747 warn('File must end with .py to be run using execfile: <%s>' % fname)
1786 warn('File must end with .py to be run using execfile: <%s>' % fname)
1748
1787
1749 # Make sure we can open the file
1788 # Make sure we can open the file
1750 try:
1789 try:
1751 with open(fname) as thefile:
1790 with open(fname) as thefile:
1752 pass
1791 pass
1753 except:
1792 except:
1754 warn('Could not open file <%s> for safe execution.' % fname)
1793 warn('Could not open file <%s> for safe execution.' % fname)
1755 return
1794 return
1756
1795
1757 # Find things also in current directory. This is needed to mimic the
1796 # Find things also in current directory. This is needed to mimic the
1758 # behavior of running a script from the system command line, where
1797 # behavior of running a script from the system command line, where
1759 # Python inserts the script's directory into sys.path
1798 # Python inserts the script's directory into sys.path
1760 dname = os.path.dirname(fname)
1799 dname = os.path.dirname(fname)
1761
1800
1762 with prepended_to_syspath(dname):
1801 with prepended_to_syspath(dname):
1763 try:
1802 try:
1764 execfile(fname,*where)
1803 execfile(fname,*where)
1765 except SystemExit, status:
1804 except SystemExit, status:
1766 # If the call was made with 0 or None exit status (sys.exit(0)
1805 # If the call was made with 0 or None exit status (sys.exit(0)
1767 # or sys.exit() ), don't bother showing a traceback, as both of
1806 # or sys.exit() ), don't bother showing a traceback, as both of
1768 # these are considered normal by the OS:
1807 # these are considered normal by the OS:
1769 # > python -c'import sys;sys.exit(0)'; echo $?
1808 # > python -c'import sys;sys.exit(0)'; echo $?
1770 # 0
1809 # 0
1771 # > python -c'import sys;sys.exit()'; echo $?
1810 # > python -c'import sys;sys.exit()'; echo $?
1772 # 0
1811 # 0
1773 # For other exit status, we show the exception unless
1812 # For other exit status, we show the exception unless
1774 # explicitly silenced, but only in short form.
1813 # explicitly silenced, but only in short form.
1775 if status.code not in (0, None) and not kw['exit_ignore']:
1814 if status.code not in (0, None) and not kw['exit_ignore']:
1776 self.showtraceback(exception_only=True)
1815 self.showtraceback(exception_only=True)
1777 except:
1816 except:
1778 self.showtraceback()
1817 self.showtraceback()
1779
1818
1780 def safe_execfile_ipy(self, fname):
1819 def safe_execfile_ipy(self, fname):
1781 """Like safe_execfile, but for .ipy files with IPython syntax.
1820 """Like safe_execfile, but for .ipy files with IPython syntax.
1782
1821
1783 Parameters
1822 Parameters
1784 ----------
1823 ----------
1785 fname : str
1824 fname : str
1786 The name of the file to execute. The filename must have a
1825 The name of the file to execute. The filename must have a
1787 .ipy extension.
1826 .ipy extension.
1788 """
1827 """
1789 fname = os.path.abspath(os.path.expanduser(fname))
1828 fname = os.path.abspath(os.path.expanduser(fname))
1790
1829
1791 # Make sure we have a .py file
1830 # Make sure we have a .py file
1792 if not fname.endswith('.ipy'):
1831 if not fname.endswith('.ipy'):
1793 warn('File must end with .py to be run using execfile: <%s>' % fname)
1832 warn('File must end with .py to be run using execfile: <%s>' % fname)
1794
1833
1795 # Make sure we can open the file
1834 # Make sure we can open the file
1796 try:
1835 try:
1797 with open(fname) as thefile:
1836 with open(fname) as thefile:
1798 pass
1837 pass
1799 except:
1838 except:
1800 warn('Could not open file <%s> for safe execution.' % fname)
1839 warn('Could not open file <%s> for safe execution.' % fname)
1801 return
1840 return
1802
1841
1803 # Find things also in current directory. This is needed to mimic the
1842 # Find things also in current directory. This is needed to mimic the
1804 # behavior of running a script from the system command line, where
1843 # behavior of running a script from the system command line, where
1805 # Python inserts the script's directory into sys.path
1844 # Python inserts the script's directory into sys.path
1806 dname = os.path.dirname(fname)
1845 dname = os.path.dirname(fname)
1807
1846
1808 with prepended_to_syspath(dname):
1847 with prepended_to_syspath(dname):
1809 try:
1848 try:
1810 with open(fname) as thefile:
1849 with open(fname) as thefile:
1811 script = thefile.read()
1850 script = thefile.read()
1812 # self.runlines currently captures all exceptions
1851 # self.runlines currently captures all exceptions
1813 # raise in user code. It would be nice if there were
1852 # raise in user code. It would be nice if there were
1814 # versions of runlines, execfile that did raise, so
1853 # versions of runlines, execfile that did raise, so
1815 # we could catch the errors.
1854 # we could catch the errors.
1816 self.runlines(script, clean=True)
1855 self.runlines(script, clean=True)
1817 except:
1856 except:
1818 self.showtraceback()
1857 self.showtraceback()
1819 warn('Unknown failure executing file: <%s>' % fname)
1858 warn('Unknown failure executing file: <%s>' % fname)
1820
1859
1821 def runlines(self, lines, clean=False):
1860 def runlines(self, lines, clean=False):
1822 """Run a string of one or more lines of source.
1861 """Run a string of one or more lines of source.
1823
1862
1824 This method is capable of running a string containing multiple source
1863 This method is capable of running a string containing multiple source
1825 lines, as if they had been entered at the IPython prompt. Since it
1864 lines, as if they had been entered at the IPython prompt. Since it
1826 exposes IPython's processing machinery, the given strings can contain
1865 exposes IPython's processing machinery, the given strings can contain
1827 magic calls (%magic), special shell access (!cmd), etc.
1866 magic calls (%magic), special shell access (!cmd), etc.
1828 """
1867 """
1829
1868
1830 if isinstance(lines, (list, tuple)):
1869 if isinstance(lines, (list, tuple)):
1831 lines = '\n'.join(lines)
1870 lines = '\n'.join(lines)
1832
1871
1833 if clean:
1872 if clean:
1834 lines = self._cleanup_ipy_script(lines)
1873 lines = self._cleanup_ipy_script(lines)
1835
1874
1836 # We must start with a clean buffer, in case this is run from an
1875 # We must start with a clean buffer, in case this is run from an
1837 # interactive IPython session (via a magic, for example).
1876 # interactive IPython session (via a magic, for example).
1838 self.resetbuffer()
1877 self.resetbuffer()
1839 lines = lines.splitlines()
1878 lines = lines.splitlines()
1840 more = 0
1879 more = 0
1841 with nested(self.builtin_trap, self.display_trap):
1880 with nested(self.builtin_trap, self.display_trap):
1842 for line in lines:
1881 for line in lines:
1843 # skip blank lines so we don't mess up the prompt counter, but do
1882 # skip blank lines so we don't mess up the prompt counter, but do
1844 # NOT skip even a blank line if we are in a code block (more is
1883 # NOT skip even a blank line if we are in a code block (more is
1845 # true)
1884 # true)
1846
1885
1847 if line or more:
1886 if line or more:
1848 # push to raw history, so hist line numbers stay in sync
1887 # push to raw history, so hist line numbers stay in sync
1849 self.input_hist_raw.append(line + '\n')
1888 self.input_hist_raw.append(line + '\n')
1850 prefiltered = self.prefilter_manager.prefilter_lines(line,
1889 prefiltered = self.prefilter_manager.prefilter_lines(line,
1851 more)
1890 more)
1852 more = self.push_line(prefiltered)
1891 more = self.push_line(prefiltered)
1853 # IPython's runsource returns None if there was an error
1892 # IPython's runsource returns None if there was an error
1854 # compiling the code. This allows us to stop processing right
1893 # compiling the code. This allows us to stop processing right
1855 # away, so the user gets the error message at the right place.
1894 # away, so the user gets the error message at the right place.
1856 if more is None:
1895 if more is None:
1857 break
1896 break
1858 else:
1897 else:
1859 self.input_hist_raw.append("\n")
1898 self.input_hist_raw.append("\n")
1860 # final newline in case the input didn't have it, so that the code
1899 # final newline in case the input didn't have it, so that the code
1861 # actually does get executed
1900 # actually does get executed
1862 if more:
1901 if more:
1863 self.push_line('\n')
1902 self.push_line('\n')
1864
1903
1865 def runsource(self, source, filename='<input>', symbol='single'):
1904 def runsource(self, source, filename='<input>', symbol='single'):
1866 """Compile and run some source in the interpreter.
1905 """Compile and run some source in the interpreter.
1867
1906
1868 Arguments are as for compile_command().
1907 Arguments are as for compile_command().
1869
1908
1870 One several things can happen:
1909 One several things can happen:
1871
1910
1872 1) The input is incorrect; compile_command() raised an
1911 1) The input is incorrect; compile_command() raised an
1873 exception (SyntaxError or OverflowError). A syntax traceback
1912 exception (SyntaxError or OverflowError). A syntax traceback
1874 will be printed by calling the showsyntaxerror() method.
1913 will be printed by calling the showsyntaxerror() method.
1875
1914
1876 2) The input is incomplete, and more input is required;
1915 2) The input is incomplete, and more input is required;
1877 compile_command() returned None. Nothing happens.
1916 compile_command() returned None. Nothing happens.
1878
1917
1879 3) The input is complete; compile_command() returned a code
1918 3) The input is complete; compile_command() returned a code
1880 object. The code is executed by calling self.runcode() (which
1919 object. The code is executed by calling self.runcode() (which
1881 also handles run-time exceptions, except for SystemExit).
1920 also handles run-time exceptions, except for SystemExit).
1882
1921
1883 The return value is:
1922 The return value is:
1884
1923
1885 - True in case 2
1924 - True in case 2
1886
1925
1887 - False in the other cases, unless an exception is raised, where
1926 - False in the other cases, unless an exception is raised, where
1888 None is returned instead. This can be used by external callers to
1927 None is returned instead. This can be used by external callers to
1889 know whether to continue feeding input or not.
1928 know whether to continue feeding input or not.
1890
1929
1891 The return value can be used to decide whether to use sys.ps1 or
1930 The return value can be used to decide whether to use sys.ps1 or
1892 sys.ps2 to prompt the next line."""
1931 sys.ps2 to prompt the next line."""
1893
1932
1894 # if the source code has leading blanks, add 'if 1:\n' to it
1933 # if the source code has leading blanks, add 'if 1:\n' to it
1895 # this allows execution of indented pasted code. It is tempting
1934 # this allows execution of indented pasted code. It is tempting
1896 # to add '\n' at the end of source to run commands like ' a=1'
1935 # to add '\n' at the end of source to run commands like ' a=1'
1897 # directly, but this fails for more complicated scenarios
1936 # directly, but this fails for more complicated scenarios
1898 source=source.encode(self.stdin_encoding)
1937 source=source.encode(self.stdin_encoding)
1899 if source[:1] in [' ', '\t']:
1938 if source[:1] in [' ', '\t']:
1900 source = 'if 1:\n%s' % source
1939 source = 'if 1:\n%s' % source
1901
1940
1902 try:
1941 try:
1903 code = self.compile(source,filename,symbol)
1942 code = self.compile(source,filename,symbol)
1904 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1943 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1905 # Case 1
1944 # Case 1
1906 self.showsyntaxerror(filename)
1945 self.showsyntaxerror(filename)
1907 return None
1946 return None
1908
1947
1909 if code is None:
1948 if code is None:
1910 # Case 2
1949 # Case 2
1911 return True
1950 return True
1912
1951
1913 # Case 3
1952 # Case 3
1914 # We store the code object so that threaded shells and
1953 # We store the code object so that threaded shells and
1915 # custom exception handlers can access all this info if needed.
1954 # custom exception handlers can access all this info if needed.
1916 # The source corresponding to this can be obtained from the
1955 # The source corresponding to this can be obtained from the
1917 # buffer attribute as '\n'.join(self.buffer).
1956 # buffer attribute as '\n'.join(self.buffer).
1918 self.code_to_run = code
1957 self.code_to_run = code
1919 # now actually execute the code object
1958 # now actually execute the code object
1920 if self.runcode(code) == 0:
1959 if self.runcode(code) == 0:
1921 return False
1960 return False
1922 else:
1961 else:
1923 return None
1962 return None
1924
1963
1925 def runcode(self,code_obj):
1964 def runcode(self,code_obj):
1926 """Execute a code object.
1965 """Execute a code object.
1927
1966
1928 When an exception occurs, self.showtraceback() is called to display a
1967 When an exception occurs, self.showtraceback() is called to display a
1929 traceback.
1968 traceback.
1930
1969
1931 Return value: a flag indicating whether the code to be run completed
1970 Return value: a flag indicating whether the code to be run completed
1932 successfully:
1971 successfully:
1933
1972
1934 - 0: successful execution.
1973 - 0: successful execution.
1935 - 1: an error occurred.
1974 - 1: an error occurred.
1936 """
1975 """
1937
1976
1938 # Set our own excepthook in case the user code tries to call it
1977 # Set our own excepthook in case the user code tries to call it
1939 # directly, so that the IPython crash handler doesn't get triggered
1978 # directly, so that the IPython crash handler doesn't get triggered
1940 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1979 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1941
1980
1942 # we save the original sys.excepthook in the instance, in case config
1981 # we save the original sys.excepthook in the instance, in case config
1943 # code (such as magics) needs access to it.
1982 # code (such as magics) needs access to it.
1944 self.sys_excepthook = old_excepthook
1983 self.sys_excepthook = old_excepthook
1945 outflag = 1 # happens in more places, so it's easier as default
1984 outflag = 1 # happens in more places, so it's easier as default
1946 try:
1985 try:
1947 try:
1986 try:
1948 self.hooks.pre_runcode_hook()
1987 self.hooks.pre_runcode_hook()
1949 #rprint('Running code') # dbg
1988 #rprint('Running code') # dbg
1950 exec code_obj in self.user_global_ns, self.user_ns
1989 exec code_obj in self.user_global_ns, self.user_ns
1951 finally:
1990 finally:
1952 # Reset our crash handler in place
1991 # Reset our crash handler in place
1953 sys.excepthook = old_excepthook
1992 sys.excepthook = old_excepthook
1954 except SystemExit:
1993 except SystemExit:
1955 self.resetbuffer()
1994 self.resetbuffer()
1956 self.showtraceback(exception_only=True)
1995 self.showtraceback(exception_only=True)
1957 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1996 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1958 except self.custom_exceptions:
1997 except self.custom_exceptions:
1959 etype,value,tb = sys.exc_info()
1998 etype,value,tb = sys.exc_info()
1960 self.CustomTB(etype,value,tb)
1999 self.CustomTB(etype,value,tb)
1961 except:
2000 except:
1962 self.showtraceback()
2001 self.showtraceback()
1963 else:
2002 else:
1964 outflag = 0
2003 outflag = 0
1965 if softspace(sys.stdout, 0):
2004 if softspace(sys.stdout, 0):
1966 print
2005 print
1967 # Flush out code object which has been run (and source)
2006 # Flush out code object which has been run (and source)
1968 self.code_to_run = None
2007 self.code_to_run = None
1969 return outflag
2008 return outflag
1970
2009
1971 def push_line(self, line):
2010 def push_line(self, line):
1972 """Push a line to the interpreter.
2011 """Push a line to the interpreter.
1973
2012
1974 The line should not have a trailing newline; it may have
2013 The line should not have a trailing newline; it may have
1975 internal newlines. The line is appended to a buffer and the
2014 internal newlines. The line is appended to a buffer and the
1976 interpreter's runsource() method is called with the
2015 interpreter's runsource() method is called with the
1977 concatenated contents of the buffer as source. If this
2016 concatenated contents of the buffer as source. If this
1978 indicates that the command was executed or invalid, the buffer
2017 indicates that the command was executed or invalid, the buffer
1979 is reset; otherwise, the command is incomplete, and the buffer
2018 is reset; otherwise, the command is incomplete, and the buffer
1980 is left as it was after the line was appended. The return
2019 is left as it was after the line was appended. The return
1981 value is 1 if more input is required, 0 if the line was dealt
2020 value is 1 if more input is required, 0 if the line was dealt
1982 with in some way (this is the same as runsource()).
2021 with in some way (this is the same as runsource()).
1983 """
2022 """
1984
2023
1985 # autoindent management should be done here, and not in the
2024 # autoindent management should be done here, and not in the
1986 # interactive loop, since that one is only seen by keyboard input. We
2025 # interactive loop, since that one is only seen by keyboard input. We
1987 # need this done correctly even for code run via runlines (which uses
2026 # need this done correctly even for code run via runlines (which uses
1988 # push).
2027 # push).
1989
2028
1990 #print 'push line: <%s>' % line # dbg
2029 #print 'push line: <%s>' % line # dbg
1991 for subline in line.splitlines():
2030 for subline in line.splitlines():
1992 self._autoindent_update(subline)
2031 self._autoindent_update(subline)
1993 self.buffer.append(line)
2032 self.buffer.append(line)
1994 more = self.runsource('\n'.join(self.buffer), self.filename)
2033 more = self.runsource('\n'.join(self.buffer), self.filename)
1995 if not more:
2034 if not more:
1996 self.resetbuffer()
2035 self.resetbuffer()
1997 return more
2036 return more
1998
2037
1999 def resetbuffer(self):
2038 def resetbuffer(self):
2000 """Reset the input buffer."""
2039 """Reset the input buffer."""
2001 self.buffer[:] = []
2040 self.buffer[:] = []
2002
2041
2003 def _is_secondary_block_start(self, s):
2042 def _is_secondary_block_start(self, s):
2004 if not s.endswith(':'):
2043 if not s.endswith(':'):
2005 return False
2044 return False
2006 if (s.startswith('elif') or
2045 if (s.startswith('elif') or
2007 s.startswith('else') or
2046 s.startswith('else') or
2008 s.startswith('except') or
2047 s.startswith('except') or
2009 s.startswith('finally')):
2048 s.startswith('finally')):
2010 return True
2049 return True
2011
2050
2012 def _cleanup_ipy_script(self, script):
2051 def _cleanup_ipy_script(self, script):
2013 """Make a script safe for self.runlines()
2052 """Make a script safe for self.runlines()
2014
2053
2015 Currently, IPython is lines based, with blocks being detected by
2054 Currently, IPython is lines based, with blocks being detected by
2016 empty lines. This is a problem for block based scripts that may
2055 empty lines. This is a problem for block based scripts that may
2017 not have empty lines after blocks. This script adds those empty
2056 not have empty lines after blocks. This script adds those empty
2018 lines to make scripts safe for running in the current line based
2057 lines to make scripts safe for running in the current line based
2019 IPython.
2058 IPython.
2020 """
2059 """
2021 res = []
2060 res = []
2022 lines = script.splitlines()
2061 lines = script.splitlines()
2023 level = 0
2062 level = 0
2024
2063
2025 for l in lines:
2064 for l in lines:
2026 lstripped = l.lstrip()
2065 lstripped = l.lstrip()
2027 stripped = l.strip()
2066 stripped = l.strip()
2028 if not stripped:
2067 if not stripped:
2029 continue
2068 continue
2030 newlevel = len(l) - len(lstripped)
2069 newlevel = len(l) - len(lstripped)
2031 if level > 0 and newlevel == 0 and \
2070 if level > 0 and newlevel == 0 and \
2032 not self._is_secondary_block_start(stripped):
2071 not self._is_secondary_block_start(stripped):
2033 # add empty line
2072 # add empty line
2034 res.append('')
2073 res.append('')
2035 res.append(l)
2074 res.append(l)
2036 level = newlevel
2075 level = newlevel
2037
2076
2038 return '\n'.join(res) + '\n'
2077 return '\n'.join(res) + '\n'
2039
2078
2040 def _autoindent_update(self,line):
2079 def _autoindent_update(self,line):
2041 """Keep track of the indent level."""
2080 """Keep track of the indent level."""
2042
2081
2043 #debugx('line')
2082 #debugx('line')
2044 #debugx('self.indent_current_nsp')
2083 #debugx('self.indent_current_nsp')
2045 if self.autoindent:
2084 if self.autoindent:
2046 if line:
2085 if line:
2047 inisp = num_ini_spaces(line)
2086 inisp = num_ini_spaces(line)
2048 if inisp < self.indent_current_nsp:
2087 if inisp < self.indent_current_nsp:
2049 self.indent_current_nsp = inisp
2088 self.indent_current_nsp = inisp
2050
2089
2051 if line[-1] == ':':
2090 if line[-1] == ':':
2052 self.indent_current_nsp += 4
2091 self.indent_current_nsp += 4
2053 elif dedent_re.match(line):
2092 elif dedent_re.match(line):
2054 self.indent_current_nsp -= 4
2093 self.indent_current_nsp -= 4
2055 else:
2094 else:
2056 self.indent_current_nsp = 0
2095 self.indent_current_nsp = 0
2057
2096
2058 #-------------------------------------------------------------------------
2097 #-------------------------------------------------------------------------
2059 # Things related to GUI support and pylab
2098 # Things related to GUI support and pylab
2060 #-------------------------------------------------------------------------
2099 #-------------------------------------------------------------------------
2061
2100
2062 def enable_pylab(self, gui=None):
2101 def enable_pylab(self, gui=None):
2063 raise NotImplementedError('Implement enable_pylab in a subclass')
2102 raise NotImplementedError('Implement enable_pylab in a subclass')
2064
2103
2065 #-------------------------------------------------------------------------
2104 #-------------------------------------------------------------------------
2066 # Utilities
2105 # Utilities
2067 #-------------------------------------------------------------------------
2106 #-------------------------------------------------------------------------
2068
2107
2069 def var_expand(self,cmd,depth=0):
2108 def var_expand(self,cmd,depth=0):
2070 """Expand python variables in a string.
2109 """Expand python variables in a string.
2071
2110
2072 The depth argument indicates how many frames above the caller should
2111 The depth argument indicates how many frames above the caller should
2073 be walked to look for the local namespace where to expand variables.
2112 be walked to look for the local namespace where to expand variables.
2074
2113
2075 The global namespace for expansion is always the user's interactive
2114 The global namespace for expansion is always the user's interactive
2076 namespace.
2115 namespace.
2077 """
2116 """
2078
2117
2079 return str(ItplNS(cmd,
2118 return str(ItplNS(cmd,
2080 self.user_ns, # globals
2119 self.user_ns, # globals
2081 # Skip our own frame in searching for locals:
2120 # Skip our own frame in searching for locals:
2082 sys._getframe(depth+1).f_locals # locals
2121 sys._getframe(depth+1).f_locals # locals
2083 ))
2122 ))
2084
2123
2085 def mktempfile(self,data=None):
2124 def mktempfile(self,data=None):
2086 """Make a new tempfile and return its filename.
2125 """Make a new tempfile and return its filename.
2087
2126
2088 This makes a call to tempfile.mktemp, but it registers the created
2127 This makes a call to tempfile.mktemp, but it registers the created
2089 filename internally so ipython cleans it up at exit time.
2128 filename internally so ipython cleans it up at exit time.
2090
2129
2091 Optional inputs:
2130 Optional inputs:
2092
2131
2093 - data(None): if data is given, it gets written out to the temp file
2132 - data(None): if data is given, it gets written out to the temp file
2094 immediately, and the file is closed again."""
2133 immediately, and the file is closed again."""
2095
2134
2096 filename = tempfile.mktemp('.py','ipython_edit_')
2135 filename = tempfile.mktemp('.py','ipython_edit_')
2097 self.tempfiles.append(filename)
2136 self.tempfiles.append(filename)
2098
2137
2099 if data:
2138 if data:
2100 tmp_file = open(filename,'w')
2139 tmp_file = open(filename,'w')
2101 tmp_file.write(data)
2140 tmp_file.write(data)
2102 tmp_file.close()
2141 tmp_file.close()
2103 return filename
2142 return filename
2104
2143
2105 # TODO: This should be removed when Term is refactored.
2144 # TODO: This should be removed when Term is refactored.
2106 def write(self,data):
2145 def write(self,data):
2107 """Write a string to the default output"""
2146 """Write a string to the default output"""
2108 io.Term.cout.write(data)
2147 io.Term.cout.write(data)
2109
2148
2110 # TODO: This should be removed when Term is refactored.
2149 # TODO: This should be removed when Term is refactored.
2111 def write_err(self,data):
2150 def write_err(self,data):
2112 """Write a string to the default error output"""
2151 """Write a string to the default error output"""
2113 io.Term.cerr.write(data)
2152 io.Term.cerr.write(data)
2114
2153
2115 def ask_yes_no(self,prompt,default=True):
2154 def ask_yes_no(self,prompt,default=True):
2116 if self.quiet:
2155 if self.quiet:
2117 return True
2156 return True
2118 return ask_yes_no(prompt,default)
2157 return ask_yes_no(prompt,default)
2119
2158
2120 def show_usage(self):
2159 def show_usage(self):
2121 """Show a usage message"""
2160 """Show a usage message"""
2122 page.page(IPython.core.usage.interactive_usage)
2161 page.page(IPython.core.usage.interactive_usage)
2123
2162
2124 #-------------------------------------------------------------------------
2163 #-------------------------------------------------------------------------
2125 # Things related to IPython exiting
2164 # Things related to IPython exiting
2126 #-------------------------------------------------------------------------
2165 #-------------------------------------------------------------------------
2127
2166
2128 def atexit_operations(self):
2167 def atexit_operations(self):
2129 """This will be executed at the time of exit.
2168 """This will be executed at the time of exit.
2130
2169
2131 Saving of persistent data should be performed here.
2170 Saving of persistent data should be performed here.
2132 """
2171 """
2133 self.savehist()
2172 self.savehist()
2134
2173
2135 # Cleanup all tempfiles left around
2174 # Cleanup all tempfiles left around
2136 for tfile in self.tempfiles:
2175 for tfile in self.tempfiles:
2137 try:
2176 try:
2138 os.unlink(tfile)
2177 os.unlink(tfile)
2139 except OSError:
2178 except OSError:
2140 pass
2179 pass
2141
2180
2142 # Clear all user namespaces to release all references cleanly.
2181 # Clear all user namespaces to release all references cleanly.
2143 self.reset()
2182 self.reset()
2144
2183
2145 # Run user hooks
2184 # Run user hooks
2146 self.hooks.shutdown_hook()
2185 self.hooks.shutdown_hook()
2147
2186
2148 def cleanup(self):
2187 def cleanup(self):
2149 self.restore_sys_module_state()
2188 self.restore_sys_module_state()
2150
2189
2151
2190
2152 class InteractiveShellABC(object):
2191 class InteractiveShellABC(object):
2153 """An abstract base class for InteractiveShell."""
2192 """An abstract base class for InteractiveShell."""
2154 __metaclass__ = abc.ABCMeta
2193 __metaclass__ = abc.ABCMeta
2155
2194
2156 InteractiveShellABC.register(InteractiveShell)
2195 InteractiveShellABC.register(InteractiveShell)
@@ -1,449 +1,466 b''
1 # Standard library imports
1 # Standard library imports
2 import signal
2 import signal
3 import sys
3 import sys
4
4
5 # System library imports
5 # System library imports
6 from pygments.lexers import PythonLexer
6 from pygments.lexers import PythonLexer
7 from PyQt4 import QtCore, QtGui
7 from PyQt4 import QtCore, QtGui
8
8
9 # Local imports
9 # Local imports
10 from IPython.core.inputsplitter import InputSplitter
10 from IPython.core.inputsplitter import InputSplitter
11 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
11 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
12 from IPython.utils.traitlets import Bool
12 from IPython.utils.traitlets import Bool
13 from bracket_matcher import BracketMatcher
13 from bracket_matcher import BracketMatcher
14 from call_tip_widget import CallTipWidget
14 from call_tip_widget import CallTipWidget
15 from completion_lexer import CompletionLexer
15 from completion_lexer import CompletionLexer
16 from console_widget import HistoryConsoleWidget
16 from console_widget import HistoryConsoleWidget
17 from pygments_highlighter import PygmentsHighlighter
17 from pygments_highlighter import PygmentsHighlighter
18
18
19
19
20 class FrontendHighlighter(PygmentsHighlighter):
20 class FrontendHighlighter(PygmentsHighlighter):
21 """ A PygmentsHighlighter that can be turned on and off and that ignores
21 """ A PygmentsHighlighter that can be turned on and off and that ignores
22 prompts.
22 prompts.
23 """
23 """
24
24
25 def __init__(self, frontend):
25 def __init__(self, frontend):
26 super(FrontendHighlighter, self).__init__(frontend._control.document())
26 super(FrontendHighlighter, self).__init__(frontend._control.document())
27 self._current_offset = 0
27 self._current_offset = 0
28 self._frontend = frontend
28 self._frontend = frontend
29 self.highlighting_on = False
29 self.highlighting_on = False
30
30
31 def highlightBlock(self, qstring):
31 def highlightBlock(self, qstring):
32 """ Highlight a block of text. Reimplemented to highlight selectively.
32 """ Highlight a block of text. Reimplemented to highlight selectively.
33 """
33 """
34 if not self.highlighting_on:
34 if not self.highlighting_on:
35 return
35 return
36
36
37 # The input to this function is unicode string that may contain
37 # The input to this function is unicode string that may contain
38 # paragraph break characters, non-breaking spaces, etc. Here we acquire
38 # paragraph break characters, non-breaking spaces, etc. Here we acquire
39 # the string as plain text so we can compare it.
39 # the string as plain text so we can compare it.
40 current_block = self.currentBlock()
40 current_block = self.currentBlock()
41 string = self._frontend._get_block_plain_text(current_block)
41 string = self._frontend._get_block_plain_text(current_block)
42
42
43 # Decide whether to check for the regular or continuation prompt.
43 # Decide whether to check for the regular or continuation prompt.
44 if current_block.contains(self._frontend._prompt_pos):
44 if current_block.contains(self._frontend._prompt_pos):
45 prompt = self._frontend._prompt
45 prompt = self._frontend._prompt
46 else:
46 else:
47 prompt = self._frontend._continuation_prompt
47 prompt = self._frontend._continuation_prompt
48
48
49 # Don't highlight the part of the string that contains the prompt.
49 # Don't highlight the part of the string that contains the prompt.
50 if string.startswith(prompt):
50 if string.startswith(prompt):
51 self._current_offset = len(prompt)
51 self._current_offset = len(prompt)
52 qstring.remove(0, len(prompt))
52 qstring.remove(0, len(prompt))
53 else:
53 else:
54 self._current_offset = 0
54 self._current_offset = 0
55
55
56 PygmentsHighlighter.highlightBlock(self, qstring)
56 PygmentsHighlighter.highlightBlock(self, qstring)
57
57
58 def rehighlightBlock(self, block):
58 def rehighlightBlock(self, block):
59 """ Reimplemented to temporarily enable highlighting if disabled.
59 """ Reimplemented to temporarily enable highlighting if disabled.
60 """
60 """
61 old = self.highlighting_on
61 old = self.highlighting_on
62 self.highlighting_on = True
62 self.highlighting_on = True
63 super(FrontendHighlighter, self).rehighlightBlock(block)
63 super(FrontendHighlighter, self).rehighlightBlock(block)
64 self.highlighting_on = old
64 self.highlighting_on = old
65
65
66 def setFormat(self, start, count, format):
66 def setFormat(self, start, count, format):
67 """ Reimplemented to highlight selectively.
67 """ Reimplemented to highlight selectively.
68 """
68 """
69 start += self._current_offset
69 start += self._current_offset
70 PygmentsHighlighter.setFormat(self, start, count, format)
70 PygmentsHighlighter.setFormat(self, start, count, format)
71
71
72
72
73 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
73 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
74 """ A Qt frontend for a generic Python kernel.
74 """ A Qt frontend for a generic Python kernel.
75 """
75 """
76
76
77 # An option and corresponding signal for overriding the default kernel
77 # An option and corresponding signal for overriding the default kernel
78 # interrupt behavior.
78 # interrupt behavior.
79 custom_interrupt = Bool(False)
79 custom_interrupt = Bool(False)
80 custom_interrupt_requested = QtCore.pyqtSignal()
80 custom_interrupt_requested = QtCore.pyqtSignal()
81
81
82 # An option and corresponding signals for overriding the default kernel
82 # An option and corresponding signals for overriding the default kernel
83 # restart behavior.
83 # restart behavior.
84 custom_restart = Bool(False)
84 custom_restart = Bool(False)
85 custom_restart_kernel_died = QtCore.pyqtSignal(float)
85 custom_restart_kernel_died = QtCore.pyqtSignal(float)
86 custom_restart_requested = QtCore.pyqtSignal()
86 custom_restart_requested = QtCore.pyqtSignal()
87
87
88 # Emitted when an 'execute_reply' has been received from the kernel and
88 # Emitted when an 'execute_reply' has been received from the kernel and
89 # processed by the FrontendWidget.
89 # processed by the FrontendWidget.
90 executed = QtCore.pyqtSignal(object)
90 executed = QtCore.pyqtSignal(object)
91
91
92 # Protected class variables.
92 # Protected class variables.
93 _input_splitter_class = InputSplitter
93 _input_splitter_class = InputSplitter
94
94
95 #---------------------------------------------------------------------------
95 #---------------------------------------------------------------------------
96 # 'object' interface
96 # 'object' interface
97 #---------------------------------------------------------------------------
97 #---------------------------------------------------------------------------
98
98
99 def __init__(self, *args, **kw):
99 def __init__(self, *args, **kw):
100 super(FrontendWidget, self).__init__(*args, **kw)
100 super(FrontendWidget, self).__init__(*args, **kw)
101
101
102 # FrontendWidget protected variables.
102 # FrontendWidget protected variables.
103 self._bracket_matcher = BracketMatcher(self._control)
103 self._bracket_matcher = BracketMatcher(self._control)
104 self._call_tip_widget = CallTipWidget(self._control)
104 self._call_tip_widget = CallTipWidget(self._control)
105 self._completion_lexer = CompletionLexer(PythonLexer())
105 self._completion_lexer = CompletionLexer(PythonLexer())
106 self._hidden = False
106 self._hidden = False
107 self._highlighter = FrontendHighlighter(self)
107 self._highlighter = FrontendHighlighter(self)
108 self._input_splitter = self._input_splitter_class(input_mode='block')
108 self._input_splitter = self._input_splitter_class(input_mode='block')
109 self._kernel_manager = None
109 self._kernel_manager = None
110 self._possible_kernel_restart = False
110 self._possible_kernel_restart = False
111
111
112 # Configure the ConsoleWidget.
112 # Configure the ConsoleWidget.
113 self.tab_width = 4
113 self.tab_width = 4
114 self._set_continuation_prompt('... ')
114 self._set_continuation_prompt('... ')
115
115
116 # Connect signal handlers.
116 # Connect signal handlers.
117 document = self._control.document()
117 document = self._control.document()
118 document.contentsChange.connect(self._document_contents_change)
118 document.contentsChange.connect(self._document_contents_change)
119
119
120 #---------------------------------------------------------------------------
120 #---------------------------------------------------------------------------
121 # 'ConsoleWidget' abstract interface
121 # 'ConsoleWidget' abstract interface
122 #---------------------------------------------------------------------------
122 #---------------------------------------------------------------------------
123
123
124 def _is_complete(self, source, interactive):
124 def _is_complete(self, source, interactive):
125 """ Returns whether 'source' can be completely processed and a new
125 """ Returns whether 'source' can be completely processed and a new
126 prompt created. When triggered by an Enter/Return key press,
126 prompt created. When triggered by an Enter/Return key press,
127 'interactive' is True; otherwise, it is False.
127 'interactive' is True; otherwise, it is False.
128 """
128 """
129 complete = self._input_splitter.push(source.expandtabs(4))
129 complete = self._input_splitter.push(source.expandtabs(4))
130 if interactive:
130 if interactive:
131 complete = not self._input_splitter.push_accepts_more()
131 complete = not self._input_splitter.push_accepts_more()
132 return complete
132 return complete
133
133
134 def _execute(self, source, hidden):
134 def _execute(self, source, hidden, user_variables=None,
135 user_expressions=None):
135 """ Execute 'source'. If 'hidden', do not show any output.
136 """ Execute 'source'. If 'hidden', do not show any output.
136 """
137
137 self.kernel_manager.xreq_channel.execute(source, hidden)
138 See parent class :meth:`execute` docstring for full details.
139 """
140 # tmp code for testing, disable in real use with 'if 0'. Only delete
141 # this code once we have automated tests for these fields.
142 if 0:
143 user_variables = ['x', 'y', 'z']
144 user_expressions = {'sum' : '1+1',
145 'bad syntax' : 'klsdafj kasd f',
146 'bad call' : 'range("hi")',
147 'time' : 'time.time()',
148 }
149 # /end tmp code
150
151 # FIXME - user_variables/expressions are not visible in API above us.
152 self.kernel_manager.xreq_channel.execute(source, hidden,
153 user_variables,
154 user_expressions)
138 self._hidden = hidden
155 self._hidden = hidden
139
156
140 def _prompt_started_hook(self):
157 def _prompt_started_hook(self):
141 """ Called immediately after a new prompt is displayed.
158 """ Called immediately after a new prompt is displayed.
142 """
159 """
143 if not self._reading:
160 if not self._reading:
144 self._highlighter.highlighting_on = True
161 self._highlighter.highlighting_on = True
145
162
146 def _prompt_finished_hook(self):
163 def _prompt_finished_hook(self):
147 """ Called immediately after a prompt is finished, i.e. when some input
164 """ Called immediately after a prompt is finished, i.e. when some input
148 will be processed and a new prompt displayed.
165 will be processed and a new prompt displayed.
149 """
166 """
150 if not self._reading:
167 if not self._reading:
151 self._highlighter.highlighting_on = False
168 self._highlighter.highlighting_on = False
152
169
153 def _tab_pressed(self):
170 def _tab_pressed(self):
154 """ Called when the tab key is pressed. Returns whether to continue
171 """ Called when the tab key is pressed. Returns whether to continue
155 processing the event.
172 processing the event.
156 """
173 """
157 # Perform tab completion if:
174 # Perform tab completion if:
158 # 1) The cursor is in the input buffer.
175 # 1) The cursor is in the input buffer.
159 # 2) There is a non-whitespace character before the cursor.
176 # 2) There is a non-whitespace character before the cursor.
160 text = self._get_input_buffer_cursor_line()
177 text = self._get_input_buffer_cursor_line()
161 if text is None:
178 if text is None:
162 return False
179 return False
163 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
180 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
164 if complete:
181 if complete:
165 self._complete()
182 self._complete()
166 return not complete
183 return not complete
167
184
168 #---------------------------------------------------------------------------
185 #---------------------------------------------------------------------------
169 # 'ConsoleWidget' protected interface
186 # 'ConsoleWidget' protected interface
170 #---------------------------------------------------------------------------
187 #---------------------------------------------------------------------------
171
188
172 def _event_filter_console_keypress(self, event):
189 def _event_filter_console_keypress(self, event):
173 """ Reimplemented to allow execution interruption.
190 """ Reimplemented to allow execution interruption.
174 """
191 """
175 key = event.key()
192 key = event.key()
176 if self._control_key_down(event.modifiers()):
193 if self._control_key_down(event.modifiers()):
177 if key == QtCore.Qt.Key_C and self._executing:
194 if key == QtCore.Qt.Key_C and self._executing:
178 self.interrupt_kernel()
195 self.interrupt_kernel()
179 return True
196 return True
180 elif key == QtCore.Qt.Key_Period:
197 elif key == QtCore.Qt.Key_Period:
181 message = 'Are you sure you want to restart the kernel?'
198 message = 'Are you sure you want to restart the kernel?'
182 self.restart_kernel(message)
199 self.restart_kernel(message)
183 return True
200 return True
184 return super(FrontendWidget, self)._event_filter_console_keypress(event)
201 return super(FrontendWidget, self)._event_filter_console_keypress(event)
185
202
186 def _insert_continuation_prompt(self, cursor):
203 def _insert_continuation_prompt(self, cursor):
187 """ Reimplemented for auto-indentation.
204 """ Reimplemented for auto-indentation.
188 """
205 """
189 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
206 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
190 spaces = self._input_splitter.indent_spaces
207 spaces = self._input_splitter.indent_spaces
191 cursor.insertText('\t' * (spaces / self.tab_width))
208 cursor.insertText('\t' * (spaces / self.tab_width))
192 cursor.insertText(' ' * (spaces % self.tab_width))
209 cursor.insertText(' ' * (spaces % self.tab_width))
193
210
194 #---------------------------------------------------------------------------
211 #---------------------------------------------------------------------------
195 # 'BaseFrontendMixin' abstract interface
212 # 'BaseFrontendMixin' abstract interface
196 #---------------------------------------------------------------------------
213 #---------------------------------------------------------------------------
197
214
198 def _handle_complete_reply(self, rep):
215 def _handle_complete_reply(self, rep):
199 """ Handle replies for tab completion.
216 """ Handle replies for tab completion.
200 """
217 """
201 cursor = self._get_cursor()
218 cursor = self._get_cursor()
202 if rep['parent_header']['msg_id'] == self._complete_id and \
219 if rep['parent_header']['msg_id'] == self._complete_id and \
203 cursor.position() == self._complete_pos:
220 cursor.position() == self._complete_pos:
204 text = '.'.join(self._get_context())
221 text = '.'.join(self._get_context())
205 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
222 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
206 self._complete_with_items(cursor, rep['content']['matches'])
223 self._complete_with_items(cursor, rep['content']['matches'])
207
224
208 def _handle_execute_reply(self, msg):
225 def _handle_execute_reply(self, msg):
209 """ Handles replies for code execution.
226 """ Handles replies for code execution.
210 """
227 """
211 if not self._hidden:
228 if not self._hidden:
212 # Make sure that all output from the SUB channel has been processed
229 # Make sure that all output from the SUB channel has been processed
213 # before writing a new prompt.
230 # before writing a new prompt.
214 self.kernel_manager.sub_channel.flush()
231 self.kernel_manager.sub_channel.flush()
215
232
216 content = msg['content']
233 content = msg['content']
217 status = content['status']
234 status = content['status']
218 if status == 'ok':
235 if status == 'ok':
219 self._process_execute_ok(msg)
236 self._process_execute_ok(msg)
220 elif status == 'error':
237 elif status == 'error':
221 self._process_execute_error(msg)
238 self._process_execute_error(msg)
222 elif status == 'abort':
239 elif status == 'abort':
223 self._process_execute_abort(msg)
240 self._process_execute_abort(msg)
224
241
225 self._show_interpreter_prompt_for_reply(msg)
242 self._show_interpreter_prompt_for_reply(msg)
226 self.executed.emit(msg)
243 self.executed.emit(msg)
227
244
228 def _handle_input_request(self, msg):
245 def _handle_input_request(self, msg):
229 """ Handle requests for raw_input.
246 """ Handle requests for raw_input.
230 """
247 """
231 if self._hidden:
248 if self._hidden:
232 raise RuntimeError('Request for raw input during hidden execution.')
249 raise RuntimeError('Request for raw input during hidden execution.')
233
250
234 # Make sure that all output from the SUB channel has been processed
251 # Make sure that all output from the SUB channel has been processed
235 # before entering readline mode.
252 # before entering readline mode.
236 self.kernel_manager.sub_channel.flush()
253 self.kernel_manager.sub_channel.flush()
237
254
238 def callback(line):
255 def callback(line):
239 self.kernel_manager.rep_channel.input(line)
256 self.kernel_manager.rep_channel.input(line)
240 self._readline(msg['content']['prompt'], callback=callback)
257 self._readline(msg['content']['prompt'], callback=callback)
241
258
242 def _handle_kernel_died(self, since_last_heartbeat):
259 def _handle_kernel_died(self, since_last_heartbeat):
243 """ Handle the kernel's death by asking if the user wants to restart.
260 """ Handle the kernel's death by asking if the user wants to restart.
244 """
261 """
245 message = 'The kernel heartbeat has been inactive for %.2f ' \
262 message = 'The kernel heartbeat has been inactive for %.2f ' \
246 'seconds. Do you want to restart the kernel? You may ' \
263 'seconds. Do you want to restart the kernel? You may ' \
247 'first want to check the network connection.' % \
264 'first want to check the network connection.' % \
248 since_last_heartbeat
265 since_last_heartbeat
249 if self.custom_restart:
266 if self.custom_restart:
250 self.custom_restart_kernel_died.emit(since_last_heartbeat)
267 self.custom_restart_kernel_died.emit(since_last_heartbeat)
251 else:
268 else:
252 self.restart_kernel(message)
269 self.restart_kernel(message)
253
270
254 def _handle_object_info_reply(self, rep):
271 def _handle_object_info_reply(self, rep):
255 """ Handle replies for call tips.
272 """ Handle replies for call tips.
256 """
273 """
257 cursor = self._get_cursor()
274 cursor = self._get_cursor()
258 if rep['parent_header']['msg_id'] == self._call_tip_id and \
275 if rep['parent_header']['msg_id'] == self._call_tip_id and \
259 cursor.position() == self._call_tip_pos:
276 cursor.position() == self._call_tip_pos:
260 doc = rep['content']['docstring']
277 doc = rep['content']['docstring']
261 if doc:
278 if doc:
262 self._call_tip_widget.show_docstring(doc)
279 self._call_tip_widget.show_docstring(doc)
263
280
264 def _handle_pyout(self, msg):
281 def _handle_pyout(self, msg):
265 """ Handle display hook output.
282 """ Handle display hook output.
266 """
283 """
267 if not self._hidden and self._is_from_this_session(msg):
284 if not self._hidden and self._is_from_this_session(msg):
268 self._append_plain_text(msg['content']['data'] + '\n')
285 self._append_plain_text(msg['content']['data'] + '\n')
269
286
270 def _handle_stream(self, msg):
287 def _handle_stream(self, msg):
271 """ Handle stdout, stderr, and stdin.
288 """ Handle stdout, stderr, and stdin.
272 """
289 """
273 if not self._hidden and self._is_from_this_session(msg):
290 if not self._hidden and self._is_from_this_session(msg):
274 self._append_plain_text(msg['content']['data'])
291 self._append_plain_text(msg['content']['data'])
275 self._control.moveCursor(QtGui.QTextCursor.End)
292 self._control.moveCursor(QtGui.QTextCursor.End)
276
293
277 def _started_channels(self):
294 def _started_channels(self):
278 """ Called when the KernelManager channels have started listening or
295 """ Called when the KernelManager channels have started listening or
279 when the frontend is assigned an already listening KernelManager.
296 when the frontend is assigned an already listening KernelManager.
280 """
297 """
281 self._control.clear()
298 self._control.clear()
282 self._append_plain_text(self._get_banner())
299 self._append_plain_text(self._get_banner())
283 self._show_interpreter_prompt()
300 self._show_interpreter_prompt()
284
301
285 def _stopped_channels(self):
302 def _stopped_channels(self):
286 """ Called when the KernelManager channels have stopped listening or
303 """ Called when the KernelManager channels have stopped listening or
287 when a listening KernelManager is removed from the frontend.
304 when a listening KernelManager is removed from the frontend.
288 """
305 """
289 self._executing = self._reading = False
306 self._executing = self._reading = False
290 self._highlighter.highlighting_on = False
307 self._highlighter.highlighting_on = False
291
308
292 #---------------------------------------------------------------------------
309 #---------------------------------------------------------------------------
293 # 'FrontendWidget' interface
310 # 'FrontendWidget' interface
294 #---------------------------------------------------------------------------
311 #---------------------------------------------------------------------------
295
312
296 def execute_file(self, path, hidden=False):
313 def execute_file(self, path, hidden=False):
297 """ Attempts to execute file with 'path'. If 'hidden', no output is
314 """ Attempts to execute file with 'path'. If 'hidden', no output is
298 shown.
315 shown.
299 """
316 """
300 self.execute('execfile("%s")' % path, hidden=hidden)
317 self.execute('execfile("%s")' % path, hidden=hidden)
301
318
302 def interrupt_kernel(self):
319 def interrupt_kernel(self):
303 """ Attempts to interrupt the running kernel.
320 """ Attempts to interrupt the running kernel.
304 """
321 """
305 if self.custom_interrupt:
322 if self.custom_interrupt:
306 self.custom_interrupt_requested.emit()
323 self.custom_interrupt_requested.emit()
307 elif self.kernel_manager.has_kernel:
324 elif self.kernel_manager.has_kernel:
308 self.kernel_manager.signal_kernel(signal.SIGINT)
325 self.kernel_manager.signal_kernel(signal.SIGINT)
309 else:
326 else:
310 self._append_plain_text('Kernel process is either remote or '
327 self._append_plain_text('Kernel process is either remote or '
311 'unspecified. Cannot interrupt.\n')
328 'unspecified. Cannot interrupt.\n')
312
329
313 def restart_kernel(self, message):
330 def restart_kernel(self, message):
314 """ Attempts to restart the running kernel.
331 """ Attempts to restart the running kernel.
315 """
332 """
316 # We want to make sure that if this dialog is already happening, that
333 # We want to make sure that if this dialog is already happening, that
317 # other signals don't trigger it again. This can happen when the
334 # other signals don't trigger it again. This can happen when the
318 # kernel_died heartbeat signal is emitted and the user is slow to
335 # kernel_died heartbeat signal is emitted and the user is slow to
319 # respond to the dialog.
336 # respond to the dialog.
320 if not self._possible_kernel_restart:
337 if not self._possible_kernel_restart:
321 if self.custom_restart:
338 if self.custom_restart:
322 self.custom_restart_requested.emit()
339 self.custom_restart_requested.emit()
323 elif self.kernel_manager.has_kernel:
340 elif self.kernel_manager.has_kernel:
324 # Setting this to True will prevent this logic from happening
341 # Setting this to True will prevent this logic from happening
325 # again until the current pass is completed.
342 # again until the current pass is completed.
326 self._possible_kernel_restart = True
343 self._possible_kernel_restart = True
327 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
344 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
328 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
345 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
329 message, buttons)
346 message, buttons)
330 if result == QtGui.QMessageBox.Yes:
347 if result == QtGui.QMessageBox.Yes:
331 try:
348 try:
332 self.kernel_manager.restart_kernel()
349 self.kernel_manager.restart_kernel()
333 except RuntimeError:
350 except RuntimeError:
334 message = 'Kernel started externally. Cannot restart.\n'
351 message = 'Kernel started externally. Cannot restart.\n'
335 self._append_plain_text(message)
352 self._append_plain_text(message)
336 else:
353 else:
337 self._stopped_channels()
354 self._stopped_channels()
338 self._append_plain_text('Kernel restarting...\n')
355 self._append_plain_text('Kernel restarting...\n')
339 self._show_interpreter_prompt()
356 self._show_interpreter_prompt()
340 # This might need to be moved to another location?
357 # This might need to be moved to another location?
341 self._possible_kernel_restart = False
358 self._possible_kernel_restart = False
342 else:
359 else:
343 self._append_plain_text('Kernel process is either remote or '
360 self._append_plain_text('Kernel process is either remote or '
344 'unspecified. Cannot restart.\n')
361 'unspecified. Cannot restart.\n')
345
362
346 #---------------------------------------------------------------------------
363 #---------------------------------------------------------------------------
347 # 'FrontendWidget' protected interface
364 # 'FrontendWidget' protected interface
348 #---------------------------------------------------------------------------
365 #---------------------------------------------------------------------------
349
366
350 def _call_tip(self):
367 def _call_tip(self):
351 """ Shows a call tip, if appropriate, at the current cursor location.
368 """ Shows a call tip, if appropriate, at the current cursor location.
352 """
369 """
353 # Decide if it makes sense to show a call tip
370 # Decide if it makes sense to show a call tip
354 cursor = self._get_cursor()
371 cursor = self._get_cursor()
355 cursor.movePosition(QtGui.QTextCursor.Left)
372 cursor.movePosition(QtGui.QTextCursor.Left)
356 if cursor.document().characterAt(cursor.position()).toAscii() != '(':
373 if cursor.document().characterAt(cursor.position()).toAscii() != '(':
357 return False
374 return False
358 context = self._get_context(cursor)
375 context = self._get_context(cursor)
359 if not context:
376 if not context:
360 return False
377 return False
361
378
362 # Send the metadata request to the kernel
379 # Send the metadata request to the kernel
363 name = '.'.join(context)
380 name = '.'.join(context)
364 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
381 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
365 self._call_tip_pos = self._get_cursor().position()
382 self._call_tip_pos = self._get_cursor().position()
366 return True
383 return True
367
384
368 def _complete(self):
385 def _complete(self):
369 """ Performs completion at the current cursor location.
386 """ Performs completion at the current cursor location.
370 """
387 """
371 context = self._get_context()
388 context = self._get_context()
372 if context:
389 if context:
373 # Send the completion request to the kernel
390 # Send the completion request to the kernel
374 self._complete_id = self.kernel_manager.xreq_channel.complete(
391 self._complete_id = self.kernel_manager.xreq_channel.complete(
375 '.'.join(context), # text
392 '.'.join(context), # text
376 self._get_input_buffer_cursor_line(), # line
393 self._get_input_buffer_cursor_line(), # line
377 self._get_input_buffer_cursor_column(), # cursor_pos
394 self._get_input_buffer_cursor_column(), # cursor_pos
378 self.input_buffer) # block
395 self.input_buffer) # block
379 self._complete_pos = self._get_cursor().position()
396 self._complete_pos = self._get_cursor().position()
380
397
381 def _get_banner(self):
398 def _get_banner(self):
382 """ Gets a banner to display at the beginning of a session.
399 """ Gets a banner to display at the beginning of a session.
383 """
400 """
384 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
401 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
385 '"license" for more information.'
402 '"license" for more information.'
386 return banner % (sys.version, sys.platform)
403 return banner % (sys.version, sys.platform)
387
404
388 def _get_context(self, cursor=None):
405 def _get_context(self, cursor=None):
389 """ Gets the context for the specified cursor (or the current cursor
406 """ Gets the context for the specified cursor (or the current cursor
390 if none is specified).
407 if none is specified).
391 """
408 """
392 if cursor is None:
409 if cursor is None:
393 cursor = self._get_cursor()
410 cursor = self._get_cursor()
394 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
411 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
395 QtGui.QTextCursor.KeepAnchor)
412 QtGui.QTextCursor.KeepAnchor)
396 text = str(cursor.selection().toPlainText())
413 text = str(cursor.selection().toPlainText())
397 return self._completion_lexer.get_context(text)
414 return self._completion_lexer.get_context(text)
398
415
399 def _process_execute_abort(self, msg):
416 def _process_execute_abort(self, msg):
400 """ Process a reply for an aborted execution request.
417 """ Process a reply for an aborted execution request.
401 """
418 """
402 self._append_plain_text("ERROR: execution aborted\n")
419 self._append_plain_text("ERROR: execution aborted\n")
403
420
404 def _process_execute_error(self, msg):
421 def _process_execute_error(self, msg):
405 """ Process a reply for an execution request that resulted in an error.
422 """ Process a reply for an execution request that resulted in an error.
406 """
423 """
407 content = msg['content']
424 content = msg['content']
408 traceback = ''.join(content['traceback'])
425 traceback = ''.join(content['traceback'])
409 self._append_plain_text(traceback)
426 self._append_plain_text(traceback)
410
427
411 def _process_execute_ok(self, msg):
428 def _process_execute_ok(self, msg):
412 """ Process a reply for a successful execution equest.
429 """ Process a reply for a successful execution equest.
413 """
430 """
414 payload = msg['content']['payload']
431 payload = msg['content']['payload']
415 for item in payload:
432 for item in payload:
416 if not self._process_execute_payload(item):
433 if not self._process_execute_payload(item):
417 warning = 'Received unknown payload of type %s\n'
434 warning = 'Received unknown payload of type %s\n'
418 self._append_plain_text(warning % repr(item['source']))
435 self._append_plain_text(warning % repr(item['source']))
419
436
420 def _process_execute_payload(self, item):
437 def _process_execute_payload(self, item):
421 """ Process a single payload item from the list of payload items in an
438 """ Process a single payload item from the list of payload items in an
422 execution reply. Returns whether the payload was handled.
439 execution reply. Returns whether the payload was handled.
423 """
440 """
424 # The basic FrontendWidget doesn't handle payloads, as they are a
441 # The basic FrontendWidget doesn't handle payloads, as they are a
425 # mechanism for going beyond the standard Python interpreter model.
442 # mechanism for going beyond the standard Python interpreter model.
426 return False
443 return False
427
444
428 def _show_interpreter_prompt(self):
445 def _show_interpreter_prompt(self):
429 """ Shows a prompt for the interpreter.
446 """ Shows a prompt for the interpreter.
430 """
447 """
431 self._show_prompt('>>> ')
448 self._show_prompt('>>> ')
432
449
433 def _show_interpreter_prompt_for_reply(self, msg):
450 def _show_interpreter_prompt_for_reply(self, msg):
434 """ Shows a prompt for the interpreter given an 'execute_reply' message.
451 """ Shows a prompt for the interpreter given an 'execute_reply' message.
435 """
452 """
436 self._show_interpreter_prompt()
453 self._show_interpreter_prompt()
437
454
438 #------ Signal handlers ----------------------------------------------------
455 #------ Signal handlers ----------------------------------------------------
439
456
440 def _document_contents_change(self, position, removed, added):
457 def _document_contents_change(self, position, removed, added):
441 """ Called whenever the document's content changes. Display a call tip
458 """ Called whenever the document's content changes. Display a call tip
442 if appropriate.
459 if appropriate.
443 """
460 """
444 # Calculate where the cursor should be *after* the change:
461 # Calculate where the cursor should be *after* the change:
445 position += added
462 position += added
446
463
447 document = self._control.document()
464 document = self._control.document()
448 if position == self._get_cursor().position():
465 if position == self._get_cursor().position():
449 self._call_tip()
466 self._call_tip()
@@ -1,402 +1,408 b''
1 """ A FrontendWidget that emulates the interface of the console IPython and
1 """ A FrontendWidget that emulates the interface of the console IPython and
2 supports the additional functionality provided by the IPython kernel.
2 supports the additional functionality provided by the IPython kernel.
3
3
4 TODO: Add support for retrieving the system default editor. Requires code
4 TODO: Add support for retrieving the system default editor. Requires code
5 paths for Windows (use the registry), Mac OS (use LaunchServices), and
5 paths for Windows (use the registry), Mac OS (use LaunchServices), and
6 Linux (use the xdg system).
6 Linux (use the xdg system).
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Imports
10 # Imports
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 # Standard library imports
13 # Standard library imports
14 from collections import namedtuple
14 from collections import namedtuple
15 import re
15 import re
16 from subprocess import Popen
16 from subprocess import Popen
17
17
18 # System library imports
18 # System library imports
19 from PyQt4 import QtCore, QtGui
19 from PyQt4 import QtCore, QtGui
20
20
21 # Local imports
21 # Local imports
22 from IPython.core.inputsplitter import IPythonInputSplitter
22 from IPython.core.inputsplitter import IPythonInputSplitter
23 from IPython.core.usage import default_banner
23 from IPython.core.usage import default_banner
24 from IPython.utils import io
24 from IPython.utils.traitlets import Bool, Str
25 from IPython.utils.traitlets import Bool, Str
25 from frontend_widget import FrontendWidget
26 from frontend_widget import FrontendWidget
26
27
27 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
28 # Constants
29 # Constants
29 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
30
31
31 # The default light style sheet: black text on a white background.
32 # The default light style sheet: black text on a white background.
32 default_light_style_sheet = '''
33 default_light_style_sheet = '''
33 .error { color: red; }
34 .error { color: red; }
34 .in-prompt { color: navy; }
35 .in-prompt { color: navy; }
35 .in-prompt-number { font-weight: bold; }
36 .in-prompt-number { font-weight: bold; }
36 .out-prompt { color: darkred; }
37 .out-prompt { color: darkred; }
37 .out-prompt-number { font-weight: bold; }
38 .out-prompt-number { font-weight: bold; }
38 '''
39 '''
39 default_light_syntax_style = 'default'
40 default_light_syntax_style = 'default'
40
41
41 # The default dark style sheet: white text on a black background.
42 # The default dark style sheet: white text on a black background.
42 default_dark_style_sheet = '''
43 default_dark_style_sheet = '''
43 QPlainTextEdit, QTextEdit { background-color: black; color: white }
44 QPlainTextEdit, QTextEdit { background-color: black; color: white }
44 QFrame { border: 1px solid grey; }
45 QFrame { border: 1px solid grey; }
45 .error { color: red; }
46 .error { color: red; }
46 .in-prompt { color: lime; }
47 .in-prompt { color: lime; }
47 .in-prompt-number { color: lime; font-weight: bold; }
48 .in-prompt-number { color: lime; font-weight: bold; }
48 .out-prompt { color: red; }
49 .out-prompt { color: red; }
49 .out-prompt-number { color: red; font-weight: bold; }
50 .out-prompt-number { color: red; font-weight: bold; }
50 '''
51 '''
51 default_dark_syntax_style = 'monokai'
52 default_dark_syntax_style = 'monokai'
52
53
53 # Default prompts.
54 # Default strings to build and display input and output prompts (and separators
55 # in between)
54 default_in_prompt = 'In [<span class="in-prompt-number">%i</span>]: '
56 default_in_prompt = 'In [<span class="in-prompt-number">%i</span>]: '
55 default_out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
57 default_out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
58 default_input_sep = '\n'
59 default_output_sep = ''
60 default_output_sep2 = ''
56
61
57 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
58 # IPythonWidget class
63 # IPythonWidget class
59 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
60
65
61 class IPythonWidget(FrontendWidget):
66 class IPythonWidget(FrontendWidget):
62 """ A FrontendWidget for an IPython kernel.
67 """ A FrontendWidget for an IPython kernel.
63 """
68 """
64
69
65 # If set, the 'custom_edit_requested(str, int)' signal will be emitted when
70 # If set, the 'custom_edit_requested(str, int)' signal will be emitted when
66 # an editor is needed for a file. This overrides 'editor' and 'editor_line'
71 # an editor is needed for a file. This overrides 'editor' and 'editor_line'
67 # settings.
72 # settings.
68 custom_edit = Bool(False)
73 custom_edit = Bool(False)
69 custom_edit_requested = QtCore.pyqtSignal(object, object)
74 custom_edit_requested = QtCore.pyqtSignal(object, object)
70
75
71 # A command for invoking a system text editor. If the string contains a
76 # A command for invoking a system text editor. If the string contains a
72 # {filename} format specifier, it will be used. Otherwise, the filename will
77 # {filename} format specifier, it will be used. Otherwise, the filename will
73 # be appended to the end the command.
78 # be appended to the end the command.
74 editor = Str('default', config=True)
79 editor = Str('default', config=True)
75
80
76 # The editor command to use when a specific line number is requested. The
81 # The editor command to use when a specific line number is requested. The
77 # string should contain two format specifiers: {line} and {filename}. If
82 # string should contain two format specifiers: {line} and {filename}. If
78 # this parameter is not specified, the line number option to the %edit magic
83 # this parameter is not specified, the line number option to the %edit magic
79 # will be ignored.
84 # will be ignored.
80 editor_line = Str(config=True)
85 editor_line = Str(config=True)
81
86
82 # A CSS stylesheet. The stylesheet can contain classes for:
87 # A CSS stylesheet. The stylesheet can contain classes for:
83 # 1. Qt: QPlainTextEdit, QFrame, QWidget, etc
88 # 1. Qt: QPlainTextEdit, QFrame, QWidget, etc
84 # 2. Pygments: .c, .k, .o, etc (see PygmentsHighlighter)
89 # 2. Pygments: .c, .k, .o, etc (see PygmentsHighlighter)
85 # 3. IPython: .error, .in-prompt, .out-prompt, etc
90 # 3. IPython: .error, .in-prompt, .out-prompt, etc
86 style_sheet = Str(config=True)
91 style_sheet = Str(config=True)
87
92
88 # If not empty, use this Pygments style for syntax highlighting. Otherwise,
93 # If not empty, use this Pygments style for syntax highlighting. Otherwise,
89 # the style sheet is queried for Pygments style information.
94 # the style sheet is queried for Pygments style information.
90 syntax_style = Str(config=True)
95 syntax_style = Str(config=True)
91
96
92 # Prompts.
97 # Prompts.
93 in_prompt = Str(default_in_prompt, config=True)
98 in_prompt = Str(default_in_prompt, config=True)
94 out_prompt = Str(default_out_prompt, config=True)
99 out_prompt = Str(default_out_prompt, config=True)
100 input_sep = Str(default_input_sep, config=True)
101 output_sep = Str(default_output_sep, config=True)
102 output_sep2 = Str(default_output_sep2, config=True)
95
103
96 # FrontendWidget protected class variables.
104 # FrontendWidget protected class variables.
97 _input_splitter_class = IPythonInputSplitter
105 _input_splitter_class = IPythonInputSplitter
98
106
99 # IPythonWidget protected class variables.
107 # IPythonWidget protected class variables.
100 _PromptBlock = namedtuple('_PromptBlock', ['block', 'length', 'number'])
108 _PromptBlock = namedtuple('_PromptBlock', ['block', 'length', 'number'])
101 _payload_source_edit = 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic'
109 _payload_source_edit = 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic'
102 _payload_source_page = 'IPython.zmq.page.page'
110 _payload_source_page = 'IPython.zmq.page.page'
103
111
104 #---------------------------------------------------------------------------
112 #---------------------------------------------------------------------------
105 # 'object' interface
113 # 'object' interface
106 #---------------------------------------------------------------------------
114 #---------------------------------------------------------------------------
107
115
108 def __init__(self, *args, **kw):
116 def __init__(self, *args, **kw):
109 super(IPythonWidget, self).__init__(*args, **kw)
117 super(IPythonWidget, self).__init__(*args, **kw)
110
118
111 # IPythonWidget protected variables.
119 # IPythonWidget protected variables.
112 self._previous_prompt_obj = None
120 self._previous_prompt_obj = None
113
121
114 # Initialize widget styling.
122 # Initialize widget styling.
115 if self.style_sheet:
123 if self.style_sheet:
116 self._style_sheet_changed()
124 self._style_sheet_changed()
117 self._syntax_style_changed()
125 self._syntax_style_changed()
118 else:
126 else:
119 self.set_default_style()
127 self.set_default_style()
120
128
121 #---------------------------------------------------------------------------
129 #---------------------------------------------------------------------------
122 # 'BaseFrontendMixin' abstract interface
130 # 'BaseFrontendMixin' abstract interface
123 #---------------------------------------------------------------------------
131 #---------------------------------------------------------------------------
124
132
125 def _handle_complete_reply(self, rep):
133 def _handle_complete_reply(self, rep):
126 """ Reimplemented to support IPython's improved completion machinery.
134 """ Reimplemented to support IPython's improved completion machinery.
127 """
135 """
128 cursor = self._get_cursor()
136 cursor = self._get_cursor()
129 if rep['parent_header']['msg_id'] == self._complete_id and \
137 if rep['parent_header']['msg_id'] == self._complete_id and \
130 cursor.position() == self._complete_pos:
138 cursor.position() == self._complete_pos:
131 matches = rep['content']['matches']
139 matches = rep['content']['matches']
132 text = rep['content']['matched_text']
140 text = rep['content']['matched_text']
133
141
134 # Clean up matches with '.'s and path separators.
142 # Clean up matches with '.'s and path separators.
135 parts = re.split(r'[./\\]', text)
143 parts = re.split(r'[./\\]', text)
136 sep_count = len(parts) - 1
144 sep_count = len(parts) - 1
137 if sep_count:
145 if sep_count:
138 chop_length = sum(map(len, parts[:sep_count])) + sep_count
146 chop_length = sum(map(len, parts[:sep_count])) + sep_count
139 matches = [ match[chop_length:] for match in matches ]
147 matches = [ match[chop_length:] for match in matches ]
140 text = text[chop_length:]
148 text = text[chop_length:]
141
149
142 # Move the cursor to the start of the match and complete.
150 # Move the cursor to the start of the match and complete.
143 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
151 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
144 self._complete_with_items(cursor, matches)
152 self._complete_with_items(cursor, matches)
145
153
146 def _handle_history_reply(self, msg):
154 def _handle_history_reply(self, msg):
147 """ Implemented to handle history replies, which are only supported by
155 """ Implemented to handle history replies, which are only supported by
148 the IPython kernel.
156 the IPython kernel.
149 """
157 """
150 history_dict = msg['content']['history']
158 history_dict = msg['content']['history']
151 items = [ history_dict[key] for key in sorted(history_dict.keys()) ]
159 items = [ history_dict[key] for key in sorted(history_dict.keys()) ]
152 self._set_history(items)
160 self._set_history(items)
153
161
154 def _handle_prompt_reply(self, msg):
162 def _handle_prompt_reply(self, msg):
155 """ Implemented to handle prompt number replies, which are only
163 """ Implemented to handle prompt number replies, which are only
156 supported by the IPython kernel.
164 supported by the IPython kernel.
157 """
165 """
158 content = msg['content']
166 self._show_interpreter_prompt(msg['content']['execution_count'])
159 self._show_interpreter_prompt(content['prompt_number'],
160 content['input_sep'])
161
167
162 def _handle_pyout(self, msg):
168 def _handle_pyout(self, msg):
163 """ Reimplemented for IPython-style "display hook".
169 """ Reimplemented for IPython-style "display hook".
164 """
170 """
165 if not self._hidden and self._is_from_this_session(msg):
171 if not self._hidden and self._is_from_this_session(msg):
166 content = msg['content']
172 content = msg['content']
167 prompt_number = content['prompt_number']
173 prompt_number = content['execution_count']
168 self._append_plain_text(content['output_sep'])
174 self._append_plain_text(self.output_sep)
169 self._append_html(self._make_out_prompt(prompt_number))
175 self._append_html(self._make_out_prompt(prompt_number))
170 self._append_plain_text(content['data'] + '\n' +
176 self._append_plain_text(content['data']+self.output_sep2)
171 content['output_sep2'])
172
177
173 def _started_channels(self):
178 def _started_channels(self):
174 """ Reimplemented to make a history request.
179 """ Reimplemented to make a history request.
175 """
180 """
176 super(IPythonWidget, self)._started_channels()
181 super(IPythonWidget, self)._started_channels()
177 # FIXME: Disabled until history requests are properly implemented.
182 # FIXME: Disabled until history requests are properly implemented.
178 #self.kernel_manager.xreq_channel.history(raw=True, output=False)
183 #self.kernel_manager.xreq_channel.history(raw=True, output=False)
179
184
180 #---------------------------------------------------------------------------
185 #---------------------------------------------------------------------------
181 # 'FrontendWidget' interface
186 # 'FrontendWidget' interface
182 #---------------------------------------------------------------------------
187 #---------------------------------------------------------------------------
183
188
184 def execute_file(self, path, hidden=False):
189 def execute_file(self, path, hidden=False):
185 """ Reimplemented to use the 'run' magic.
190 """ Reimplemented to use the 'run' magic.
186 """
191 """
187 self.execute('%%run %s' % path, hidden=hidden)
192 self.execute('%%run %s' % path, hidden=hidden)
188
193
189 #---------------------------------------------------------------------------
194 #---------------------------------------------------------------------------
190 # 'FrontendWidget' protected interface
195 # 'FrontendWidget' protected interface
191 #---------------------------------------------------------------------------
196 #---------------------------------------------------------------------------
192
197
193 def _complete(self):
198 def _complete(self):
194 """ Reimplemented to support IPython's improved completion machinery.
199 """ Reimplemented to support IPython's improved completion machinery.
195 """
200 """
196 # We let the kernel split the input line, so we *always* send an empty
201 # We let the kernel split the input line, so we *always* send an empty
197 # text field. Readline-based frontends do get a real text field which
202 # text field. Readline-based frontends do get a real text field which
198 # they can use.
203 # they can use.
199 text = ''
204 text = ''
200
205
201 # Send the completion request to the kernel
206 # Send the completion request to the kernel
202 self._complete_id = self.kernel_manager.xreq_channel.complete(
207 self._complete_id = self.kernel_manager.xreq_channel.complete(
203 text, # text
208 text, # text
204 self._get_input_buffer_cursor_line(), # line
209 self._get_input_buffer_cursor_line(), # line
205 self._get_input_buffer_cursor_column(), # cursor_pos
210 self._get_input_buffer_cursor_column(), # cursor_pos
206 self.input_buffer) # block
211 self.input_buffer) # block
207 self._complete_pos = self._get_cursor().position()
212 self._complete_pos = self._get_cursor().position()
208
213
209 def _get_banner(self):
214 def _get_banner(self):
210 """ Reimplemented to return IPython's default banner.
215 """ Reimplemented to return IPython's default banner.
211 """
216 """
212 return default_banner + '\n'
217 return default_banner + '\n'
213
218
214 def _process_execute_error(self, msg):
219 def _process_execute_error(self, msg):
215 """ Reimplemented for IPython-style traceback formatting.
220 """ Reimplemented for IPython-style traceback formatting.
216 """
221 """
217 content = msg['content']
222 content = msg['content']
218 traceback = '\n'.join(content['traceback']) + '\n'
223 traceback = '\n'.join(content['traceback']) + '\n'
219 if False:
224 if False:
220 # FIXME: For now, tracebacks come as plain text, so we can't use
225 # FIXME: For now, tracebacks come as plain text, so we can't use
221 # the html renderer yet. Once we refactor ultratb to produce
226 # the html renderer yet. Once we refactor ultratb to produce
222 # properly styled tracebacks, this branch should be the default
227 # properly styled tracebacks, this branch should be the default
223 traceback = traceback.replace(' ', '&nbsp;')
228 traceback = traceback.replace(' ', '&nbsp;')
224 traceback = traceback.replace('\n', '<br/>')
229 traceback = traceback.replace('\n', '<br/>')
225
230
226 ename = content['ename']
231 ename = content['ename']
227 ename_styled = '<span class="error">%s</span>' % ename
232 ename_styled = '<span class="error">%s</span>' % ename
228 traceback = traceback.replace(ename, ename_styled)
233 traceback = traceback.replace(ename, ename_styled)
229
234
230 self._append_html(traceback)
235 self._append_html(traceback)
231 else:
236 else:
232 # This is the fallback for now, using plain text with ansi escapes
237 # This is the fallback for now, using plain text with ansi escapes
233 self._append_plain_text(traceback)
238 self._append_plain_text(traceback)
234
239
235 def _process_execute_payload(self, item):
240 def _process_execute_payload(self, item):
236 """ Reimplemented to handle %edit and paging payloads.
241 """ Reimplemented to handle %edit and paging payloads.
237 """
242 """
238 if item['source'] == self._payload_source_edit:
243 if item['source'] == self._payload_source_edit:
239 self._edit(item['filename'], item['line_number'])
244 self._edit(item['filename'], item['line_number'])
240 return True
245 return True
241 elif item['source'] == self._payload_source_page:
246 elif item['source'] == self._payload_source_page:
242 self._page(item['data'])
247 self._page(item['data'])
243 return True
248 return True
244 else:
249 else:
245 return False
250 return False
246
251
247 def _show_interpreter_prompt(self, number=None, input_sep='\n'):
252 def _show_interpreter_prompt(self, number=None):
248 """ Reimplemented for IPython-style prompts.
253 """ Reimplemented for IPython-style prompts.
249 """
254 """
250 # If a number was not specified, make a prompt number request.
255 # If a number was not specified, make a prompt number request.
251 if number is None:
256 if number is None:
252 self.kernel_manager.xreq_channel.prompt()
257 # FIXME - fperez: this should be a silent code request
253 return
258 number = 1
259 ##self.kernel_manager.xreq_channel.prompt()
260 ##return
254
261
255 # Show a new prompt and save information about it so that it can be
262 # Show a new prompt and save information about it so that it can be
256 # updated later if the prompt number turns out to be wrong.
263 # updated later if the prompt number turns out to be wrong.
257 self._prompt_sep = input_sep
264 self._prompt_sep = self.input_sep
258 self._show_prompt(self._make_in_prompt(number), html=True)
265 self._show_prompt(self._make_in_prompt(number), html=True)
259 block = self._control.document().lastBlock()
266 block = self._control.document().lastBlock()
260 length = len(self._prompt)
267 length = len(self._prompt)
261 self._previous_prompt_obj = self._PromptBlock(block, length, number)
268 self._previous_prompt_obj = self._PromptBlock(block, length, number)
262
269
263 # Update continuation prompt to reflect (possibly) new prompt length.
270 # Update continuation prompt to reflect (possibly) new prompt length.
264 self._set_continuation_prompt(
271 self._set_continuation_prompt(
265 self._make_continuation_prompt(self._prompt), html=True)
272 self._make_continuation_prompt(self._prompt), html=True)
266
273
267 def _show_interpreter_prompt_for_reply(self, msg):
274 def _show_interpreter_prompt_for_reply(self, msg):
268 """ Reimplemented for IPython-style prompts.
275 """ Reimplemented for IPython-style prompts.
269 """
276 """
270 # Update the old prompt number if necessary.
277 # Update the old prompt number if necessary.
271 content = msg['content']
278 content = msg['content']
272 previous_prompt_number = content['prompt_number']
279 ##io.rprint('_show_interpreter_prompt_for_reply\n', content) # dbg
280 previous_prompt_number = content['execution_count']
273 if self._previous_prompt_obj and \
281 if self._previous_prompt_obj and \
274 self._previous_prompt_obj.number != previous_prompt_number:
282 self._previous_prompt_obj.number != previous_prompt_number:
275 block = self._previous_prompt_obj.block
283 block = self._previous_prompt_obj.block
276
284
277 # Make sure the prompt block has not been erased.
285 # Make sure the prompt block has not been erased.
278 if block.isValid() and not block.text().isEmpty():
286 if block.isValid() and not block.text().isEmpty():
279
287
280 # Remove the old prompt and insert a new prompt.
288 # Remove the old prompt and insert a new prompt.
281 cursor = QtGui.QTextCursor(block)
289 cursor = QtGui.QTextCursor(block)
282 cursor.movePosition(QtGui.QTextCursor.Right,
290 cursor.movePosition(QtGui.QTextCursor.Right,
283 QtGui.QTextCursor.KeepAnchor,
291 QtGui.QTextCursor.KeepAnchor,
284 self._previous_prompt_obj.length)
292 self._previous_prompt_obj.length)
285 prompt = self._make_in_prompt(previous_prompt_number)
293 prompt = self._make_in_prompt(previous_prompt_number)
286 self._prompt = self._insert_html_fetching_plain_text(
294 self._prompt = self._insert_html_fetching_plain_text(
287 cursor, prompt)
295 cursor, prompt)
288
296
289 # When the HTML is inserted, Qt blows away the syntax
297 # When the HTML is inserted, Qt blows away the syntax
290 # highlighting for the line, so we need to rehighlight it.
298 # highlighting for the line, so we need to rehighlight it.
291 self._highlighter.rehighlightBlock(cursor.block())
299 self._highlighter.rehighlightBlock(cursor.block())
292
300
293 self._previous_prompt_obj = None
301 self._previous_prompt_obj = None
294
302
295 # Show a new prompt with the kernel's estimated prompt number.
303 # Show a new prompt with the kernel's estimated prompt number.
296 next_prompt = content['next_prompt']
304 self._show_interpreter_prompt(previous_prompt_number+1)
297 self._show_interpreter_prompt(next_prompt['prompt_number'],
298 next_prompt['input_sep'])
299
305
300 #---------------------------------------------------------------------------
306 #---------------------------------------------------------------------------
301 # 'IPythonWidget' interface
307 # 'IPythonWidget' interface
302 #---------------------------------------------------------------------------
308 #---------------------------------------------------------------------------
303
309
304 def set_default_style(self, lightbg=True):
310 def set_default_style(self, lightbg=True):
305 """ Sets the widget style to the class defaults.
311 """ Sets the widget style to the class defaults.
306
312
307 Parameters:
313 Parameters:
308 -----------
314 -----------
309 lightbg : bool, optional (default True)
315 lightbg : bool, optional (default True)
310 Whether to use the default IPython light background or dark
316 Whether to use the default IPython light background or dark
311 background style.
317 background style.
312 """
318 """
313 if lightbg:
319 if lightbg:
314 self.style_sheet = default_light_style_sheet
320 self.style_sheet = default_light_style_sheet
315 self.syntax_style = default_light_syntax_style
321 self.syntax_style = default_light_syntax_style
316 else:
322 else:
317 self.style_sheet = default_dark_style_sheet
323 self.style_sheet = default_dark_style_sheet
318 self.syntax_style = default_dark_syntax_style
324 self.syntax_style = default_dark_syntax_style
319
325
320 #---------------------------------------------------------------------------
326 #---------------------------------------------------------------------------
321 # 'IPythonWidget' protected interface
327 # 'IPythonWidget' protected interface
322 #---------------------------------------------------------------------------
328 #---------------------------------------------------------------------------
323
329
324 def _edit(self, filename, line=None):
330 def _edit(self, filename, line=None):
325 """ Opens a Python script for editing.
331 """ Opens a Python script for editing.
326
332
327 Parameters:
333 Parameters:
328 -----------
334 -----------
329 filename : str
335 filename : str
330 A path to a local system file.
336 A path to a local system file.
331
337
332 line : int, optional
338 line : int, optional
333 A line of interest in the file.
339 A line of interest in the file.
334 """
340 """
335 if self.custom_edit:
341 if self.custom_edit:
336 self.custom_edit_requested.emit(filename, line)
342 self.custom_edit_requested.emit(filename, line)
337 elif self.editor == 'default':
343 elif self.editor == 'default':
338 self._append_plain_text('No default editor available.\n')
344 self._append_plain_text('No default editor available.\n')
339 else:
345 else:
340 try:
346 try:
341 filename = '"%s"' % filename
347 filename = '"%s"' % filename
342 if line and self.editor_line:
348 if line and self.editor_line:
343 command = self.editor_line.format(filename=filename,
349 command = self.editor_line.format(filename=filename,
344 line=line)
350 line=line)
345 else:
351 else:
346 try:
352 try:
347 command = self.editor.format()
353 command = self.editor.format()
348 except KeyError:
354 except KeyError:
349 command = self.editor.format(filename=filename)
355 command = self.editor.format(filename=filename)
350 else:
356 else:
351 command += ' ' + filename
357 command += ' ' + filename
352 except KeyError:
358 except KeyError:
353 self._append_plain_text('Invalid editor command.\n')
359 self._append_plain_text('Invalid editor command.\n')
354 else:
360 else:
355 try:
361 try:
356 Popen(command, shell=True)
362 Popen(command, shell=True)
357 except OSError:
363 except OSError:
358 msg = 'Opening editor with command "%s" failed.\n'
364 msg = 'Opening editor with command "%s" failed.\n'
359 self._append_plain_text(msg % command)
365 self._append_plain_text(msg % command)
360
366
361 def _make_in_prompt(self, number):
367 def _make_in_prompt(self, number):
362 """ Given a prompt number, returns an HTML In prompt.
368 """ Given a prompt number, returns an HTML In prompt.
363 """
369 """
364 body = self.in_prompt % number
370 body = self.in_prompt % number
365 return '<span class="in-prompt">%s</span>' % body
371 return '<span class="in-prompt">%s</span>' % body
366
372
367 def _make_continuation_prompt(self, prompt):
373 def _make_continuation_prompt(self, prompt):
368 """ Given a plain text version of an In prompt, returns an HTML
374 """ Given a plain text version of an In prompt, returns an HTML
369 continuation prompt.
375 continuation prompt.
370 """
376 """
371 end_chars = '...: '
377 end_chars = '...: '
372 space_count = len(prompt.lstrip('\n')) - len(end_chars)
378 space_count = len(prompt.lstrip('\n')) - len(end_chars)
373 body = '&nbsp;' * space_count + end_chars
379 body = '&nbsp;' * space_count + end_chars
374 return '<span class="in-prompt">%s</span>' % body
380 return '<span class="in-prompt">%s</span>' % body
375
381
376 def _make_out_prompt(self, number):
382 def _make_out_prompt(self, number):
377 """ Given a prompt number, returns an HTML Out prompt.
383 """ Given a prompt number, returns an HTML Out prompt.
378 """
384 """
379 body = self.out_prompt % number
385 body = self.out_prompt % number
380 return '<span class="out-prompt">%s</span>' % body
386 return '<span class="out-prompt">%s</span>' % body
381
387
382 #------ Trait change handlers ---------------------------------------------
388 #------ Trait change handlers ---------------------------------------------
383
389
384 def _style_sheet_changed(self):
390 def _style_sheet_changed(self):
385 """ Set the style sheets of the underlying widgets.
391 """ Set the style sheets of the underlying widgets.
386 """
392 """
387 self.setStyleSheet(self.style_sheet)
393 self.setStyleSheet(self.style_sheet)
388 self._control.document().setDefaultStyleSheet(self.style_sheet)
394 self._control.document().setDefaultStyleSheet(self.style_sheet)
389 if self._page_control:
395 if self._page_control:
390 self._page_control.document().setDefaultStyleSheet(self.style_sheet)
396 self._page_control.document().setDefaultStyleSheet(self.style_sheet)
391
397
392 bg_color = self._control.palette().background().color()
398 bg_color = self._control.palette().background().color()
393 self._ansi_processor.set_background_color(bg_color)
399 self._ansi_processor.set_background_color(bg_color)
394
400
395 def _syntax_style_changed(self):
401 def _syntax_style_changed(self):
396 """ Set the style for the syntax highlighter.
402 """ Set the style for the syntax highlighter.
397 """
403 """
398 if self.syntax_style:
404 if self.syntax_style:
399 self._highlighter.set_style(self.syntax_style)
405 self._highlighter.set_style(self.syntax_style)
400 else:
406 else:
401 self._highlighter.set_style_sheet(self.style_sheet)
407 self._highlighter.set_style_sheet(self.style_sheet)
402
408
@@ -1,120 +1,121 b''
1 """Common utilities for the various process_* implementations.
1 """Common utilities for the various process_* implementations.
2
2
3 This file is only meant to be imported by the platform-specific implementations
3 This file is only meant to be imported by the platform-specific implementations
4 of subprocess utilities, and it contains tools that are common to all of them.
4 of subprocess utilities, and it contains tools that are common to all of them.
5 """
5 """
6
6
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2010 The IPython Development Team
8 # Copyright (C) 2010 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 import subprocess
17 import subprocess
18 import sys
18 import sys
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Function definitions
21 # Function definitions
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 def read_no_interrupt(p):
24 def read_no_interrupt(p):
25 """Read from a pipe ignoring EINTR errors.
25 """Read from a pipe ignoring EINTR errors.
26
26
27 This is necessary because when reading from pipes with GUI event loops
27 This is necessary because when reading from pipes with GUI event loops
28 running in the background, often interrupts are raised that stop the
28 running in the background, often interrupts are raised that stop the
29 command from completing."""
29 command from completing."""
30 import errno
30 import errno
31
31
32 try:
32 try:
33 return p.read()
33 return p.read()
34 except IOError, err:
34 except IOError, err:
35 if err.errno != errno.EINTR:
35 if err.errno != errno.EINTR:
36 raise
36 raise
37
37
38
38
39 def process_handler(cmd, callback, stderr=subprocess.PIPE):
39 def process_handler(cmd, callback, stderr=subprocess.PIPE):
40 """Open a command in a shell subprocess and execute a callback.
40 """Open a command in a shell subprocess and execute a callback.
41
41
42 This function provides common scaffolding for creating subprocess.Popen()
42 This function provides common scaffolding for creating subprocess.Popen()
43 calls. It creates a Popen object and then calls the callback with it.
43 calls. It creates a Popen object and then calls the callback with it.
44
44
45 Parameters
45 Parameters
46 ----------
46 ----------
47 cmd : str
47 cmd : str
48 A string to be executed with the underlying system shell (by calling
48 A string to be executed with the underlying system shell (by calling
49 :func:`Popen` with ``shell=True``.
49 :func:`Popen` with ``shell=True``.
50
50
51 callback : callable
51 callback : callable
52 A one-argument function that will be called with the Popen object.
52 A one-argument function that will be called with the Popen object.
53
53
54 stderr : file descriptor number, optional
54 stderr : file descriptor number, optional
55 By default this is set to ``subprocess.PIPE``, but you can also pass the
55 By default this is set to ``subprocess.PIPE``, but you can also pass the
56 value ``subprocess.STDOUT`` to force the subprocess' stderr to go into
56 value ``subprocess.STDOUT`` to force the subprocess' stderr to go into
57 the same file descriptor as its stdout. This is useful to read stdout
57 the same file descriptor as its stdout. This is useful to read stdout
58 and stderr combined in the order they are generated.
58 and stderr combined in the order they are generated.
59
59
60 Returns
60 Returns
61 -------
61 -------
62 The return value of the provided callback is returned.
62 The return value of the provided callback is returned.
63 """
63 """
64 sys.stdout.flush()
64 sys.stdout.flush()
65 sys.stderr.flush()
65 sys.stderr.flush()
66 close_fds = False if sys.platform=='win32' else True
66 # On win32, close_fds can't be true when using pipes for stdin/out/err
67 close_fds = sys.platform != 'win32'
67 p = subprocess.Popen(cmd, shell=True,
68 p = subprocess.Popen(cmd, shell=True,
68 stdin=subprocess.PIPE,
69 stdin=subprocess.PIPE,
69 stdout=subprocess.PIPE,
70 stdout=subprocess.PIPE,
70 stderr=stderr,
71 stderr=stderr,
71 close_fds=close_fds)
72 close_fds=close_fds)
72
73
73 try:
74 try:
74 out = callback(p)
75 out = callback(p)
75 except KeyboardInterrupt:
76 except KeyboardInterrupt:
76 print('^C')
77 print('^C')
77 sys.stdout.flush()
78 sys.stdout.flush()
78 sys.stderr.flush()
79 sys.stderr.flush()
79 out = None
80 out = None
80 finally:
81 finally:
81 # Make really sure that we don't leave processes behind, in case the
82 # Make really sure that we don't leave processes behind, in case the
82 # call above raises an exception
83 # call above raises an exception
83 # We start by assuming the subprocess finished (to avoid NameErrors
84 # We start by assuming the subprocess finished (to avoid NameErrors
84 # later depending on the path taken)
85 # later depending on the path taken)
85 if p.returncode is None:
86 if p.returncode is None:
86 try:
87 try:
87 p.terminate()
88 p.terminate()
88 p.poll()
89 p.poll()
89 except OSError:
90 except OSError:
90 pass
91 pass
91 # One last try on our way out
92 # One last try on our way out
92 if p.returncode is None:
93 if p.returncode is None:
93 try:
94 try:
94 p.kill()
95 p.kill()
95 except OSError:
96 except OSError:
96 pass
97 pass
97
98
98 return out
99 return out
99
100
100
101
101 def getoutputerror(cmd):
102 def getoutputerror(cmd):
102 """Return (standard output, standard error) of executing cmd in a shell.
103 """Return (standard output, standard error) of executing cmd in a shell.
103
104
104 Accepts the same arguments as os.system().
105 Accepts the same arguments as os.system().
105
106
106 Parameters
107 Parameters
107 ----------
108 ----------
108 cmd : str
109 cmd : str
109 A command to be executed in the system shell.
110 A command to be executed in the system shell.
110
111
111 Returns
112 Returns
112 -------
113 -------
113 stdout : str
114 stdout : str
114 stderr : str
115 stderr : str
115 """
116 """
116
117
117 out_err = process_handler(cmd, lambda p: p.communicate())
118 out_err = process_handler(cmd, lambda p: p.communicate())
118 if out_err is None:
119 if out_err is None:
119 out_err = '', ''
120 out_err = '', ''
120 return out_err
121 return out_err
@@ -1,44 +1,114 b''
1 from kernelmanager import SubSocketChannel
1 """Implement a fully blocking kernel manager.
2
3 Useful for test suites and blocking terminal interfaces.
4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2010 The IPython Development Team
7 #
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING.txt, distributed as part of this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15 from __future__ import print_function
16
17 # Stdlib
2 from Queue import Queue, Empty
18 from Queue import Queue, Empty
3
19
20 # Our own
21 from IPython.utils import io
22 from IPython.utils.traitlets import Type
4
23
5 class MsgNotReady(Exception):
24 from .kernelmanager import (KernelManager, SubSocketChannel,
6 pass
25 XReqSocketChannel, RepSocketChannel, HBSocketChannel)
7
26
27 #-----------------------------------------------------------------------------
28 # Functions and classes
29 #-----------------------------------------------------------------------------
8
30
9 class BlockingSubSocketChannel(SubSocketChannel):
31 class BlockingSubSocketChannel(SubSocketChannel):
10
32
11 def __init__(self, context, session, address=None):
33 def __init__(self, context, session, address=None):
12 super(BlockingSubSocketChannel, self).__init__(context, session, address)
34 super(BlockingSubSocketChannel, self).__init__(context, session, address)
13 self._in_queue = Queue()
35 self._in_queue = Queue()
14
36
15 def call_handlers(self, msg):
37 def call_handlers(self, msg):
38 io.rprint('[[Sub]]', msg) # dbg
16 self._in_queue.put(msg)
39 self._in_queue.put(msg)
17
40
18 def msg_ready(self):
41 def msg_ready(self):
19 """Is there a message that has been received?"""
42 """Is there a message that has been received?"""
20 if self._in_queue.qsize() == 0:
43 if self._in_queue.qsize() == 0:
21 return False
44 return False
22 else:
45 else:
23 return True
46 return True
24
47
25 def get_msg(self, block=True, timeout=None):
48 def get_msg(self, block=True, timeout=None):
26 """Get a message if there is one that is ready."""
49 """Get a message if there is one that is ready."""
27 try:
50 return self.in_queue.get(block, timeout)
28 msg = self.in_queue.get(block, timeout)
51
29 except Empty:
52 def get_msgs(self):
30 raise MsgNotReady('No message has been received.')
53 """Get all messages that are currently ready."""
54 msgs = []
55 while True:
56 try:
57 msgs.append(self.get_msg(block=False))
58 except Empty:
59 break
60 return msgs
61
62
63
64 class BlockingXReqSocketChannel(XReqSocketChannel):
65
66 def __init__(self, context, session, address=None):
67 super(BlockingXReqSocketChannel, self).__init__(context, session, address)
68 self._in_queue = Queue()
69
70 def call_handlers(self, msg):
71 io.rprint('[[XReq]]', msg) # dbg
72
73 def msg_ready(self):
74 """Is there a message that has been received?"""
75 if self._in_queue.qsize() == 0:
76 return False
31 else:
77 else:
32 return msg
78 return True
79
80 def get_msg(self, block=True, timeout=None):
81 """Get a message if there is one that is ready."""
82 return self.in_queue.get(block, timeout)
33
83
34 def get_msgs(self):
84 def get_msgs(self):
35 """Get all messages that are currently ready."""
85 """Get all messages that are currently ready."""
36 msgs = []
86 msgs = []
37 while True:
87 while True:
38 try:
88 try:
39 msg = self.get_msg(block=False)
89 msgs.append(self.get_msg(block=False))
40 except MsgNotReady:
90 except Empty:
41 break
91 break
42 else:
92 return msgs
43 msgs.append(msg)
93
44 return msgs No newline at end of file
94 class BlockingRepSocketChannel(RepSocketChannel):
95 def call_handlers(self, msg):
96 io.rprint('[[Rep]]', msg) # dbg
97
98
99 class BlockingHBSocketChannel(HBSocketChannel):
100 # This kernel needs rapid monitoring capabilities
101 time_to_dead = 0.2
102
103 def call_handlers(self, since_last_heartbeat):
104 io.rprint('[[Heart]]', since_last_heartbeat) # dbg
105
106
107 class BlockingKernelManager(KernelManager):
108
109 # The classes to use for the various channels.
110 xreq_channel_class = Type(BlockingXReqSocketChannel)
111 sub_channel_class = Type(BlockingSubSocketChannel)
112 rep_channel_class = Type(BlockingRepSocketChannel)
113 hb_channel_class = Type(BlockingHBSocketChannel)
114
@@ -1,462 +1,486 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """A simple interactive kernel that talks to a frontend over 0MQ.
2 """A simple interactive kernel that talks to a frontend over 0MQ.
3
3
4 Things to do:
4 Things to do:
5
5
6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
6 * Implement `set_parent` logic. Right before doing exec, the Kernel should
7 call set_parent on all the PUB objects with the message about to be executed.
7 call set_parent on all the PUB objects with the message about to be executed.
8 * Implement random port and security key logic.
8 * Implement random port and security key logic.
9 * Implement control messages.
9 * Implement control messages.
10 * Implement event loop and poll version.
10 * Implement event loop and poll version.
11 """
11 """
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 # Standard library imports.
18 # Standard library imports.
19 import __builtin__
19 import __builtin__
20 import sys
20 import sys
21 import time
21 import time
22 import traceback
22 import traceback
23
23
24 # System library imports.
24 # System library imports.
25 import zmq
25 import zmq
26
26
27 # Local imports.
27 # Local imports.
28 from IPython.config.configurable import Configurable
28 from IPython.config.configurable import Configurable
29 from IPython.utils import io
29 from IPython.utils import io
30 from IPython.lib import pylabtools
30 from IPython.lib import pylabtools
31 from IPython.utils.traitlets import Instance
31 from IPython.utils.traitlets import Instance
32 from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \
32 from entry_point import base_launch_kernel, make_argument_parser, make_kernel, \
33 start_kernel
33 start_kernel
34 from iostream import OutStream
34 from iostream import OutStream
35 from session import Session, Message
35 from session import Session, Message
36 from zmqshell import ZMQInteractiveShell
36 from zmqshell import ZMQInteractiveShell
37
37
38
38 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
39 # Main kernel class
40 # Main kernel class
40 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
41
42
42 class Kernel(Configurable):
43 class Kernel(Configurable):
43
44
44 #---------------------------------------------------------------------------
45 #---------------------------------------------------------------------------
45 # Kernel interface
46 # Kernel interface
46 #---------------------------------------------------------------------------
47 #---------------------------------------------------------------------------
47
48
48 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
49 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
49 session = Instance(Session)
50 session = Instance(Session)
50 reply_socket = Instance('zmq.Socket')
51 reply_socket = Instance('zmq.Socket')
51 pub_socket = Instance('zmq.Socket')
52 pub_socket = Instance('zmq.Socket')
52 req_socket = Instance('zmq.Socket')
53 req_socket = Instance('zmq.Socket')
53
54
54 def __init__(self, **kwargs):
55 def __init__(self, **kwargs):
55 super(Kernel, self).__init__(**kwargs)
56 super(Kernel, self).__init__(**kwargs)
56
57
57 # Initialize the InteractiveShell subclass
58 # Initialize the InteractiveShell subclass
58 self.shell = ZMQInteractiveShell.instance()
59 self.shell = ZMQInteractiveShell.instance()
59 self.shell.displayhook.session = self.session
60 self.shell.displayhook.session = self.session
60 self.shell.displayhook.pub_socket = self.pub_socket
61 self.shell.displayhook.pub_socket = self.pub_socket
61
62
62 # TMP - hack while developing
63 # TMP - hack while developing
63 self.shell._reply_content = None
64 self.shell._reply_content = None
64
65
65 # Build dict of handlers for message types
66 # Build dict of handlers for message types
66 msg_types = [ 'execute_request', 'complete_request',
67 msg_types = [ 'execute_request', 'complete_request',
67 'object_info_request', 'prompt_request',
68 'object_info_request', 'history_request' ]
68 'history_request' ]
69 self.handlers = {}
69 self.handlers = {}
70 for msg_type in msg_types:
70 for msg_type in msg_types:
71 self.handlers[msg_type] = getattr(self, msg_type)
71 self.handlers[msg_type] = getattr(self, msg_type)
72
72
73 def do_one_iteration(self):
73 def do_one_iteration(self):
74 try:
74 try:
75 ident = self.reply_socket.recv(zmq.NOBLOCK)
75 ident = self.reply_socket.recv(zmq.NOBLOCK)
76 except zmq.ZMQError, e:
76 except zmq.ZMQError, e:
77 if e.errno == zmq.EAGAIN:
77 if e.errno == zmq.EAGAIN:
78 return
78 return
79 else:
79 else:
80 raise
80 raise
81 # FIXME: Bug in pyzmq/zmq?
81 # FIXME: Bug in pyzmq/zmq?
82 # assert self.reply_socket.rcvmore(), "Missing message part."
82 # assert self.reply_socket.rcvmore(), "Missing message part."
83 msg = self.reply_socket.recv_json()
83 msg = self.reply_socket.recv_json()
84 omsg = Message(msg)
84
85 io.raw_print('\n')
85 # Print some info about this message and leave a '--->' marker, so it's
86 io.raw_print(omsg)
86 # easier to trace visually the message chain when debugging. Each
87 handler = self.handlers.get(omsg.msg_type, None)
87 # handler prints its message at the end.
88 # Eventually we'll move these from stdout to a logger.
89 io.raw_print('\n*** MESSAGE TYPE:', msg['msg_type'], '***')
90 io.raw_print(' Content: ', msg['content'],
91 '\n --->\n ', sep='', end='')
92
93 # Find and call actual handler for message
94 handler = self.handlers.get(msg['msg_type'], None)
88 if handler is None:
95 if handler is None:
89 io.raw_print_err("UNKNOWN MESSAGE TYPE:", omsg)
96 io.raw_print_err("UNKNOWN MESSAGE TYPE:", msg)
90 else:
97 else:
91 handler(ident, omsg)
98 handler(ident, msg)
92
99
93 def start(self):
100 def start(self):
94 """ Start the kernel main loop.
101 """ Start the kernel main loop.
95 """
102 """
96 while True:
103 while True:
97 time.sleep(0.05)
104 time.sleep(0.05)
98 self.do_one_iteration()
105 self.do_one_iteration()
99
106
100
101 #---------------------------------------------------------------------------
107 #---------------------------------------------------------------------------
102 # Kernel request handlers
108 # Kernel request handlers
103 #---------------------------------------------------------------------------
109 #---------------------------------------------------------------------------
104
110
111 def _publish_pyin(self, code, parent):
112 """Publish the code request on the pyin stream."""
113
114 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
115 self.pub_socket.send_json(pyin_msg)
116
105 def execute_request(self, ident, parent):
117 def execute_request(self, ident, parent):
106 try:
118 try:
107 code = parent[u'content'][u'code']
119 content = parent[u'content']
120 code = content[u'code']
121 silent = content[u'silent']
108 except:
122 except:
109 io.raw_print_err("Got bad msg: ")
123 io.raw_print_err("Got bad msg: ")
110 io.raw_print_err(Message(parent))
124 io.raw_print_err(Message(parent))
111 return
125 return
112 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
113 self.pub_socket.send_json(pyin_msg)
114
126
127 shell = self.shell # we'll need this a lot here
128
129 # Replace raw_input. Note that is not sufficient to replace
130 # raw_input in the user namespace.
131 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
132 __builtin__.raw_input = raw_input
133
134 # Set the parent message of the display hook and out streams.
135 shell.displayhook.set_parent(parent)
136 sys.stdout.set_parent(parent)
137 sys.stderr.set_parent(parent)
138
139 # Re-broadcast our input for the benefit of listening clients, and
140 # start computing output
141 if not silent:
142 self._publish_pyin(code, parent)
143
144 reply_content = {}
115 try:
145 try:
116 # Replace raw_input. Note that is not sufficient to replace
146 if silent:
117 # raw_input in the user namespace.
147 # runcode uses 'exec' mode, so no displayhook will fire, and it
118 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
148 # doesn't call logging or history manipulations. Print
119 __builtin__.raw_input = raw_input
149 # statements in that code will obviously still execute.
120
150 shell.runcode(code)
121 # Set the parent message of the display hook and out streams.
151 else:
122 self.shell.displayhook.set_parent(parent)
152 # FIXME: runlines calls the exception handler itself.
123 sys.stdout.set_parent(parent)
153 shell._reply_content = None
124 sys.stderr.set_parent(parent)
154 shell.runlines(code)
125
126 # FIXME: runlines calls the exception handler itself. We should
127 # clean this up.
128 self.shell._reply_content = None
129 self.shell.runlines(code)
130 except:
155 except:
156 status = u'error'
131 # FIXME: this code right now isn't being used yet by default,
157 # FIXME: this code right now isn't being used yet by default,
132 # because the runlines() call above directly fires off exception
158 # because the runlines() call above directly fires off exception
133 # reporting. This code, therefore, is only active in the scenario
159 # reporting. This code, therefore, is only active in the scenario
134 # where runlines itself has an unhandled exception. We need to
160 # where runlines itself has an unhandled exception. We need to
135 # uniformize this, for all exception construction to come from a
161 # uniformize this, for all exception construction to come from a
136 # single location in the codbase.
162 # single location in the codbase.
137 etype, evalue, tb = sys.exc_info()
163 etype, evalue, tb = sys.exc_info()
138 tb_list = traceback.format_exception(etype, evalue, tb)
164 tb_list = traceback.format_exception(etype, evalue, tb)
139 reply_content = self.shell._showtraceback(etype, evalue, tb_list)
165 reply_content.update(shell._showtraceback(etype, evalue, tb_list))
140 else:
166 else:
141 payload = self.shell.payload_manager.read_payload()
167 status = u'ok'
168 reply_content[u'payload'] = shell.payload_manager.read_payload()
142 # Be agressive about clearing the payload because we don't want
169 # Be agressive about clearing the payload because we don't want
143 # it to sit in memory until the next execute_request comes in.
170 # it to sit in memory until the next execute_request comes in.
144 self.shell.payload_manager.clear_payload()
171 shell.payload_manager.clear_payload()
145 reply_content = { 'status' : 'ok', 'payload' : payload }
172
146
173 reply_content[u'status'] = status
147 # Compute the prompt information
174 # Compute the execution counter so clients can display prompts
148 prompt_number = self.shell.displayhook.prompt_count
175 reply_content['execution_count'] = shell.displayhook.prompt_count
149 reply_content['prompt_number'] = prompt_number
176
150 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
177 # FIXME - fish exception info out of shell, possibly left there by
151 next_prompt = {'prompt_string' : prompt_string,
178 # runlines. We'll need to clean up this logic later.
152 'prompt_number' : prompt_number+1,
179 if shell._reply_content is not None:
153 'input_sep' : self.shell.displayhook.input_sep}
180 reply_content.update(shell._reply_content)
154 reply_content['next_prompt'] = next_prompt
181
155
182 # At this point, we can tell whether the main code execution succeeded
156 # TMP - fish exception info out of shell, possibly left there by
183 # or not. If it did, we proceed to evaluate user_variables/expressions
157 # runlines
184 if reply_content['status'] == 'ok':
158 if self.shell._reply_content is not None:
185 reply_content[u'user_variables'] = \
159 reply_content.update(self.shell._reply_content)
186 shell.get_user_variables(content[u'user_variables'])
160
187 reply_content[u'user_expressions'] = \
161 # Flush output before sending the reply.
188 shell.eval_expressions(content[u'user_expressions'])
162 sys.stderr.flush()
189 else:
163 sys.stdout.flush()
190 # If there was an error, don't even try to compute variables or
164
191 # expressions
192 reply_content[u'user_variables'] = {}
193 reply_content[u'user_expressions'] = {}
194
165 # Send the reply.
195 # Send the reply.
166 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
196 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
167 io.raw_print(Message(reply_msg))
197 io.raw_print(reply_msg)
168 self.reply_socket.send(ident, zmq.SNDMORE)
198 self.reply_socket.send(ident, zmq.SNDMORE)
169 self.reply_socket.send_json(reply_msg)
199 self.reply_socket.send_json(reply_msg)
170 if reply_msg['content']['status'] == u'error':
200 if reply_msg['content']['status'] == u'error':
171 self._abort_queue()
201 self._abort_queue()
172
202
173 def complete_request(self, ident, parent):
203 def complete_request(self, ident, parent):
174 txt, matches = self._complete(parent)
204 txt, matches = self._complete(parent)
175 matches = {'matches' : matches,
205 matches = {'matches' : matches,
176 'matched_text' : txt,
206 'matched_text' : txt,
177 'status' : 'ok'}
207 'status' : 'ok'}
178 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
208 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
179 matches, parent, ident)
209 matches, parent, ident)
180 io.raw_print(completion_msg)
210 io.raw_print(completion_msg)
181
211
182 def object_info_request(self, ident, parent):
212 def object_info_request(self, ident, parent):
183 context = parent['content']['oname'].split('.')
213 context = parent['content']['oname'].split('.')
184 object_info = self._object_info(context)
214 object_info = self._object_info(context)
185 msg = self.session.send(self.reply_socket, 'object_info_reply',
215 msg = self.session.send(self.reply_socket, 'object_info_reply',
186 object_info, parent, ident)
216 object_info, parent, ident)
187 io.raw_print(msg)
217 io.raw_print(msg)
188
218
189 def prompt_request(self, ident, parent):
190 prompt_number = self.shell.displayhook.prompt_count
191 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
192 content = {'prompt_string' : prompt_string,
193 'prompt_number' : prompt_number+1,
194 'input_sep' : self.shell.displayhook.input_sep}
195 msg = self.session.send(self.reply_socket, 'prompt_reply',
196 content, parent, ident)
197 io.raw_print(msg)
198
199 def history_request(self, ident, parent):
219 def history_request(self, ident, parent):
200 output = parent['content']['output']
220 output = parent['content']['output']
201 index = parent['content']['index']
221 index = parent['content']['index']
202 raw = parent['content']['raw']
222 raw = parent['content']['raw']
203 hist = self.shell.get_history(index=index, raw=raw, output=output)
223 hist = self.shell.get_history(index=index, raw=raw, output=output)
204 content = {'history' : hist}
224 content = {'history' : hist}
205 msg = self.session.send(self.reply_socket, 'history_reply',
225 msg = self.session.send(self.reply_socket, 'history_reply',
206 content, parent, ident)
226 content, parent, ident)
207 io.raw_print(msg)
227 io.raw_print(msg)
208
228
209 #---------------------------------------------------------------------------
229 #---------------------------------------------------------------------------
210 # Protected interface
230 # Protected interface
211 #---------------------------------------------------------------------------
231 #---------------------------------------------------------------------------
212
232
213 def _abort_queue(self):
233 def _abort_queue(self):
214 while True:
234 while True:
215 try:
235 try:
216 ident = self.reply_socket.recv(zmq.NOBLOCK)
236 ident = self.reply_socket.recv(zmq.NOBLOCK)
217 except zmq.ZMQError, e:
237 except zmq.ZMQError, e:
218 if e.errno == zmq.EAGAIN:
238 if e.errno == zmq.EAGAIN:
219 break
239 break
220 else:
240 else:
221 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
241 assert self.reply_socket.rcvmore(), \
242 "Unexpected missing message part."
222 msg = self.reply_socket.recv_json()
243 msg = self.reply_socket.recv_json()
223 io.raw_print("Aborting:\n", Message(msg))
244 io.raw_print("Aborting:\n", Message(msg))
224 msg_type = msg['msg_type']
245 msg_type = msg['msg_type']
225 reply_type = msg_type.split('_')[0] + '_reply'
246 reply_type = msg_type.split('_')[0] + '_reply'
226 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
247 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
227 io.raw_print(Message(reply_msg))
248 io.raw_print(reply_msg)
228 self.reply_socket.send(ident,zmq.SNDMORE)
249 self.reply_socket.send(ident,zmq.SNDMORE)
229 self.reply_socket.send_json(reply_msg)
250 self.reply_socket.send_json(reply_msg)
230 # We need to wait a bit for requests to come in. This can probably
251 # We need to wait a bit for requests to come in. This can probably
231 # be set shorter for true asynchronous clients.
252 # be set shorter for true asynchronous clients.
232 time.sleep(0.1)
253 time.sleep(0.1)
233
254
234 def _raw_input(self, prompt, ident, parent):
255 def _raw_input(self, prompt, ident, parent):
235 # Flush output before making the request.
256 # Flush output before making the request.
236 sys.stderr.flush()
257 sys.stderr.flush()
237 sys.stdout.flush()
258 sys.stdout.flush()
238
259
239 # Send the input request.
260 # Send the input request.
240 content = dict(prompt=prompt)
261 content = dict(prompt=prompt)
241 msg = self.session.msg(u'input_request', content, parent)
262 msg = self.session.msg(u'input_request', content, parent)
242 self.req_socket.send_json(msg)
263 self.req_socket.send_json(msg)
243
264
244 # Await a response.
265 # Await a response.
245 reply = self.req_socket.recv_json()
266 reply = self.req_socket.recv_json()
246 try:
267 try:
247 value = reply['content']['value']
268 value = reply['content']['value']
248 except:
269 except:
249 io.raw_print_err("Got bad raw_input reply: ")
270 io.raw_print_err("Got bad raw_input reply: ")
250 io.raw_print_err(Message(parent))
271 io.raw_print_err(Message(parent))
251 value = ''
272 value = ''
252 return value
273 return value
253
274
254 def _complete(self, msg):
275 def _complete(self, msg):
255 c = msg['content']
276 c = msg['content']
256 try:
277 try:
257 cpos = int(c['cursor_pos'])
278 cpos = int(c['cursor_pos'])
258 except:
279 except:
259 # If we don't get something that we can convert to an integer, at
280 # If we don't get something that we can convert to an integer, at
260 # least attempt the completion guessing the cursor is at the end of
281 # least attempt the completion guessing the cursor is at the end of
261 # the text, if there's any, and otherwise of the line
282 # the text, if there's any, and otherwise of the line
262 cpos = len(c['text'])
283 cpos = len(c['text'])
263 if cpos==0:
284 if cpos==0:
264 cpos = len(c['line'])
285 cpos = len(c['line'])
265 return self.shell.complete(c['text'], c['line'], cpos)
286 return self.shell.complete(c['text'], c['line'], cpos)
266
287
267 def _object_info(self, context):
288 def _object_info(self, context):
268 symbol, leftover = self._symbol_from_context(context)
289 symbol, leftover = self._symbol_from_context(context)
269 if symbol is not None and not leftover:
290 if symbol is not None and not leftover:
270 doc = getattr(symbol, '__doc__', '')
291 doc = getattr(symbol, '__doc__', '')
271 else:
292 else:
272 doc = ''
293 doc = ''
273 object_info = dict(docstring = doc)
294 object_info = dict(docstring = doc)
274 return object_info
295 return object_info
275
296
276 def _symbol_from_context(self, context):
297 def _symbol_from_context(self, context):
277 if not context:
298 if not context:
278 return None, context
299 return None, context
279
300
280 base_symbol_string = context[0]
301 base_symbol_string = context[0]
281 symbol = self.shell.user_ns.get(base_symbol_string, None)
302 symbol = self.shell.user_ns.get(base_symbol_string, None)
282 if symbol is None:
303 if symbol is None:
283 symbol = __builtin__.__dict__.get(base_symbol_string, None)
304 symbol = __builtin__.__dict__.get(base_symbol_string, None)
284 if symbol is None:
305 if symbol is None:
285 return None, context
306 return None, context
286
307
287 context = context[1:]
308 context = context[1:]
288 for i, name in enumerate(context):
309 for i, name in enumerate(context):
289 new_symbol = getattr(symbol, name, None)
310 new_symbol = getattr(symbol, name, None)
290 if new_symbol is None:
311 if new_symbol is None:
291 return symbol, context[i:]
312 return symbol, context[i:]
292 else:
313 else:
293 symbol = new_symbol
314 symbol = new_symbol
294
315
295 return symbol, []
316 return symbol, []
296
317
297
318
298 class QtKernel(Kernel):
319 class QtKernel(Kernel):
299 """A Kernel subclass with Qt support."""
320 """A Kernel subclass with Qt support."""
300
321
301 def start(self):
322 def start(self):
302 """Start a kernel with QtPy4 event loop integration."""
323 """Start a kernel with QtPy4 event loop integration."""
303
324
304 from PyQt4 import QtGui, QtCore
325 from PyQt4 import QtGui, QtCore
305 from IPython.lib.guisupport import (
326 from IPython.lib.guisupport import (
306 get_app_qt4, start_event_loop_qt4
327 get_app_qt4, start_event_loop_qt4
307 )
328 )
308 self.app = get_app_qt4([" "])
329 self.app = get_app_qt4([" "])
309 self.app.setQuitOnLastWindowClosed(False)
330 self.app.setQuitOnLastWindowClosed(False)
310 self.timer = QtCore.QTimer()
331 self.timer = QtCore.QTimer()
311 self.timer.timeout.connect(self.do_one_iteration)
332 self.timer.timeout.connect(self.do_one_iteration)
312 self.timer.start(50)
333 self.timer.start(50)
313 start_event_loop_qt4(self.app)
334 start_event_loop_qt4(self.app)
314
335
336
315 class WxKernel(Kernel):
337 class WxKernel(Kernel):
316 """A Kernel subclass with Wx support."""
338 """A Kernel subclass with Wx support."""
317
339
318 def start(self):
340 def start(self):
319 """Start a kernel with wx event loop support."""
341 """Start a kernel with wx event loop support."""
320
342
321 import wx
343 import wx
322 from IPython.lib.guisupport import start_event_loop_wx
344 from IPython.lib.guisupport import start_event_loop_wx
323 doi = self.do_one_iteration
345 doi = self.do_one_iteration
324
346
325 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
347 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
326 # We make the Frame hidden when we create it in the main app below.
348 # We make the Frame hidden when we create it in the main app below.
327 class TimerFrame(wx.Frame):
349 class TimerFrame(wx.Frame):
328 def __init__(self, func):
350 def __init__(self, func):
329 wx.Frame.__init__(self, None, -1)
351 wx.Frame.__init__(self, None, -1)
330 self.timer = wx.Timer(self)
352 self.timer = wx.Timer(self)
331 self.timer.Start(50)
353 self.timer.Start(50)
332 self.Bind(wx.EVT_TIMER, self.on_timer)
354 self.Bind(wx.EVT_TIMER, self.on_timer)
333 self.func = func
355 self.func = func
334 def on_timer(self, event):
356 def on_timer(self, event):
335 self.func()
357 self.func()
336
358
337 # We need a custom wx.App to create our Frame subclass that has the
359 # We need a custom wx.App to create our Frame subclass that has the
338 # wx.Timer to drive the ZMQ event loop.
360 # wx.Timer to drive the ZMQ event loop.
339 class IPWxApp(wx.App):
361 class IPWxApp(wx.App):
340 def OnInit(self):
362 def OnInit(self):
341 self.frame = TimerFrame(doi)
363 self.frame = TimerFrame(doi)
342 self.frame.Show(False)
364 self.frame.Show(False)
343 return True
365 return True
344
366
345 # The redirect=False here makes sure that wx doesn't replace
367 # The redirect=False here makes sure that wx doesn't replace
346 # sys.stdout/stderr with its own classes.
368 # sys.stdout/stderr with its own classes.
347 self.app = IPWxApp(redirect=False)
369 self.app = IPWxApp(redirect=False)
348 start_event_loop_wx(self.app)
370 start_event_loop_wx(self.app)
349
371
350
372
351 class TkKernel(Kernel):
373 class TkKernel(Kernel):
352 """A Kernel subclass with Tk support."""
374 """A Kernel subclass with Tk support."""
353
375
354 def start(self):
376 def start(self):
355 """Start a Tk enabled event loop."""
377 """Start a Tk enabled event loop."""
356
378
357 import Tkinter
379 import Tkinter
358 doi = self.do_one_iteration
380 doi = self.do_one_iteration
359
381
360 # For Tkinter, we create a Tk object and call its withdraw method.
382 # For Tkinter, we create a Tk object and call its withdraw method.
361 class Timer(object):
383 class Timer(object):
362 def __init__(self, func):
384 def __init__(self, func):
363 self.app = Tkinter.Tk()
385 self.app = Tkinter.Tk()
364 self.app.withdraw()
386 self.app.withdraw()
365 self.func = func
387 self.func = func
366 def on_timer(self):
388 def on_timer(self):
367 self.func()
389 self.func()
368 self.app.after(50, self.on_timer)
390 self.app.after(50, self.on_timer)
369 def start(self):
391 def start(self):
370 self.on_timer() # Call it once to get things going.
392 self.on_timer() # Call it once to get things going.
371 self.app.mainloop()
393 self.app.mainloop()
372
394
373 self.timer = Timer(doi)
395 self.timer = Timer(doi)
374 self.timer.start()
396 self.timer.start()
375
397
376 #-----------------------------------------------------------------------------
398 #-----------------------------------------------------------------------------
377 # Kernel main and launch functions
399 # Kernel main and launch functions
378 #-----------------------------------------------------------------------------
400 #-----------------------------------------------------------------------------
379
401
380 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, hb_port=0,
402 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, hb_port=0,
381 independent=False, pylab=False):
403 independent=False, pylab=False):
382 """ Launches a localhost kernel, binding to the specified ports.
404 """ Launches a localhost kernel, binding to the specified ports.
383
405
384 Parameters
406 Parameters
385 ----------
407 ----------
386 xrep_port : int, optional
408 xrep_port : int, optional
387 The port to use for XREP channel.
409 The port to use for XREP channel.
388
410
389 pub_port : int, optional
411 pub_port : int, optional
390 The port to use for the SUB channel.
412 The port to use for the SUB channel.
391
413
392 req_port : int, optional
414 req_port : int, optional
393 The port to use for the REQ (raw input) channel.
415 The port to use for the REQ (raw input) channel.
394
416
395 hb_port : int, optional
417 hb_port : int, optional
396 The port to use for the hearbeat REP channel.
418 The port to use for the hearbeat REP channel.
397
419
398 independent : bool, optional (default False)
420 independent : bool, optional (default False)
399 If set, the kernel process is guaranteed to survive if this process
421 If set, the kernel process is guaranteed to survive if this process
400 dies. If not set, an effort is made to ensure that the kernel is killed
422 dies. If not set, an effort is made to ensure that the kernel is killed
401 when this process dies. Note that in this case it is still good practice
423 when this process dies. Note that in this case it is still good practice
402 to kill kernels manually before exiting.
424 to kill kernels manually before exiting.
403
425
404 pylab : bool or string, optional (default False)
426 pylab : bool or string, optional (default False)
405 If not False, the kernel will be launched with pylab enabled. If a
427 If not False, the kernel will be launched with pylab enabled. If a
406 string is passed, matplotlib will use the specified backend. Otherwise,
428 string is passed, matplotlib will use the specified backend. Otherwise,
407 matplotlib's default backend will be used.
429 matplotlib's default backend will be used.
408
430
409 Returns
431 Returns
410 -------
432 -------
411 A tuple of form:
433 A tuple of form:
412 (kernel_process, xrep_port, pub_port, req_port)
434 (kernel_process, xrep_port, pub_port, req_port)
413 where kernel_process is a Popen object and the ports are integers.
435 where kernel_process is a Popen object and the ports are integers.
414 """
436 """
415 extra_arguments = []
437 extra_arguments = []
416 if pylab:
438 if pylab:
417 extra_arguments.append('--pylab')
439 extra_arguments.append('--pylab')
418 if isinstance(pylab, basestring):
440 if isinstance(pylab, basestring):
419 extra_arguments.append(pylab)
441 extra_arguments.append(pylab)
420 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
442 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
421 xrep_port, pub_port, req_port, hb_port,
443 xrep_port, pub_port, req_port, hb_port,
422 independent, extra_arguments)
444 independent, extra_arguments)
423
445
446
424 def main():
447 def main():
425 """ The IPython kernel main entry point.
448 """ The IPython kernel main entry point.
426 """
449 """
427 parser = make_argument_parser()
450 parser = make_argument_parser()
428 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
451 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
429 const='auto', help = \
452 const='auto', help = \
430 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
453 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
431 given, the GUI backend is matplotlib's, otherwise use one of: \
454 given, the GUI backend is matplotlib's, otherwise use one of: \
432 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
455 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
433 namespace = parser.parse_args()
456 namespace = parser.parse_args()
434
457
435 kernel_class = Kernel
458 kernel_class = Kernel
436
459
437 _kernel_classes = {
460 _kernel_classes = {
438 'qt' : QtKernel,
461 'qt' : QtKernel,
439 'qt4' : QtKernel,
462 'qt4' : QtKernel,
440 'payload-svg': Kernel,
463 'payload-svg': Kernel,
441 'wx' : WxKernel,
464 'wx' : WxKernel,
442 'tk' : TkKernel
465 'tk' : TkKernel
443 }
466 }
444 if namespace.pylab:
467 if namespace.pylab:
445 if namespace.pylab == 'auto':
468 if namespace.pylab == 'auto':
446 gui, backend = pylabtools.find_gui_and_backend()
469 gui, backend = pylabtools.find_gui_and_backend()
447 else:
470 else:
448 gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
471 gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
449 kernel_class = _kernel_classes.get(gui)
472 kernel_class = _kernel_classes.get(gui)
450 if kernel_class is None:
473 if kernel_class is None:
451 raise ValueError('GUI is not supported: %r' % gui)
474 raise ValueError('GUI is not supported: %r' % gui)
452 pylabtools.activate_matplotlib(backend)
475 pylabtools.activate_matplotlib(backend)
453
476
454 kernel = make_kernel(namespace, kernel_class, OutStream)
477 kernel = make_kernel(namespace, kernel_class, OutStream)
455
478
456 if namespace.pylab:
479 if namespace.pylab:
457 pylabtools.import_pylab(kernel.shell.user_ns)
480 pylabtools.import_pylab(kernel.shell.user_ns)
458
481
459 start_kernel(namespace, kernel)
482 start_kernel(namespace, kernel)
460
483
484
461 if __name__ == '__main__':
485 if __name__ == '__main__':
462 main()
486 main()
@@ -1,729 +1,786 b''
1 """Base classes to manage the interaction with a running kernel.
1 """Base classes to manage the interaction with a running kernel.
2
2
3 Todo
3 Todo
4 ====
4 ====
5
5
6 * Create logger to handle debugging and console messages.
6 * Create logger to handle debugging and console messages.
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2010 The IPython Development Team
10 # Copyright (C) 2008-2010 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 # Standard library imports.
20 # Standard library imports.
21 from Queue import Queue, Empty
21 from Queue import Queue, Empty
22 from subprocess import Popen
22 from subprocess import Popen
23 from threading import Thread
23 from threading import Thread
24 import time
24 import time
25
25
26 # System library imports.
26 # System library imports.
27 import zmq
27 import zmq
28 from zmq import POLLIN, POLLOUT, POLLERR
28 from zmq import POLLIN, POLLOUT, POLLERR
29 from zmq.eventloop import ioloop
29 from zmq.eventloop import ioloop
30
30
31 # Local imports.
31 # Local imports.
32 from IPython.utils import io
32 from IPython.utils.traitlets import HasTraits, Any, Instance, Type, TCPAddress
33 from IPython.utils.traitlets import HasTraits, Any, Instance, Type, TCPAddress
33 from session import Session
34 from session import Session
34
35
35 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
36 # Constants and exceptions
37 # Constants and exceptions
37 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
38
39
39 LOCALHOST = '127.0.0.1'
40 LOCALHOST = '127.0.0.1'
40
41
41 class InvalidPortNumber(Exception):
42 class InvalidPortNumber(Exception):
42 pass
43 pass
43
44
44 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46 # Utility functions
47 #-----------------------------------------------------------------------------
48
49 # some utilities to validate message structure, these might get moved elsewhere
50 # if they prove to have more generic utility
51
52 def validate_string_list(lst):
53 """Validate that the input is a list of strings.
54
55 Raises ValueError if not."""
56 if not isinstance(lst, list):
57 raise ValueError('input %r must be a list' % lst)
58 for x in lst:
59 if not isinstance(x, basestring):
60 raise ValueError('element %r in list must be a string' % x)
61
62
63 def validate_string_dict(dct):
64 """Validate that the input is a dict with string keys and values.
65
66 Raises ValueError if not."""
67 for k,v in dct.iteritems():
68 if not isinstance(k, basestring):
69 raise ValueError('key %r in dict must be a string' % k)
70 if not isinstance(v, basestring):
71 raise ValueError('value %r in dict must be a string' % v)
72
73
74 #-----------------------------------------------------------------------------
45 # ZMQ Socket Channel classes
75 # ZMQ Socket Channel classes
46 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
47
77
48 class ZmqSocketChannel(Thread):
78 class ZmqSocketChannel(Thread):
49 """The base class for the channels that use ZMQ sockets.
79 """The base class for the channels that use ZMQ sockets.
50 """
80 """
51 context = None
81 context = None
52 session = None
82 session = None
53 socket = None
83 socket = None
54 ioloop = None
84 ioloop = None
55 iostate = None
85 iostate = None
56 _address = None
86 _address = None
57
87
58 def __init__(self, context, session, address):
88 def __init__(self, context, session, address):
59 """Create a channel
89 """Create a channel
60
90
61 Parameters
91 Parameters
62 ----------
92 ----------
63 context : :class:`zmq.Context`
93 context : :class:`zmq.Context`
64 The ZMQ context to use.
94 The ZMQ context to use.
65 session : :class:`session.Session`
95 session : :class:`session.Session`
66 The session to use.
96 The session to use.
67 address : tuple
97 address : tuple
68 Standard (ip, port) tuple that the kernel is listening on.
98 Standard (ip, port) tuple that the kernel is listening on.
69 """
99 """
70 super(ZmqSocketChannel, self).__init__()
100 super(ZmqSocketChannel, self).__init__()
71 self.daemon = True
101 self.daemon = True
72
102
73 self.context = context
103 self.context = context
74 self.session = session
104 self.session = session
75 if address[1] == 0:
105 if address[1] == 0:
76 message = 'The port number for a channel cannot be 0.'
106 message = 'The port number for a channel cannot be 0.'
77 raise InvalidPortNumber(message)
107 raise InvalidPortNumber(message)
78 self._address = address
108 self._address = address
79
109
80 def stop(self):
110 def stop(self):
81 """Stop the channel's activity.
111 """Stop the channel's activity.
82
112
83 This calls :method:`Thread.join` and returns when the thread
113 This calls :method:`Thread.join` and returns when the thread
84 terminates. :class:`RuntimeError` will be raised if
114 terminates. :class:`RuntimeError` will be raised if
85 :method:`self.start` is called again.
115 :method:`self.start` is called again.
86 """
116 """
87 self.join()
117 self.join()
88
118
89 @property
119 @property
90 def address(self):
120 def address(self):
91 """Get the channel's address as an (ip, port) tuple.
121 """Get the channel's address as an (ip, port) tuple.
92
122
93 By the default, the address is (localhost, 0), where 0 means a random
123 By the default, the address is (localhost, 0), where 0 means a random
94 port.
124 port.
95 """
125 """
96 return self._address
126 return self._address
97
127
98 def add_io_state(self, state):
128 def add_io_state(self, state):
99 """Add IO state to the eventloop.
129 """Add IO state to the eventloop.
100
130
101 Parameters
131 Parameters
102 ----------
132 ----------
103 state : zmq.POLLIN|zmq.POLLOUT|zmq.POLLERR
133 state : zmq.POLLIN|zmq.POLLOUT|zmq.POLLERR
104 The IO state flag to set.
134 The IO state flag to set.
105
135
106 This is thread safe as it uses the thread safe IOLoop.add_callback.
136 This is thread safe as it uses the thread safe IOLoop.add_callback.
107 """
137 """
108 def add_io_state_callback():
138 def add_io_state_callback():
109 if not self.iostate & state:
139 if not self.iostate & state:
110 self.iostate = self.iostate | state
140 self.iostate = self.iostate | state
111 self.ioloop.update_handler(self.socket, self.iostate)
141 self.ioloop.update_handler(self.socket, self.iostate)
112 self.ioloop.add_callback(add_io_state_callback)
142 self.ioloop.add_callback(add_io_state_callback)
113
143
114 def drop_io_state(self, state):
144 def drop_io_state(self, state):
115 """Drop IO state from the eventloop.
145 """Drop IO state from the eventloop.
116
146
117 Parameters
147 Parameters
118 ----------
148 ----------
119 state : zmq.POLLIN|zmq.POLLOUT|zmq.POLLERR
149 state : zmq.POLLIN|zmq.POLLOUT|zmq.POLLERR
120 The IO state flag to set.
150 The IO state flag to set.
121
151
122 This is thread safe as it uses the thread safe IOLoop.add_callback.
152 This is thread safe as it uses the thread safe IOLoop.add_callback.
123 """
153 """
124 def drop_io_state_callback():
154 def drop_io_state_callback():
125 if self.iostate & state:
155 if self.iostate & state:
126 self.iostate = self.iostate & (~state)
156 self.iostate = self.iostate & (~state)
127 self.ioloop.update_handler(self.socket, self.iostate)
157 self.ioloop.update_handler(self.socket, self.iostate)
128 self.ioloop.add_callback(drop_io_state_callback)
158 self.ioloop.add_callback(drop_io_state_callback)
129
159
130
160
131 class XReqSocketChannel(ZmqSocketChannel):
161 class XReqSocketChannel(ZmqSocketChannel):
132 """The XREQ channel for issues request/replies to the kernel.
162 """The XREQ channel for issues request/replies to the kernel.
133 """
163 """
134
164
135 command_queue = None
165 command_queue = None
136
166
137 def __init__(self, context, session, address):
167 def __init__(self, context, session, address):
138 self.command_queue = Queue()
168 self.command_queue = Queue()
139 super(XReqSocketChannel, self).__init__(context, session, address)
169 super(XReqSocketChannel, self).__init__(context, session, address)
140
170
141 def run(self):
171 def run(self):
142 """The thread's main activity. Call start() instead."""
172 """The thread's main activity. Call start() instead."""
143 self.socket = self.context.socket(zmq.XREQ)
173 self.socket = self.context.socket(zmq.XREQ)
144 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
174 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
145 self.socket.connect('tcp://%s:%i' % self.address)
175 self.socket.connect('tcp://%s:%i' % self.address)
146 self.ioloop = ioloop.IOLoop()
176 self.ioloop = ioloop.IOLoop()
147 self.iostate = POLLERR|POLLIN
177 self.iostate = POLLERR|POLLIN
148 self.ioloop.add_handler(self.socket, self._handle_events,
178 self.ioloop.add_handler(self.socket, self._handle_events,
149 self.iostate)
179 self.iostate)
150 self.ioloop.start()
180 self.ioloop.start()
151
181
152 def stop(self):
182 def stop(self):
153 self.ioloop.stop()
183 self.ioloop.stop()
154 super(XReqSocketChannel, self).stop()
184 super(XReqSocketChannel, self).stop()
155
185
156 def call_handlers(self, msg):
186 def call_handlers(self, msg):
157 """This method is called in the ioloop thread when a message arrives.
187 """This method is called in the ioloop thread when a message arrives.
158
188
159 Subclasses should override this method to handle incoming messages.
189 Subclasses should override this method to handle incoming messages.
160 It is important to remember that this method is called in the thread
190 It is important to remember that this method is called in the thread
161 so that some logic must be done to ensure that the application leve
191 so that some logic must be done to ensure that the application leve
162 handlers are called in the application thread.
192 handlers are called in the application thread.
163 """
193 """
164 raise NotImplementedError('call_handlers must be defined in a subclass.')
194 raise NotImplementedError('call_handlers must be defined in a subclass.')
165
195
166 def execute(self, code, silent=False):
196 def execute(self, code, silent=False,
197 user_variables=None, user_expressions=None):
167 """Execute code in the kernel.
198 """Execute code in the kernel.
168
199
169 Parameters
200 Parameters
170 ----------
201 ----------
171 code : str
202 code : str
172 A string of Python code.
203 A string of Python code.
204
173 silent : bool, optional (default False)
205 silent : bool, optional (default False)
174 If set, the kernel will execute the code as quietly possible.
206 If set, the kernel will execute the code as quietly possible.
175
207
208 user_variables : list, optional
209
210 A list of variable names to pull from the user's namespace. They
211 will come back as a dict with these names as keys and their
212 :func:`repr` as values.
213
214 user_expressions : dict, optional
215 A dict with string keys and to pull from the user's
216 namespace. They will come back as a dict with these names as keys
217 and their :func:`repr` as values.
218
176 Returns
219 Returns
177 -------
220 -------
178 The msg_id of the message sent.
221 The msg_id of the message sent.
179 """
222 """
223 if user_variables is None:
224 user_variables = []
225 if user_expressions is None:
226 user_expressions = {}
227
228 # Don't waste network traffic if inputs are invalid
229 if not isinstance(code, basestring):
230 raise ValueError('code %r must be a string' % code)
231 validate_string_list(user_variables)
232 validate_string_dict(user_expressions)
233
180 # Create class for content/msg creation. Related to, but possibly
234 # Create class for content/msg creation. Related to, but possibly
181 # not in Session.
235 # not in Session.
182 content = dict(code=code, silent=silent)
236 content = dict(code=code, silent=silent,
237 user_variables=user_variables,
238 user_expressions=user_expressions)
183 msg = self.session.msg('execute_request', content)
239 msg = self.session.msg('execute_request', content)
184 self._queue_request(msg)
240 self._queue_request(msg)
185 return msg['header']['msg_id']
241 return msg['header']['msg_id']
186
242
187 def complete(self, text, line, cursor_pos, block=None):
243 def complete(self, text, line, cursor_pos, block=None):
188 """Tab complete text in the kernel's namespace.
244 """Tab complete text in the kernel's namespace.
189
245
190 Parameters
246 Parameters
191 ----------
247 ----------
192 text : str
248 text : str
193 The text to complete.
249 The text to complete.
194 line : str
250 line : str
195 The full line of text that is the surrounding context for the
251 The full line of text that is the surrounding context for the
196 text to complete.
252 text to complete.
197 cursor_pos : int
253 cursor_pos : int
198 The position of the cursor in the line where the completion was
254 The position of the cursor in the line where the completion was
199 requested.
255 requested.
200 block : str, optional
256 block : str, optional
201 The full block of code in which the completion is being requested.
257 The full block of code in which the completion is being requested.
202
258
203 Returns
259 Returns
204 -------
260 -------
205 The msg_id of the message sent.
261 The msg_id of the message sent.
206 """
262 """
207 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
263 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
208 msg = self.session.msg('complete_request', content)
264 msg = self.session.msg('complete_request', content)
209 self._queue_request(msg)
265 self._queue_request(msg)
210 return msg['header']['msg_id']
266 return msg['header']['msg_id']
211
267
212 def object_info(self, oname):
268 def object_info(self, oname):
213 """Get metadata information about an object.
269 """Get metadata information about an object.
214
270
215 Parameters
271 Parameters
216 ----------
272 ----------
217 oname : str
273 oname : str
218 A string specifying the object name.
274 A string specifying the object name.
219
275
220 Returns
276 Returns
221 -------
277 -------
222 The msg_id of the message sent.
278 The msg_id of the message sent.
223 """
279 """
224 content = dict(oname=oname)
280 content = dict(oname=oname)
225 msg = self.session.msg('object_info_request', content)
281 msg = self.session.msg('object_info_request', content)
226 self._queue_request(msg)
282 self._queue_request(msg)
227 return msg['header']['msg_id']
283 return msg['header']['msg_id']
228
284
229 def history(self, index=None, raw=False, output=True):
285 def history(self, index=None, raw=False, output=True):
230 """Get the history list.
286 """Get the history list.
231
287
232 Parameters
288 Parameters
233 ----------
289 ----------
234 index : n or (n1, n2) or None
290 index : n or (n1, n2) or None
235 If n, then the last entries. If a tuple, then all in
291 If n, then the last entries. If a tuple, then all in
236 range(n1, n2). If None, then all entries. Raises IndexError if
292 range(n1, n2). If None, then all entries. Raises IndexError if
237 the format of index is incorrect.
293 the format of index is incorrect.
238 raw : bool
294 raw : bool
239 If True, return the raw input.
295 If True, return the raw input.
240 output : bool
296 output : bool
241 If True, then return the output as well.
297 If True, then return the output as well.
242
298
243 Returns
299 Returns
244 -------
300 -------
245 The msg_id of the message sent.
301 The msg_id of the message sent.
246 """
302 """
247 content = dict(index=index, raw=raw, output=output)
303 content = dict(index=index, raw=raw, output=output)
248 msg = self.session.msg('history_request', content)
304 msg = self.session.msg('history_request', content)
249 self._queue_request(msg)
305 self._queue_request(msg)
250 return msg['header']['msg_id']
306 return msg['header']['msg_id']
251
307
252 def prompt(self):
253 """Requests a prompt number from the kernel.
254
255 Returns
256 -------
257 The msg_id of the message sent.
258 """
259 msg = self.session.msg('prompt_request')
260 self._queue_request(msg)
261 return msg['header']['msg_id']
262
263 def _handle_events(self, socket, events):
308 def _handle_events(self, socket, events):
264 if events & POLLERR:
309 if events & POLLERR:
265 self._handle_err()
310 self._handle_err()
266 if events & POLLOUT:
311 if events & POLLOUT:
267 self._handle_send()
312 self._handle_send()
268 if events & POLLIN:
313 if events & POLLIN:
269 self._handle_recv()
314 self._handle_recv()
270
315
271 def _handle_recv(self):
316 def _handle_recv(self):
272 msg = self.socket.recv_json()
317 msg = self.socket.recv_json()
273 self.call_handlers(msg)
318 self.call_handlers(msg)
274
319
275 def _handle_send(self):
320 def _handle_send(self):
276 try:
321 try:
277 msg = self.command_queue.get(False)
322 msg = self.command_queue.get(False)
278 except Empty:
323 except Empty:
279 pass
324 pass
280 else:
325 else:
281 self.socket.send_json(msg)
326 self.socket.send_json(msg)
282 if self.command_queue.empty():
327 if self.command_queue.empty():
283 self.drop_io_state(POLLOUT)
328 self.drop_io_state(POLLOUT)
284
329
285 def _handle_err(self):
330 def _handle_err(self):
286 # We don't want to let this go silently, so eventually we should log.
331 # We don't want to let this go silently, so eventually we should log.
287 raise zmq.ZMQError()
332 raise zmq.ZMQError()
288
333
289 def _queue_request(self, msg):
334 def _queue_request(self, msg):
290 self.command_queue.put(msg)
335 self.command_queue.put(msg)
291 self.add_io_state(POLLOUT)
336 self.add_io_state(POLLOUT)
292
337
293
338
294 class SubSocketChannel(ZmqSocketChannel):
339 class SubSocketChannel(ZmqSocketChannel):
295 """The SUB channel which listens for messages that the kernel publishes.
340 """The SUB channel which listens for messages that the kernel publishes.
296 """
341 """
297
342
298 def __init__(self, context, session, address):
343 def __init__(self, context, session, address):
299 super(SubSocketChannel, self).__init__(context, session, address)
344 super(SubSocketChannel, self).__init__(context, session, address)
300
345
301 def run(self):
346 def run(self):
302 """The thread's main activity. Call start() instead."""
347 """The thread's main activity. Call start() instead."""
303 self.socket = self.context.socket(zmq.SUB)
348 self.socket = self.context.socket(zmq.SUB)
304 self.socket.setsockopt(zmq.SUBSCRIBE,'')
349 self.socket.setsockopt(zmq.SUBSCRIBE,'')
305 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
350 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
306 self.socket.connect('tcp://%s:%i' % self.address)
351 self.socket.connect('tcp://%s:%i' % self.address)
307 self.ioloop = ioloop.IOLoop()
352 self.ioloop = ioloop.IOLoop()
308 self.iostate = POLLIN|POLLERR
353 self.iostate = POLLIN|POLLERR
309 self.ioloop.add_handler(self.socket, self._handle_events,
354 self.ioloop.add_handler(self.socket, self._handle_events,
310 self.iostate)
355 self.iostate)
311 self.ioloop.start()
356 self.ioloop.start()
312
357
313 def stop(self):
358 def stop(self):
314 self.ioloop.stop()
359 self.ioloop.stop()
315 super(SubSocketChannel, self).stop()
360 super(SubSocketChannel, self).stop()
316
361
317 def call_handlers(self, msg):
362 def call_handlers(self, msg):
318 """This method is called in the ioloop thread when a message arrives.
363 """This method is called in the ioloop thread when a message arrives.
319
364
320 Subclasses should override this method to handle incoming messages.
365 Subclasses should override this method to handle incoming messages.
321 It is important to remember that this method is called in the thread
366 It is important to remember that this method is called in the thread
322 so that some logic must be done to ensure that the application leve
367 so that some logic must be done to ensure that the application leve
323 handlers are called in the application thread.
368 handlers are called in the application thread.
324 """
369 """
325 raise NotImplementedError('call_handlers must be defined in a subclass.')
370 raise NotImplementedError('call_handlers must be defined in a subclass.')
326
371
327 def flush(self, timeout=1.0):
372 def flush(self, timeout=1.0):
328 """Immediately processes all pending messages on the SUB channel.
373 """Immediately processes all pending messages on the SUB channel.
329
374
330 Callers should use this method to ensure that :method:`call_handlers`
375 Callers should use this method to ensure that :method:`call_handlers`
331 has been called for all messages that have been received on the
376 has been called for all messages that have been received on the
332 0MQ SUB socket of this channel.
377 0MQ SUB socket of this channel.
333
378
334 This method is thread safe.
379 This method is thread safe.
335
380
336 Parameters
381 Parameters
337 ----------
382 ----------
338 timeout : float, optional
383 timeout : float, optional
339 The maximum amount of time to spend flushing, in seconds. The
384 The maximum amount of time to spend flushing, in seconds. The
340 default is one second.
385 default is one second.
341 """
386 """
342 # We do the IOLoop callback process twice to ensure that the IOLoop
387 # We do the IOLoop callback process twice to ensure that the IOLoop
343 # gets to perform at least one full poll.
388 # gets to perform at least one full poll.
344 stop_time = time.time() + timeout
389 stop_time = time.time() + timeout
345 for i in xrange(2):
390 for i in xrange(2):
346 self._flushed = False
391 self._flushed = False
347 self.ioloop.add_callback(self._flush)
392 self.ioloop.add_callback(self._flush)
348 while not self._flushed and time.time() < stop_time:
393 while not self._flushed and time.time() < stop_time:
349 time.sleep(0.01)
394 time.sleep(0.01)
350
395
351 def _handle_events(self, socket, events):
396 def _handle_events(self, socket, events):
352 # Turn on and off POLLOUT depending on if we have made a request
397 # Turn on and off POLLOUT depending on if we have made a request
353 if events & POLLERR:
398 if events & POLLERR:
354 self._handle_err()
399 self._handle_err()
355 if events & POLLIN:
400 if events & POLLIN:
356 self._handle_recv()
401 self._handle_recv()
357
402
358 def _handle_err(self):
403 def _handle_err(self):
359 # We don't want to let this go silently, so eventually we should log.
404 # We don't want to let this go silently, so eventually we should log.
360 raise zmq.ZMQError()
405 raise zmq.ZMQError()
361
406
362 def _handle_recv(self):
407 def _handle_recv(self):
363 # Get all of the messages we can
408 # Get all of the messages we can
364 while True:
409 while True:
365 try:
410 try:
366 msg = self.socket.recv_json(zmq.NOBLOCK)
411 msg = self.socket.recv_json(zmq.NOBLOCK)
367 except zmq.ZMQError:
412 except zmq.ZMQError:
368 # Check the errno?
413 # Check the errno?
369 # Will this trigger POLLERR?
414 # Will this trigger POLLERR?
370 break
415 break
371 else:
416 else:
372 self.call_handlers(msg)
417 self.call_handlers(msg)
373
418
374 def _flush(self):
419 def _flush(self):
375 """Callback for :method:`self.flush`."""
420 """Callback for :method:`self.flush`."""
376 self._flushed = True
421 self._flushed = True
377
422
378
423
379 class RepSocketChannel(ZmqSocketChannel):
424 class RepSocketChannel(ZmqSocketChannel):
380 """A reply channel to handle raw_input requests that the kernel makes."""
425 """A reply channel to handle raw_input requests that the kernel makes."""
381
426
382 msg_queue = None
427 msg_queue = None
383
428
384 def __init__(self, context, session, address):
429 def __init__(self, context, session, address):
385 self.msg_queue = Queue()
430 self.msg_queue = Queue()
386 super(RepSocketChannel, self).__init__(context, session, address)
431 super(RepSocketChannel, self).__init__(context, session, address)
387
432
388 def run(self):
433 def run(self):
389 """The thread's main activity. Call start() instead."""
434 """The thread's main activity. Call start() instead."""
390 self.socket = self.context.socket(zmq.XREQ)
435 self.socket = self.context.socket(zmq.XREQ)
391 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
436 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
392 self.socket.connect('tcp://%s:%i' % self.address)
437 self.socket.connect('tcp://%s:%i' % self.address)
393 self.ioloop = ioloop.IOLoop()
438 self.ioloop = ioloop.IOLoop()
394 self.iostate = POLLERR|POLLIN
439 self.iostate = POLLERR|POLLIN
395 self.ioloop.add_handler(self.socket, self._handle_events,
440 self.ioloop.add_handler(self.socket, self._handle_events,
396 self.iostate)
441 self.iostate)
397 self.ioloop.start()
442 self.ioloop.start()
398
443
399 def stop(self):
444 def stop(self):
400 self.ioloop.stop()
445 self.ioloop.stop()
401 super(RepSocketChannel, self).stop()
446 super(RepSocketChannel, self).stop()
402
447
403 def call_handlers(self, msg):
448 def call_handlers(self, msg):
404 """This method is called in the ioloop thread when a message arrives.
449 """This method is called in the ioloop thread when a message arrives.
405
450
406 Subclasses should override this method to handle incoming messages.
451 Subclasses should override this method to handle incoming messages.
407 It is important to remember that this method is called in the thread
452 It is important to remember that this method is called in the thread
408 so that some logic must be done to ensure that the application leve
453 so that some logic must be done to ensure that the application leve
409 handlers are called in the application thread.
454 handlers are called in the application thread.
410 """
455 """
411 raise NotImplementedError('call_handlers must be defined in a subclass.')
456 raise NotImplementedError('call_handlers must be defined in a subclass.')
412
457
413 def input(self, string):
458 def input(self, string):
414 """Send a string of raw input to the kernel."""
459 """Send a string of raw input to the kernel."""
415 content = dict(value=string)
460 content = dict(value=string)
416 msg = self.session.msg('input_reply', content)
461 msg = self.session.msg('input_reply', content)
417 self._queue_reply(msg)
462 self._queue_reply(msg)
418
463
419 def _handle_events(self, socket, events):
464 def _handle_events(self, socket, events):
420 if events & POLLERR:
465 if events & POLLERR:
421 self._handle_err()
466 self._handle_err()
422 if events & POLLOUT:
467 if events & POLLOUT:
423 self._handle_send()
468 self._handle_send()
424 if events & POLLIN:
469 if events & POLLIN:
425 self._handle_recv()
470 self._handle_recv()
426
471
427 def _handle_recv(self):
472 def _handle_recv(self):
428 msg = self.socket.recv_json()
473 msg = self.socket.recv_json()
429 self.call_handlers(msg)
474 self.call_handlers(msg)
430
475
431 def _handle_send(self):
476 def _handle_send(self):
432 try:
477 try:
433 msg = self.msg_queue.get(False)
478 msg = self.msg_queue.get(False)
434 except Empty:
479 except Empty:
435 pass
480 pass
436 else:
481 else:
437 self.socket.send_json(msg)
482 self.socket.send_json(msg)
438 if self.msg_queue.empty():
483 if self.msg_queue.empty():
439 self.drop_io_state(POLLOUT)
484 self.drop_io_state(POLLOUT)
440
485
441 def _handle_err(self):
486 def _handle_err(self):
442 # We don't want to let this go silently, so eventually we should log.
487 # We don't want to let this go silently, so eventually we should log.
443 raise zmq.ZMQError()
488 raise zmq.ZMQError()
444
489
445 def _queue_reply(self, msg):
490 def _queue_reply(self, msg):
446 self.msg_queue.put(msg)
491 self.msg_queue.put(msg)
447 self.add_io_state(POLLOUT)
492 self.add_io_state(POLLOUT)
448
493
449
494
450 class HBSocketChannel(ZmqSocketChannel):
495 class HBSocketChannel(ZmqSocketChannel):
451 """The heartbeat channel which monitors the kernel heartbeat."""
496 """The heartbeat channel which monitors the kernel heartbeat."""
452
497
453 time_to_dead = 3.0
498 time_to_dead = 3.0
454 socket = None
499 socket = None
455 poller = None
500 poller = None
456
501
457 def __init__(self, context, session, address):
502 def __init__(self, context, session, address):
458 super(HBSocketChannel, self).__init__(context, session, address)
503 super(HBSocketChannel, self).__init__(context, session, address)
459 self._running = False
504 self._running = False
460
505
461 def _create_socket(self):
506 def _create_socket(self):
462 self.socket = self.context.socket(zmq.REQ)
507 self.socket = self.context.socket(zmq.REQ)
463 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
508 self.socket.setsockopt(zmq.IDENTITY, self.session.session)
464 self.socket.connect('tcp://%s:%i' % self.address)
509 self.socket.connect('tcp://%s:%i' % self.address)
465 self.poller = zmq.Poller()
510 self.poller = zmq.Poller()
466 self.poller.register(self.socket, zmq.POLLIN)
511 self.poller.register(self.socket, zmq.POLLIN)
467
512
468 def run(self):
513 def run(self):
469 """The thread's main activity. Call start() instead."""
514 """The thread's main activity. Call start() instead."""
470 self._create_socket()
515 self._create_socket()
471 self._running = True
516 self._running = True
472 # Wait 2 seconds for the kernel to come up and the sockets to auto
517 # Wait 2 seconds for the kernel to come up and the sockets to auto
473 # connect. If we don't we will see the kernel as dead. Also, before
518 # connect. If we don't we will see the kernel as dead. Also, before
474 # the sockets are connected, the poller.poll line below is returning
519 # the sockets are connected, the poller.poll line below is returning
475 # too fast. This avoids that because the polling doesn't start until
520 # too fast. This avoids that because the polling doesn't start until
476 # after the sockets are connected.
521 # after the sockets are connected.
477 time.sleep(2.0)
522 time.sleep(2.0)
478 while self._running:
523 while self._running:
479 since_last_heartbeat = 0.0
524 since_last_heartbeat = 0.0
480 request_time = time.time()
525 request_time = time.time()
481 try:
526 try:
527 #io.rprint('Ping from HB channel') # dbg
482 self.socket.send_json('ping')
528 self.socket.send_json('ping')
483 except zmq.ZMQError, e:
529 except zmq.ZMQError, e:
530 #io.rprint('*** HB Error:', e) # dbg
484 if e.errno == zmq.EFSM:
531 if e.errno == zmq.EFSM:
532 #io.rprint('sleep...', self.time_to_dead) # dbg
485 time.sleep(self.time_to_dead)
533 time.sleep(self.time_to_dead)
486 self._create_socket()
534 self._create_socket()
487 else:
535 else:
488 raise
536 raise
489 else:
537 else:
490 while True:
538 while True:
491 try:
539 try:
492 reply = self.socket.recv_json(zmq.NOBLOCK)
540 self.socket.recv_json(zmq.NOBLOCK)
493 except zmq.ZMQError, e:
541 except zmq.ZMQError, e:
542 #io.rprint('*** HB Error 2:', e) # dbg
494 if e.errno == zmq.EAGAIN:
543 if e.errno == zmq.EAGAIN:
495 until_dead = self.time_to_dead - (time.time() -
544 before_poll = time.time()
545 until_dead = self.time_to_dead - (before_poll -
496 request_time)
546 request_time)
497 # poll timeout is in milliseconds.
547
498 poll_result = self.poller.poll(1000*until_dead)
548 # When the return value of poll() is an empty list,
549 # that is when things have gone wrong (zeromq bug).
550 # As long as it is not an empty list, poll is
551 # working correctly even if it returns quickly.
552 # Note: poll timeout is in milliseconds.
553 self.poller.poll(1000*until_dead)
554
499 since_last_heartbeat = time.time() - request_time
555 since_last_heartbeat = time.time() - request_time
500 if since_last_heartbeat > self.time_to_dead:
556 if since_last_heartbeat > self.time_to_dead:
501 self.call_handlers(since_last_heartbeat)
557 self.call_handlers(since_last_heartbeat)
502 break
558 break
503 else:
559 else:
504 # FIXME: We should probably log this instead.
560 # FIXME: We should probably log this instead.
505 raise
561 raise
506 else:
562 else:
507 until_dead = self.time_to_dead - (time.time() -
563 until_dead = self.time_to_dead - (time.time() -
508 request_time)
564 request_time)
509 if until_dead > 0.0:
565 if until_dead > 0.0:
566 #io.rprint('sleep...', self.time_to_dead) # dbg
510 time.sleep(until_dead)
567 time.sleep(until_dead)
511 break
568 break
512
569
513 def stop(self):
570 def stop(self):
514 self._running = False
571 self._running = False
515 super(HBSocketChannel, self).stop()
572 super(HBSocketChannel, self).stop()
516
573
517 def call_handlers(self, since_last_heartbeat):
574 def call_handlers(self, since_last_heartbeat):
518 """This method is called in the ioloop thread when a message arrives.
575 """This method is called in the ioloop thread when a message arrives.
519
576
520 Subclasses should override this method to handle incoming messages.
577 Subclasses should override this method to handle incoming messages.
521 It is important to remember that this method is called in the thread
578 It is important to remember that this method is called in the thread
522 so that some logic must be done to ensure that the application leve
579 so that some logic must be done to ensure that the application leve
523 handlers are called in the application thread.
580 handlers are called in the application thread.
524 """
581 """
525 raise NotImplementedError('call_handlers must be defined in a subclass.')
582 raise NotImplementedError('call_handlers must be defined in a subclass.')
526
583
527
584
528 #-----------------------------------------------------------------------------
585 #-----------------------------------------------------------------------------
529 # Main kernel manager class
586 # Main kernel manager class
530 #-----------------------------------------------------------------------------
587 #-----------------------------------------------------------------------------
531
588
532 class KernelManager(HasTraits):
589 class KernelManager(HasTraits):
533 """ Manages a kernel for a frontend.
590 """ Manages a kernel for a frontend.
534
591
535 The SUB channel is for the frontend to receive messages published by the
592 The SUB channel is for the frontend to receive messages published by the
536 kernel.
593 kernel.
537
594
538 The REQ channel is for the frontend to make requests of the kernel.
595 The REQ channel is for the frontend to make requests of the kernel.
539
596
540 The REP channel is for the kernel to request stdin (raw_input) from the
597 The REP channel is for the kernel to request stdin (raw_input) from the
541 frontend.
598 frontend.
542 """
599 """
543 # The PyZMQ Context to use for communication with the kernel.
600 # The PyZMQ Context to use for communication with the kernel.
544 context = Instance(zmq.Context,(),{})
601 context = Instance(zmq.Context,(),{})
545
602
546 # The Session to use for communication with the kernel.
603 # The Session to use for communication with the kernel.
547 session = Instance(Session,(),{})
604 session = Instance(Session,(),{})
548
605
549 # The kernel process with which the KernelManager is communicating.
606 # The kernel process with which the KernelManager is communicating.
550 kernel = Instance(Popen)
607 kernel = Instance(Popen)
551
608
552 # The addresses for the communication channels.
609 # The addresses for the communication channels.
553 xreq_address = TCPAddress((LOCALHOST, 0))
610 xreq_address = TCPAddress((LOCALHOST, 0))
554 sub_address = TCPAddress((LOCALHOST, 0))
611 sub_address = TCPAddress((LOCALHOST, 0))
555 rep_address = TCPAddress((LOCALHOST, 0))
612 rep_address = TCPAddress((LOCALHOST, 0))
556 hb_address = TCPAddress((LOCALHOST, 0))
613 hb_address = TCPAddress((LOCALHOST, 0))
557
614
558 # The classes to use for the various channels.
615 # The classes to use for the various channels.
559 xreq_channel_class = Type(XReqSocketChannel)
616 xreq_channel_class = Type(XReqSocketChannel)
560 sub_channel_class = Type(SubSocketChannel)
617 sub_channel_class = Type(SubSocketChannel)
561 rep_channel_class = Type(RepSocketChannel)
618 rep_channel_class = Type(RepSocketChannel)
562 hb_channel_class = Type(HBSocketChannel)
619 hb_channel_class = Type(HBSocketChannel)
563
620
564 # Protected traits.
621 # Protected traits.
565 _launch_args = Any
622 _launch_args = Any
566 _xreq_channel = Any
623 _xreq_channel = Any
567 _sub_channel = Any
624 _sub_channel = Any
568 _rep_channel = Any
625 _rep_channel = Any
569 _hb_channel = Any
626 _hb_channel = Any
570
627
571 #--------------------------------------------------------------------------
628 #--------------------------------------------------------------------------
572 # Channel management methods:
629 # Channel management methods:
573 #--------------------------------------------------------------------------
630 #--------------------------------------------------------------------------
574
631
575 def start_channels(self):
632 def start_channels(self):
576 """Starts the channels for this kernel.
633 """Starts the channels for this kernel.
577
634
578 This will create the channels if they do not exist and then start
635 This will create the channels if they do not exist and then start
579 them. If port numbers of 0 are being used (random ports) then you
636 them. If port numbers of 0 are being used (random ports) then you
580 must first call :method:`start_kernel`. If the channels have been
637 must first call :method:`start_kernel`. If the channels have been
581 stopped and you call this, :class:`RuntimeError` will be raised.
638 stopped and you call this, :class:`RuntimeError` will be raised.
582 """
639 """
583 self.xreq_channel.start()
640 self.xreq_channel.start()
584 self.sub_channel.start()
641 self.sub_channel.start()
585 self.rep_channel.start()
642 self.rep_channel.start()
586 self.hb_channel.start()
643 self.hb_channel.start()
587
644
588 def stop_channels(self):
645 def stop_channels(self):
589 """Stops the channels for this kernel.
646 """Stops the channels for this kernel.
590
647
591 This stops the channels by joining their threads. If the channels
648 This stops the channels by joining their threads. If the channels
592 were not started, :class:`RuntimeError` will be raised.
649 were not started, :class:`RuntimeError` will be raised.
593 """
650 """
594 self.xreq_channel.stop()
651 self.xreq_channel.stop()
595 self.sub_channel.stop()
652 self.sub_channel.stop()
596 self.rep_channel.stop()
653 self.rep_channel.stop()
597 self.hb_channel.stop()
654 self.hb_channel.stop()
598
655
599 @property
656 @property
600 def channels_running(self):
657 def channels_running(self):
601 """Are all of the channels created and running?"""
658 """Are all of the channels created and running?"""
602 return self.xreq_channel.is_alive() \
659 return self.xreq_channel.is_alive() \
603 and self.sub_channel.is_alive() \
660 and self.sub_channel.is_alive() \
604 and self.rep_channel.is_alive() \
661 and self.rep_channel.is_alive() \
605 and self.hb_channel.is_alive()
662 and self.hb_channel.is_alive()
606
663
607 #--------------------------------------------------------------------------
664 #--------------------------------------------------------------------------
608 # Kernel process management methods:
665 # Kernel process management methods:
609 #--------------------------------------------------------------------------
666 #--------------------------------------------------------------------------
610
667
611 def start_kernel(self, **kw):
668 def start_kernel(self, **kw):
612 """Starts a kernel process and configures the manager to use it.
669 """Starts a kernel process and configures the manager to use it.
613
670
614 If random ports (port=0) are being used, this method must be called
671 If random ports (port=0) are being used, this method must be called
615 before the channels are created.
672 before the channels are created.
616
673
617 Parameters:
674 Parameters:
618 -----------
675 -----------
619 ipython : bool, optional (default True)
676 ipython : bool, optional (default True)
620 Whether to use an IPython kernel instead of a plain Python kernel.
677 Whether to use an IPython kernel instead of a plain Python kernel.
621 """
678 """
622 xreq, sub, rep, hb = self.xreq_address, self.sub_address, \
679 xreq, sub, rep, hb = self.xreq_address, self.sub_address, \
623 self.rep_address, self.hb_address
680 self.rep_address, self.hb_address
624 if xreq[0] != LOCALHOST or sub[0] != LOCALHOST or \
681 if xreq[0] != LOCALHOST or sub[0] != LOCALHOST or \
625 rep[0] != LOCALHOST or hb[0] != LOCALHOST:
682 rep[0] != LOCALHOST or hb[0] != LOCALHOST:
626 raise RuntimeError("Can only launch a kernel on localhost."
683 raise RuntimeError("Can only launch a kernel on localhost."
627 "Make sure that the '*_address' attributes are "
684 "Make sure that the '*_address' attributes are "
628 "configured properly.")
685 "configured properly.")
629
686
630 self._launch_args = kw.copy()
687 self._launch_args = kw.copy()
631 if kw.pop('ipython', True):
688 if kw.pop('ipython', True):
632 from ipkernel import launch_kernel as launch
689 from ipkernel import launch_kernel as launch
633 else:
690 else:
634 from pykernel import launch_kernel as launch
691 from pykernel import launch_kernel as launch
635 self.kernel, xrep, pub, req, hb = launch(
692 self.kernel, xrep, pub, req, hb = launch(
636 xrep_port=xreq[1], pub_port=sub[1],
693 xrep_port=xreq[1], pub_port=sub[1],
637 req_port=rep[1], hb_port=hb[1], **kw)
694 req_port=rep[1], hb_port=hb[1], **kw)
638 self.xreq_address = (LOCALHOST, xrep)
695 self.xreq_address = (LOCALHOST, xrep)
639 self.sub_address = (LOCALHOST, pub)
696 self.sub_address = (LOCALHOST, pub)
640 self.rep_address = (LOCALHOST, req)
697 self.rep_address = (LOCALHOST, req)
641 self.hb_address = (LOCALHOST, hb)
698 self.hb_address = (LOCALHOST, hb)
642
699
643 def restart_kernel(self):
700 def restart_kernel(self):
644 """Restarts a kernel with the same arguments that were used to launch
701 """Restarts a kernel with the same arguments that were used to launch
645 it. If the old kernel was launched with random ports, the same ports
702 it. If the old kernel was launched with random ports, the same ports
646 will be used for the new kernel.
703 will be used for the new kernel.
647 """
704 """
648 if self._launch_args is None:
705 if self._launch_args is None:
649 raise RuntimeError("Cannot restart the kernel. "
706 raise RuntimeError("Cannot restart the kernel. "
650 "No previous call to 'start_kernel'.")
707 "No previous call to 'start_kernel'.")
651 else:
708 else:
652 if self.has_kernel:
709 if self.has_kernel:
653 self.kill_kernel()
710 self.kill_kernel()
654 self.start_kernel(**self._launch_args)
711 self.start_kernel(**self._launch_args)
655
712
656 @property
713 @property
657 def has_kernel(self):
714 def has_kernel(self):
658 """Returns whether a kernel process has been specified for the kernel
715 """Returns whether a kernel process has been specified for the kernel
659 manager.
716 manager.
660 """
717 """
661 return self.kernel is not None
718 return self.kernel is not None
662
719
663 def kill_kernel(self):
720 def kill_kernel(self):
664 """ Kill the running kernel. """
721 """ Kill the running kernel. """
665 if self.kernel is not None:
722 if self.kernel is not None:
666 self.kernel.kill()
723 self.kernel.kill()
667 self.kernel = None
724 self.kernel = None
668 else:
725 else:
669 raise RuntimeError("Cannot kill kernel. No kernel is running!")
726 raise RuntimeError("Cannot kill kernel. No kernel is running!")
670
727
671 def signal_kernel(self, signum):
728 def signal_kernel(self, signum):
672 """ Sends a signal to the kernel. """
729 """ Sends a signal to the kernel. """
673 if self.kernel is not None:
730 if self.kernel is not None:
674 self.kernel.send_signal(signum)
731 self.kernel.send_signal(signum)
675 else:
732 else:
676 raise RuntimeError("Cannot signal kernel. No kernel is running!")
733 raise RuntimeError("Cannot signal kernel. No kernel is running!")
677
734
678 @property
735 @property
679 def is_alive(self):
736 def is_alive(self):
680 """Is the kernel process still running?"""
737 """Is the kernel process still running?"""
681 if self.kernel is not None:
738 if self.kernel is not None:
682 if self.kernel.poll() is None:
739 if self.kernel.poll() is None:
683 return True
740 return True
684 else:
741 else:
685 return False
742 return False
686 else:
743 else:
687 # We didn't start the kernel with this KernelManager so we don't
744 # We didn't start the kernel with this KernelManager so we don't
688 # know if it is running. We should use a heartbeat for this case.
745 # know if it is running. We should use a heartbeat for this case.
689 return True
746 return True
690
747
691 #--------------------------------------------------------------------------
748 #--------------------------------------------------------------------------
692 # Channels used for communication with the kernel:
749 # Channels used for communication with the kernel:
693 #--------------------------------------------------------------------------
750 #--------------------------------------------------------------------------
694
751
695 @property
752 @property
696 def xreq_channel(self):
753 def xreq_channel(self):
697 """Get the REQ socket channel object to make requests of the kernel."""
754 """Get the REQ socket channel object to make requests of the kernel."""
698 if self._xreq_channel is None:
755 if self._xreq_channel is None:
699 self._xreq_channel = self.xreq_channel_class(self.context,
756 self._xreq_channel = self.xreq_channel_class(self.context,
700 self.session,
757 self.session,
701 self.xreq_address)
758 self.xreq_address)
702 return self._xreq_channel
759 return self._xreq_channel
703
760
704 @property
761 @property
705 def sub_channel(self):
762 def sub_channel(self):
706 """Get the SUB socket channel object."""
763 """Get the SUB socket channel object."""
707 if self._sub_channel is None:
764 if self._sub_channel is None:
708 self._sub_channel = self.sub_channel_class(self.context,
765 self._sub_channel = self.sub_channel_class(self.context,
709 self.session,
766 self.session,
710 self.sub_address)
767 self.sub_address)
711 return self._sub_channel
768 return self._sub_channel
712
769
713 @property
770 @property
714 def rep_channel(self):
771 def rep_channel(self):
715 """Get the REP socket channel object to handle stdin (raw_input)."""
772 """Get the REP socket channel object to handle stdin (raw_input)."""
716 if self._rep_channel is None:
773 if self._rep_channel is None:
717 self._rep_channel = self.rep_channel_class(self.context,
774 self._rep_channel = self.rep_channel_class(self.context,
718 self.session,
775 self.session,
719 self.rep_address)
776 self.rep_address)
720 return self._rep_channel
777 return self._rep_channel
721
778
722 @property
779 @property
723 def hb_channel(self):
780 def hb_channel(self):
724 """Get the REP socket channel object to handle stdin (raw_input)."""
781 """Get the REP socket channel object to handle stdin (raw_input)."""
725 if self._hb_channel is None:
782 if self._hb_channel is None:
726 self._hb_channel = self.hb_channel_class(self.context,
783 self._hb_channel = self.hb_channel_class(self.context,
727 self.session,
784 self.session,
728 self.hb_address)
785 self.hb_address)
729 return self._hb_channel
786 return self._hb_channel
@@ -1,409 +1,408 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.displayhook import DisplayHook
27 from IPython.core.displayhook import DisplayHook
28 from IPython.core.macro import Macro
28 from IPython.core.macro import Macro
29 from IPython.utils.path import get_py_filename
29 from IPython.utils.path import get_py_filename
30 from IPython.utils.text import StringTypes
30 from IPython.utils.text import StringTypes
31 from IPython.utils.traitlets import Instance, Type, Dict
31 from IPython.utils.traitlets import Instance, Type, Dict
32 from IPython.utils.warn import warn
32 from IPython.utils.warn import warn
33 from IPython.zmq.session import extract_header
33 from IPython.zmq.session import extract_header
34 from IPython.core.payloadpage import install_payload_page
34 from IPython.core.payloadpage import install_payload_page
35 from session import Session
35 from session import Session
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Globals and side-effects
38 # Globals and side-effects
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40
40
41 # Install the payload version of page.
41 # Install the payload version of page.
42 install_payload_page()
42 install_payload_page()
43
43
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # Functions and classes
45 # Functions and classes
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47
47
48 class ZMQDisplayHook(DisplayHook):
48 class ZMQDisplayHook(DisplayHook):
49
49
50 session = Instance(Session)
50 session = Instance(Session)
51 pub_socket = Instance('zmq.Socket')
51 pub_socket = Instance('zmq.Socket')
52 parent_header = Dict({})
52 parent_header = Dict({})
53
53
54 def set_parent(self, parent):
54 def set_parent(self, parent):
55 """Set the parent for outbound messages."""
55 """Set the parent for outbound messages."""
56 self.parent_header = extract_header(parent)
56 self.parent_header = extract_header(parent)
57
57
58 def start_displayhook(self):
58 def start_displayhook(self):
59 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
59 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
60
60
61 def write_output_prompt(self):
61 def write_output_prompt(self):
62 """Write the output prompt."""
62 """Write the output prompt."""
63 if self.do_full_cache:
63 if self.do_full_cache:
64 self.msg['content']['output_sep'] = self.output_sep
64 self.msg['content']['execution_count'] = self.prompt_count
65 self.msg['content']['prompt_string'] = str(self.prompt_out)
66 self.msg['content']['prompt_number'] = self.prompt_count
67 self.msg['content']['output_sep2'] = self.output_sep2
68
65
69 def write_result_repr(self, result_repr):
66 def write_result_repr(self, result_repr):
70 self.msg['content']['data'] = result_repr
67 self.msg['content']['data'] = result_repr
71
68
72 def finish_displayhook(self):
69 def finish_displayhook(self):
73 """Finish up all displayhook activities."""
70 """Finish up all displayhook activities."""
74 self.pub_socket.send_json(self.msg)
71 self.pub_socket.send_json(self.msg)
75 self.msg = None
72 self.msg = None
76
73
77
74
78 class ZMQInteractiveShell(InteractiveShell):
75 class ZMQInteractiveShell(InteractiveShell):
79 """A subclass of InteractiveShell for ZMQ."""
76 """A subclass of InteractiveShell for ZMQ."""
80
77
81 displayhook_class = Type(ZMQDisplayHook)
78 displayhook_class = Type(ZMQDisplayHook)
82
79
83 def init_io(self):
80 def init_io(self):
84 # This will just use sys.stdout and sys.stderr. If you want to
81 # This will just use sys.stdout and sys.stderr. If you want to
85 # override sys.stdout and sys.stderr themselves, you need to do that
82 # override sys.stdout and sys.stderr themselves, you need to do that
86 # *before* instantiating this class, because Term holds onto
83 # *before* instantiating this class, because Term holds onto
87 # references to the underlying streams.
84 # references to the underlying streams.
88 import IPython.utils.io
85 import IPython.utils.io
89 Term = IPython.utils.io.IOTerm()
86 Term = IPython.utils.io.IOTerm()
90 IPython.utils.io.Term = Term
87 IPython.utils.io.Term = Term
91
88
92 def magic_edit(self,parameter_s='',last_call=['','']):
89 def magic_edit(self,parameter_s='',last_call=['','']):
93 """Bring up an editor and execute the resulting code.
90 """Bring up an editor and execute the resulting code.
94
91
95 Usage:
92 Usage:
96 %edit [options] [args]
93 %edit [options] [args]
97
94
98 %edit runs IPython's editor hook. The default version of this hook is
95 %edit runs IPython's editor hook. The default version of this hook is
99 set to call the __IPYTHON__.rc.editor command. This is read from your
96 set to call the __IPYTHON__.rc.editor command. This is read from your
100 environment variable $EDITOR. If this isn't found, it will default to
97 environment variable $EDITOR. If this isn't found, it will default to
101 vi under Linux/Unix and to notepad under Windows. See the end of this
98 vi under Linux/Unix and to notepad under Windows. See the end of this
102 docstring for how to change the editor hook.
99 docstring for how to change the editor hook.
103
100
104 You can also set the value of this editor via the command line option
101 You can also set the value of this editor via the command line option
105 '-editor' or in your ipythonrc file. This is useful if you wish to use
102 '-editor' or in your ipythonrc file. This is useful if you wish to use
106 specifically for IPython an editor different from your typical default
103 specifically for IPython an editor different from your typical default
107 (and for Windows users who typically don't set environment variables).
104 (and for Windows users who typically don't set environment variables).
108
105
109 This command allows you to conveniently edit multi-line code right in
106 This command allows you to conveniently edit multi-line code right in
110 your IPython session.
107 your IPython session.
111
108
112 If called without arguments, %edit opens up an empty editor with a
109 If called without arguments, %edit opens up an empty editor with a
113 temporary file and will execute the contents of this file when you
110 temporary file and will execute the contents of this file when you
114 close it (don't forget to save it!).
111 close it (don't forget to save it!).
115
112
116
113
117 Options:
114 Options:
118
115
119 -n <number>: open the editor at a specified line number. By default,
116 -n <number>: open the editor at a specified line number. By default,
120 the IPython editor hook uses the unix syntax 'editor +N filename', but
117 the IPython editor hook uses the unix syntax 'editor +N filename', but
121 you can configure this by providing your own modified hook if your
118 you can configure this by providing your own modified hook if your
122 favorite editor supports line-number specifications with a different
119 favorite editor supports line-number specifications with a different
123 syntax.
120 syntax.
124
121
125 -p: this will call the editor with the same data as the previous time
122 -p: this will call the editor with the same data as the previous time
126 it was used, regardless of how long ago (in your current session) it
123 it was used, regardless of how long ago (in your current session) it
127 was.
124 was.
128
125
129 -r: use 'raw' input. This option only applies to input taken from the
126 -r: use 'raw' input. This option only applies to input taken from the
130 user's history. By default, the 'processed' history is used, so that
127 user's history. By default, the 'processed' history is used, so that
131 magics are loaded in their transformed version to valid Python. If
128 magics are loaded in their transformed version to valid Python. If
132 this option is given, the raw input as typed as the command line is
129 this option is given, the raw input as typed as the command line is
133 used instead. When you exit the editor, it will be executed by
130 used instead. When you exit the editor, it will be executed by
134 IPython's own processor.
131 IPython's own processor.
135
132
136 -x: do not execute the edited code immediately upon exit. This is
133 -x: do not execute the edited code immediately upon exit. This is
137 mainly useful if you are editing programs which need to be called with
134 mainly useful if you are editing programs which need to be called with
138 command line arguments, which you can then do using %run.
135 command line arguments, which you can then do using %run.
139
136
140
137
141 Arguments:
138 Arguments:
142
139
143 If arguments are given, the following possibilites exist:
140 If arguments are given, the following possibilites exist:
144
141
145 - The arguments are numbers or pairs of colon-separated numbers (like
142 - The arguments are numbers or pairs of colon-separated numbers (like
146 1 4:8 9). These are interpreted as lines of previous input to be
143 1 4:8 9). These are interpreted as lines of previous input to be
147 loaded into the editor. The syntax is the same of the %macro command.
144 loaded into the editor. The syntax is the same of the %macro command.
148
145
149 - If the argument doesn't start with a number, it is evaluated as a
146 - If the argument doesn't start with a number, it is evaluated as a
150 variable and its contents loaded into the editor. You can thus edit
147 variable and its contents loaded into the editor. You can thus edit
151 any string which contains python code (including the result of
148 any string which contains python code (including the result of
152 previous edits).
149 previous edits).
153
150
154 - If the argument is the name of an object (other than a string),
151 - If the argument is the name of an object (other than a string),
155 IPython will try to locate the file where it was defined and open the
152 IPython will try to locate the file where it was defined and open the
156 editor at the point where it is defined. You can use `%edit function`
153 editor at the point where it is defined. You can use `%edit function`
157 to load an editor exactly at the point where 'function' is defined,
154 to load an editor exactly at the point where 'function' is defined,
158 edit it and have the file be executed automatically.
155 edit it and have the file be executed automatically.
159
156
160 If the object is a macro (see %macro for details), this opens up your
157 If the object is a macro (see %macro for details), this opens up your
161 specified editor with a temporary file containing the macro's data.
158 specified editor with a temporary file containing the macro's data.
162 Upon exit, the macro is reloaded with the contents of the file.
159 Upon exit, the macro is reloaded with the contents of the file.
163
160
164 Note: opening at an exact line is only supported under Unix, and some
161 Note: opening at an exact line is only supported under Unix, and some
165 editors (like kedit and gedit up to Gnome 2.8) do not understand the
162 editors (like kedit and gedit up to Gnome 2.8) do not understand the
166 '+NUMBER' parameter necessary for this feature. Good editors like
163 '+NUMBER' parameter necessary for this feature. Good editors like
167 (X)Emacs, vi, jed, pico and joe all do.
164 (X)Emacs, vi, jed, pico and joe all do.
168
165
169 - If the argument is not found as a variable, IPython will look for a
166 - If the argument is not found as a variable, IPython will look for a
170 file with that name (adding .py if necessary) and load it into the
167 file with that name (adding .py if necessary) and load it into the
171 editor. It will execute its contents with execfile() when you exit,
168 editor. It will execute its contents with execfile() when you exit,
172 loading any code in the file into your interactive namespace.
169 loading any code in the file into your interactive namespace.
173
170
174 After executing your code, %edit will return as output the code you
171 After executing your code, %edit will return as output the code you
175 typed in the editor (except when it was an existing file). This way
172 typed in the editor (except when it was an existing file). This way
176 you can reload the code in further invocations of %edit as a variable,
173 you can reload the code in further invocations of %edit as a variable,
177 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
174 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
178 the output.
175 the output.
179
176
180 Note that %edit is also available through the alias %ed.
177 Note that %edit is also available through the alias %ed.
181
178
182 This is an example of creating a simple function inside the editor and
179 This is an example of creating a simple function inside the editor and
183 then modifying it. First, start up the editor:
180 then modifying it. First, start up the editor:
184
181
185 In [1]: ed
182 In [1]: ed
186 Editing... done. Executing edited code...
183 Editing... done. Executing edited code...
187 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
184 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
188
185
189 We can then call the function foo():
186 We can then call the function foo():
190
187
191 In [2]: foo()
188 In [2]: foo()
192 foo() was defined in an editing session
189 foo() was defined in an editing session
193
190
194 Now we edit foo. IPython automatically loads the editor with the
191 Now we edit foo. IPython automatically loads the editor with the
195 (temporary) file where foo() was previously defined:
192 (temporary) file where foo() was previously defined:
196
193
197 In [3]: ed foo
194 In [3]: ed foo
198 Editing... done. Executing edited code...
195 Editing... done. Executing edited code...
199
196
200 And if we call foo() again we get the modified version:
197 And if we call foo() again we get the modified version:
201
198
202 In [4]: foo()
199 In [4]: foo()
203 foo() has now been changed!
200 foo() has now been changed!
204
201
205 Here is an example of how to edit a code snippet successive
202 Here is an example of how to edit a code snippet successive
206 times. First we call the editor:
203 times. First we call the editor:
207
204
208 In [5]: ed
205 In [5]: ed
209 Editing... done. Executing edited code...
206 Editing... done. Executing edited code...
210 hello
207 hello
211 Out[5]: "print 'hello'n"
208 Out[5]: "print 'hello'n"
212
209
213 Now we call it again with the previous output (stored in _):
210 Now we call it again with the previous output (stored in _):
214
211
215 In [6]: ed _
212 In [6]: ed _
216 Editing... done. Executing edited code...
213 Editing... done. Executing edited code...
217 hello world
214 hello world
218 Out[6]: "print 'hello world'n"
215 Out[6]: "print 'hello world'n"
219
216
220 Now we call it with the output #8 (stored in _8, also as Out[8]):
217 Now we call it with the output #8 (stored in _8, also as Out[8]):
221
218
222 In [7]: ed _8
219 In [7]: ed _8
223 Editing... done. Executing edited code...
220 Editing... done. Executing edited code...
224 hello again
221 hello again
225 Out[7]: "print 'hello again'n"
222 Out[7]: "print 'hello again'n"
226
223
227
224
228 Changing the default editor hook:
225 Changing the default editor hook:
229
226
230 If you wish to write your own editor hook, you can put it in a
227 If you wish to write your own editor hook, you can put it in a
231 configuration file which you load at startup time. The default hook
228 configuration file which you load at startup time. The default hook
232 is defined in the IPython.core.hooks module, and you can use that as a
229 is defined in the IPython.core.hooks module, and you can use that as a
233 starting example for further modifications. That file also has
230 starting example for further modifications. That file also has
234 general instructions on how to set a new hook for use once you've
231 general instructions on how to set a new hook for use once you've
235 defined it."""
232 defined it."""
236
233
237 # FIXME: This function has become a convoluted mess. It needs a
234 # FIXME: This function has become a convoluted mess. It needs a
238 # ground-up rewrite with clean, simple logic.
235 # ground-up rewrite with clean, simple logic.
239
236
240 def make_filename(arg):
237 def make_filename(arg):
241 "Make a filename from the given args"
238 "Make a filename from the given args"
242 try:
239 try:
243 filename = get_py_filename(arg)
240 filename = get_py_filename(arg)
244 except IOError:
241 except IOError:
245 if args.endswith('.py'):
242 if args.endswith('.py'):
246 filename = arg
243 filename = arg
247 else:
244 else:
248 filename = None
245 filename = None
249 return filename
246 return filename
250
247
251 # custom exceptions
248 # custom exceptions
252 class DataIsObject(Exception): pass
249 class DataIsObject(Exception): pass
253
250
254 opts,args = self.parse_options(parameter_s,'prn:')
251 opts,args = self.parse_options(parameter_s,'prn:')
255 # Set a few locals from the options for convenience:
252 # Set a few locals from the options for convenience:
256 opts_p = opts.has_key('p')
253 opts_p = opts.has_key('p')
257 opts_r = opts.has_key('r')
254 opts_r = opts.has_key('r')
258
255
259 # Default line number value
256 # Default line number value
260 lineno = opts.get('n',None)
257 lineno = opts.get('n',None)
261 if lineno is not None:
258 if lineno is not None:
262 try:
259 try:
263 lineno = int(lineno)
260 lineno = int(lineno)
264 except:
261 except:
265 warn("The -n argument must be an integer.")
262 warn("The -n argument must be an integer.")
266 return
263 return
267
264
268 if opts_p:
265 if opts_p:
269 args = '_%s' % last_call[0]
266 args = '_%s' % last_call[0]
270 if not self.shell.user_ns.has_key(args):
267 if not self.shell.user_ns.has_key(args):
271 args = last_call[1]
268 args = last_call[1]
272
269
273 # use last_call to remember the state of the previous call, but don't
270 # use last_call to remember the state of the previous call, but don't
274 # let it be clobbered by successive '-p' calls.
271 # let it be clobbered by successive '-p' calls.
275 try:
272 try:
276 last_call[0] = self.shell.displayhook.prompt_count
273 last_call[0] = self.shell.displayhook.prompt_count
277 if not opts_p:
274 if not opts_p:
278 last_call[1] = parameter_s
275 last_call[1] = parameter_s
279 except:
276 except:
280 pass
277 pass
281
278
282 # by default this is done with temp files, except when the given
279 # by default this is done with temp files, except when the given
283 # arg is a filename
280 # arg is a filename
284 use_temp = 1
281 use_temp = 1
285
282
286 if re.match(r'\d',args):
283 if re.match(r'\d',args):
287 # Mode where user specifies ranges of lines, like in %macro.
284 # Mode where user specifies ranges of lines, like in %macro.
288 # This means that you can't edit files whose names begin with
285 # This means that you can't edit files whose names begin with
289 # numbers this way. Tough.
286 # numbers this way. Tough.
290 ranges = args.split()
287 ranges = args.split()
291 data = ''.join(self.extract_input_slices(ranges,opts_r))
288 data = ''.join(self.extract_input_slices(ranges,opts_r))
292 elif args.endswith('.py'):
289 elif args.endswith('.py'):
293 filename = make_filename(args)
290 filename = make_filename(args)
294 data = ''
291 data = ''
295 use_temp = 0
292 use_temp = 0
296 elif args:
293 elif args:
297 try:
294 try:
298 # Load the parameter given as a variable. If not a string,
295 # Load the parameter given as a variable. If not a string,
299 # process it as an object instead (below)
296 # process it as an object instead (below)
300
297
301 #print '*** args',args,'type',type(args) # dbg
298 #print '*** args',args,'type',type(args) # dbg
302 data = eval(args,self.shell.user_ns)
299 data = eval(args,self.shell.user_ns)
303 if not type(data) in StringTypes:
300 if not type(data) in StringTypes:
304 raise DataIsObject
301 raise DataIsObject
305
302
306 except (NameError,SyntaxError):
303 except (NameError,SyntaxError):
307 # given argument is not a variable, try as a filename
304 # given argument is not a variable, try as a filename
308 filename = make_filename(args)
305 filename = make_filename(args)
309 if filename is None:
306 if filename is None:
310 warn("Argument given (%s) can't be found as a variable "
307 warn("Argument given (%s) can't be found as a variable "
311 "or as a filename." % args)
308 "or as a filename." % args)
312 return
309 return
313
310
314 data = ''
311 data = ''
315 use_temp = 0
312 use_temp = 0
316 except DataIsObject:
313 except DataIsObject:
317
314
318 # macros have a special edit function
315 # macros have a special edit function
319 if isinstance(data,Macro):
316 if isinstance(data,Macro):
320 self._edit_macro(args,data)
317 self._edit_macro(args,data)
321 return
318 return
322
319
323 # For objects, try to edit the file where they are defined
320 # For objects, try to edit the file where they are defined
324 try:
321 try:
325 filename = inspect.getabsfile(data)
322 filename = inspect.getabsfile(data)
326 if 'fakemodule' in filename.lower() and inspect.isclass(data):
323 if 'fakemodule' in filename.lower() and inspect.isclass(data):
327 # class created by %edit? Try to find source
324 # class created by %edit? Try to find source
328 # by looking for method definitions instead, the
325 # by looking for method definitions instead, the
329 # __module__ in those classes is FakeModule.
326 # __module__ in those classes is FakeModule.
330 attrs = [getattr(data, aname) for aname in dir(data)]
327 attrs = [getattr(data, aname) for aname in dir(data)]
331 for attr in attrs:
328 for attr in attrs:
332 if not inspect.ismethod(attr):
329 if not inspect.ismethod(attr):
333 continue
330 continue
334 filename = inspect.getabsfile(attr)
331 filename = inspect.getabsfile(attr)
335 if filename and 'fakemodule' not in filename.lower():
332 if filename and 'fakemodule' not in filename.lower():
336 # change the attribute to be the edit target instead
333 # change the attribute to be the edit target instead
337 data = attr
334 data = attr
338 break
335 break
339
336
340 datafile = 1
337 datafile = 1
341 except TypeError:
338 except TypeError:
342 filename = make_filename(args)
339 filename = make_filename(args)
343 datafile = 1
340 datafile = 1
344 warn('Could not find file where `%s` is defined.\n'
341 warn('Could not find file where `%s` is defined.\n'
345 'Opening a file named `%s`' % (args,filename))
342 'Opening a file named `%s`' % (args,filename))
346 # Now, make sure we can actually read the source (if it was in
343 # Now, make sure we can actually read the source (if it was in
347 # a temp file it's gone by now).
344 # a temp file it's gone by now).
348 if datafile:
345 if datafile:
349 try:
346 try:
350 if lineno is None:
347 if lineno is None:
351 lineno = inspect.getsourcelines(data)[1]
348 lineno = inspect.getsourcelines(data)[1]
352 except IOError:
349 except IOError:
353 filename = make_filename(args)
350 filename = make_filename(args)
354 if filename is None:
351 if filename is None:
355 warn('The file `%s` where `%s` was defined cannot '
352 warn('The file `%s` where `%s` was defined cannot '
356 'be read.' % (filename,data))
353 'be read.' % (filename,data))
357 return
354 return
358 use_temp = 0
355 use_temp = 0
359 else:
356 else:
360 data = ''
357 data = ''
361
358
362 if use_temp:
359 if use_temp:
363 filename = self.shell.mktempfile(data)
360 filename = self.shell.mktempfile(data)
364 print('IPython will make a temporary file named:', filename)
361 print('IPython will make a temporary file named:', filename)
365
362
366 # Make sure we send to the client an absolute path, in case the working
363 # Make sure we send to the client an absolute path, in case the working
367 # directory of client and kernel don't match
364 # directory of client and kernel don't match
368 filename = os.path.abspath(filename)
365 filename = os.path.abspath(filename)
369
366
370 payload = {
367 payload = {
371 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
368 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
372 'filename' : filename,
369 'filename' : filename,
373 'line_number' : lineno
370 'line_number' : lineno
374 }
371 }
375 self.payload_manager.write_payload(payload)
372 self.payload_manager.write_payload(payload)
376
373
377 def magic_gui(self, *args, **kwargs):
374 def magic_gui(self, *args, **kwargs):
378 raise NotImplementedError('GUI support must be enabled in command line options.')
375 raise NotImplementedError('GUI support must be enabled in command line options.')
379
376
380 def magic_pylab(self, *args, **kwargs):
377 def magic_pylab(self, *args, **kwargs):
381 raise NotImplementedError('pylab support must be enabled in commandl in options.')
378 raise NotImplementedError('pylab support must be enabled in commandl in options.')
382
379
383 def _showtraceback(self, etype, evalue, stb):
380 def _showtraceback(self, etype, evalue, stb):
384
381
385 exc_content = {
382 exc_content = {
386 u'status' : u'error',
387 u'traceback' : stb,
383 u'traceback' : stb,
388 u'ename' : unicode(etype.__name__),
384 u'ename' : unicode(etype.__name__),
389 u'evalue' : unicode(evalue)
385 u'evalue' : unicode(evalue)
390 }
386 }
391
387
392 dh = self.displayhook
388 dh = self.displayhook
393 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
389 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
394 # Send exception info over pub socket for other clients than the caller
390 # Send exception info over pub socket for other clients than the caller
395 # to pick up
391 # to pick up
396 dh.pub_socket.send_json(exc_msg)
392 dh.pub_socket.send_json(exc_msg)
397
393
398 # FIXME - Hack: store exception info in shell object. Right now, the
394 # FIXME - Hack: store exception info in shell object. Right now, the
399 # caller is reading this info after the fact, we need to fix this logic
395 # caller is reading this info after the fact, we need to fix this logic
400 # to remove this hack.
396 # to remove this hack. Even uglier, we need to store the error status
397 # here, because in the main loop, the logic that sets it is being
398 # skipped because runlines swallows the exceptions.
399 exc_content[u'status'] = u'error'
401 self._reply_content = exc_content
400 self._reply_content = exc_content
402 # /FIXME
401 # /FIXME
403
402
404 return exc_content
403 return exc_content
405
404
406 def runlines(self, lines, clean=False):
405 def runlines(self, lines, clean=False):
407 return InteractiveShell.runlines(self, lines, clean)
406 return InteractiveShell.runlines(self, lines, clean)
408
407
409 InteractiveShellABC.register(ZMQInteractiveShell)
408 InteractiveShellABC.register(ZMQInteractiveShell)
@@ -1,708 +1,707 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, but this may be a multiline
163 The ``code`` field contains a single string, but this may be a multiline
164 string. The kernel is responsible for splitting this into possibly more than
164 string. The kernel is responsible for splitting this into possibly more than
165 one block and deciding whether to compile these in 'single' or 'exec' mode.
165 one block and deciding whether to compile these in 'single' or 'exec' mode.
166 We're still sorting out this policy. The current inputsplitter is capable of
166 We're still sorting out this policy. The current inputsplitter is capable of
167 splitting the input for blocks that can all be run as 'single', but in the long
167 splitting the input for blocks that can all be run as 'single', but in the long
168 run it may prove cleaner to only use 'single' mode for truly single-line
168 run it may prove cleaner to only use 'single' mode for truly single-line
169 inputs, and run all multiline input in 'exec' mode. This would preserve the
169 inputs, and run all multiline input in 'exec' mode. This would preserve the
170 natural behavior of single-line inputs while allowing long cells to behave more
170 natural behavior of single-line inputs while allowing long cells to behave more
171 likea a script. This design will be refined as we complete the implementation.
171 likea a script. This design will be refined as we complete the implementation.
172
172
173 The ``user_`` fields deserve a detailed explanation. In the past, IPython had
173 The ``user_`` fields deserve a detailed explanation. In the past, IPython had
174 the notion of a prompt string that allowed arbitrary code to be evaluated, and
174 the notion of a prompt string that allowed arbitrary code to be evaluated, and
175 this was put to good use by many in creating prompts that displayed system
175 this was put to good use by many in creating prompts that displayed system
176 status, path information, and even more esoteric uses like remote instrument
176 status, path information, and even more esoteric uses like remote instrument
177 status aqcuired over the network. But now that IPython has a clean separation
177 status aqcuired over the network. But now that IPython has a clean separation
178 between the kernel and the clients, the notion of embedding 'prompt'
178 between the kernel and the clients, the notion of embedding 'prompt'
179 maninpulations into the kernel itself feels awkward. Prompts should be a
179 maninpulations into the kernel itself feels awkward. Prompts should be a
180 frontend-side feature, and it should be even possible for different frontends
180 frontend-side feature, and it should be even possible for different frontends
181 to display different prompts while interacting with the same kernel.
181 to display different prompts while interacting with the same kernel.
182
182
183 We have therefore abandoned the idea of a 'prompt string' to be evaluated by
183 We have therefore abandoned the idea of a 'prompt string' to be evaluated by
184 the kernel, and instead provide the ability to retrieve from the user's
184 the kernel, and instead provide the ability to retrieve from the user's
185 namespace information after the execution of the main ``code``, with two fields
185 namespace information after the execution of the main ``code``, with two fields
186 of the execution request:
186 of the execution request:
187
187
188 - ``user_variables``: If only variables from the user's namespace are needed, a
188 - ``user_variables``: If only variables from the user's namespace are needed, a
189 list of variable names can be passed and a dict with these names as keys and
189 list of variable names can be passed and a dict with these names as keys and
190 their :func:`repr()` as values will be returned.
190 their :func:`repr()` as values will be returned.
191
191
192 - ``user_expressions``: For more complex expressions that require function
192 - ``user_expressions``: For more complex expressions that require function
193 evaluations, a dict can be provided with string keys and arbitrary python
193 evaluations, a dict can be provided with string keys and arbitrary python
194 expressions as values. The return message will contain also a dict with the
194 expressions as values. The return message will contain also a dict with the
195 same keys and the :func:`repr()` of the evaluated expressions as value.
195 same keys and the :func:`repr()` of the evaluated expressions as value.
196
196
197 With this information, frontends can display any status information they wish
197 With this information, frontends can display any status information they wish
198 in the form that best suits each frontend (a status line, a popup, inline for a
198 in the form that best suits each frontend (a status line, a popup, inline for a
199 terminal, etc).
199 terminal, etc).
200
200
201 .. Note::
201 .. Note::
202
202
203 In order to obtain the current execution counter for the purposes of
203 In order to obtain the current execution counter for the purposes of
204 displaying input prompts, frontends simply make an execution request with an
204 displaying input prompts, frontends simply make an execution request with an
205 empty code string and ``silent=True``.
205 empty code string and ``silent=True``.
206
206
207 Execution semantics
207 Execution semantics
208 Upon completion of the execution request, the kernel *always* sends a
208 Upon completion of the execution request, the kernel *always* sends a
209 reply, with a status code indicating what happened and additional data
209 reply, with a status code indicating what happened and additional data
210 depending on the outcome.
210 depending on the outcome.
211
211
212 The ``code`` field is executed first, and then the ``user_variables`` and
212 The ``code`` field is executed first, and then the ``user_variables`` and
213 ``user_expressions`` are computed. This ensures that any error in the
213 ``user_expressions`` are computed. This ensures that any error in the
214 latter don't harm the main code execution.
214 latter don't harm the main code execution.
215
215
216 Any error in retrieving the ``user_variables`` or evaluating the
216 Any error in retrieving the ``user_variables`` or evaluating the
217 ``user_expressions`` will result in a simple error message in the return
217 ``user_expressions`` will result in a simple error message in the return
218 fields of the form::
218 fields of the form::
219
219
220 [ERROR] ExceptionType: Exception message
220 [ERROR] ExceptionType: Exception message
221
221
222 The user can simply send the same variable name or expression for
222 The user can simply send the same variable name or expression for
223 evaluation to see a regular traceback.
223 evaluation to see a regular traceback.
224
224
225 Execution counter (old prompt number)
225 Execution counter (old prompt number)
226 The kernel has a single, monotonically increasing counter of all execution
226 The kernel has a single, monotonically increasing counter of all execution
227 requests that are made with ``silent=False``. This counter is used to
227 requests that are made with ``silent=False``. This counter is used to
228 populate the ``In[n]``, ``Out[n]`` and ``_n`` variables, so clients will
228 populate the ``In[n]``, ``Out[n]`` and ``_n`` variables, so clients will
229 likely want to display it in some form to the user, which will typically
229 likely want to display it in some form to the user, which will typically
230 (but not necessarily) be done in the prompts. The value of this counter
230 (but not necessarily) be done in the prompts. The value of this counter
231 will be returned as the ``execution_count`` field of all ``execute_reply```
231 will be returned as the ``execution_count`` field of all ``execute_reply```
232 messages.
232 messages.
233
233
234 Message type: ``execute_reply``::
234 Message type: ``execute_reply``::
235
235
236 content = {
236 content = {
237 # One of: 'ok' OR 'error' OR 'abort'
237 # One of: 'ok' OR 'error' OR 'abort'
238 'status' : str,
238 'status' : str,
239
239
240 # The global kernel counter that increases by one with each non-silent
240 # The global kernel counter that increases by one with each non-silent
241 # executed request. This will typically be used by clients to display
241 # executed request. This will typically be used by clients to display
242 # prompt numbers to the user. If the request was a silent one, this will
242 # prompt numbers to the user. If the request was a silent one, this will
243 # be the current value of the counter in the kernel.
243 # be the current value of the counter in the kernel.
244 'execution_count' : int,
244 'execution_count' : int,
245
246 # If the state_template was provided, this will contain the evaluated
247 # form of the template.
248 'state' : str,
249 }
245 }
250
246
251 When status is 'ok', the following extra fields are present::
247 When status is 'ok', the following extra fields are present::
252
248
253 {
249 {
254 # The kernel will often transform the input provided to it. If the
255 # '---->' transform had been applied, this is filled, otherwise it's the
256 # empty string. So transformations like magics don't appear here, only
257 # autocall ones.
258
259 'transformed_code' : str,
260
261 # The execution payload is a dict with string keys that may have been
250 # The execution payload is a dict with string keys that may have been
262 # produced by the code being executed. It is retrieved by the kernel at
251 # produced by the code being executed. It is retrieved by the kernel at
263 # the end of the execution and sent back to the front end, which can take
252 # the end of the execution and sent back to the front end, which can take
264 # action on it as needed. See main text for further details.
253 # action on it as needed. See main text for further details.
265 'payload' : dict,
254 'payload' : dict,
266 }
255
256 # Results for the user_variables and user_expressions.
257 'user_variables' : dict,
258 'user_expressions' : dict,
259
260 # The kernel will often transform the input provided to it. If the
261 # '---->' transform had been applied, this is filled, otherwise it's the
262 # empty string. So transformations like magics don't appear here, only
263 # autocall ones.
264 'transformed_code' : str,
265 }
267
266
268 .. admonition:: Execution payloads
267 .. admonition:: Execution payloads
269
268
270 The notion of an 'execution payload' is different from a return value of a
269 The notion of an 'execution payload' is different from a return value of a
271 given set of code, which normally is just displayed on the pyout stream
270 given set of code, which normally is just displayed on the pyout stream
272 through the PUB socket. The idea of a payload is to allow special types of
271 through the PUB socket. The idea of a payload is to allow special types of
273 code, typically magics, to populate a data container in the IPython kernel
272 code, typically magics, to populate a data container in the IPython kernel
274 that will be shipped back to the caller via this channel. The kernel will
273 that will be shipped back to the caller via this channel. The kernel will
275 have an API for this, probably something along the lines of::
274 have an API for this, probably something along the lines of::
276
275
277 ip.exec_payload_add(key, value)
276 ip.exec_payload_add(key, value)
278
277
279 though this API is still in the design stages. The data returned in this
278 though this API is still in the design stages. The data returned in this
280 payload will allow frontends to present special views of what just happened.
279 payload will allow frontends to present special views of what just happened.
281
280
282
281
283 When status is 'error', the following extra fields are present::
282 When status is 'error', the following extra fields are present::
284
283
285 {
284 {
286 'exc_name' : str, # Exception name, as a string
285 'exc_name' : str, # Exception name, as a string
287 'exc_value' : str, # Exception value, as a string
286 'exc_value' : str, # Exception value, as a string
288
287
289 # The traceback will contain a list of frames, represented each as a
288 # The traceback will contain a list of frames, represented each as a
290 # string. For now we'll stick to the existing design of ultraTB, which
289 # string. For now we'll stick to the existing design of ultraTB, which
291 # controls exception level of detail statefully. But eventually we'll
290 # controls exception level of detail statefully. But eventually we'll
292 # want to grow into a model where more information is collected and
291 # want to grow into a model where more information is collected and
293 # packed into the traceback object, with clients deciding how little or
292 # packed into the traceback object, with clients deciding how little or
294 # how much of it to unpack. But for now, let's start with a simple list
293 # how much of it to unpack. But for now, let's start with a simple list
295 # of strings, since that requires only minimal changes to ultratb as
294 # of strings, since that requires only minimal changes to ultratb as
296 # written.
295 # written.
297 'traceback' : list,
296 'traceback' : list,
298 }
297 }
299
298
300
299
301 When status is 'abort', there are for now no additional data fields. This
300 When status is 'abort', there are for now no additional data fields. This
302 happens when the kernel was interrupted by a signal.
301 happens when the kernel was interrupted by a signal.
303
302
304 Kernel attribute access
303 Kernel attribute access
305 -----------------------
304 -----------------------
306
305
307 While this protocol does not specify full RPC access to arbitrary methods of
306 While this protocol does not specify full RPC access to arbitrary methods of
308 the kernel object, the kernel does allow read (and in some cases write) access
307 the kernel object, the kernel does allow read (and in some cases write) access
309 to certain attributes.
308 to certain attributes.
310
309
311 The policy for which attributes can be read is: any attribute of the kernel, or
310 The policy for which attributes can be read is: any attribute of the kernel, or
312 its sub-objects, that belongs to a :class:`Configurable` object and has been
311 its sub-objects, that belongs to a :class:`Configurable` object and has been
313 declared at the class-level with Traits validation, is in principle accessible
312 declared at the class-level with Traits validation, is in principle accessible
314 as long as its name does not begin with a leading underscore. The attribute
313 as long as its name does not begin with a leading underscore. The attribute
315 itself will have metadata indicating whether it allows remote read and/or write
314 itself will have metadata indicating whether it allows remote read and/or write
316 access. The message spec follows for attribute read and write requests.
315 access. The message spec follows for attribute read and write requests.
317
316
318 Message type: ``getattr_request``::
317 Message type: ``getattr_request``::
319
318
320 content = {
319 content = {
321 # The (possibly dotted) name of the attribute
320 # The (possibly dotted) name of the attribute
322 'name' : str,
321 'name' : str,
323 }
322 }
324
323
325 When a ``getattr_request`` fails, there are two possible error types:
324 When a ``getattr_request`` fails, there are two possible error types:
326
325
327 - AttributeError: this type of error was raised when trying to access the
326 - AttributeError: this type of error was raised when trying to access the
328 given name by the kernel itself. This means that the attribute likely
327 given name by the kernel itself. This means that the attribute likely
329 doesn't exist.
328 doesn't exist.
330
329
331 - AccessError: the attribute exists but its value is not readable remotely.
330 - AccessError: the attribute exists but its value is not readable remotely.
332
331
333
332
334 Message type: ``getattr_reply``::
333 Message type: ``getattr_reply``::
335
334
336 content = {
335 content = {
337 # One of ['ok', 'AttributeError', 'AccessError'].
336 # One of ['ok', 'AttributeError', 'AccessError'].
338 'status' : str,
337 'status' : str,
339 # If status is 'ok', a JSON object.
338 # If status is 'ok', a JSON object.
340 'value' : object,
339 'value' : object,
341 }
340 }
342
341
343 Message type: ``setattr_request``::
342 Message type: ``setattr_request``::
344
343
345 content = {
344 content = {
346 # The (possibly dotted) name of the attribute
345 # The (possibly dotted) name of the attribute
347 'name' : str,
346 'name' : str,
348
347
349 # A JSON-encoded object, that will be validated by the Traits
348 # A JSON-encoded object, that will be validated by the Traits
350 # information in the kernel
349 # information in the kernel
351 'value' : object,
350 'value' : object,
352 }
351 }
353
352
354 When a ``setattr_request`` fails, there are also two possible error types with
353 When a ``setattr_request`` fails, there are also two possible error types with
355 similar meanings as those of the ``getattr_request`` case, but for writing.
354 similar meanings as those of the ``getattr_request`` case, but for writing.
356
355
357 Message type: ``setattr_reply``::
356 Message type: ``setattr_reply``::
358
357
359 content = {
358 content = {
360 # One of ['ok', 'AttributeError', 'AccessError'].
359 # One of ['ok', 'AttributeError', 'AccessError'].
361 'status' : str,
360 'status' : str,
362 }
361 }
363
362
364
363
365 Object information
364 Object information
366 ------------------
365 ------------------
367
366
368 One of IPython's most used capabilities is the introspection of Python objects
367 One of IPython's most used capabilities is the introspection of Python objects
369 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
368 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
370 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
369 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
371 enough that it warrants an explicit message type, especially because frontends
370 enough that it warrants an explicit message type, especially because frontends
372 may want to get object information in response to user keystrokes (like Tab or
371 may want to get object information in response to user keystrokes (like Tab or
373 F1) besides from the user explicitly typing code like ``x??``.
372 F1) besides from the user explicitly typing code like ``x??``.
374
373
375 Message type: ``object_info_request``::
374 Message type: ``object_info_request``::
376
375
377 content = {
376 content = {
378 # The (possibly dotted) name of the object to be searched in all
377 # The (possibly dotted) name of the object to be searched in all
379 # relevant namespaces
378 # relevant namespaces
380 'name' : str,
379 'name' : str,
381
380
382 # The level of detail desired. The default (0) is equivalent to typing
381 # The level of detail desired. The default (0) is equivalent to typing
383 # 'x?' at the prompt, 1 is equivalent to 'x??'.
382 # 'x?' at the prompt, 1 is equivalent to 'x??'.
384 'detail_level' : int,
383 'detail_level' : int,
385 }
384 }
386
385
387 The returned information will be a dictionary with keys very similar to the
386 The returned information will be a dictionary with keys very similar to the
388 field names that IPython prints at the terminal.
387 field names that IPython prints at the terminal.
389
388
390 Message type: ``object_info_reply``::
389 Message type: ``object_info_reply``::
391
390
392 content = {
391 content = {
393 # Flags for magics and system aliases
392 # Flags for magics and system aliases
394 'ismagic' : bool,
393 'ismagic' : bool,
395 'isalias' : bool,
394 'isalias' : bool,
396
395
397 # The name of the namespace where the object was found ('builtin',
396 # The name of the namespace where the object was found ('builtin',
398 # 'magics', 'alias', 'interactive', etc.)
397 # 'magics', 'alias', 'interactive', etc.)
399 'namespace' : str,
398 'namespace' : str,
400
399
401 # The type name will be type.__name__ for normal Python objects, but it
400 # The type name will be type.__name__ for normal Python objects, but it
402 # can also be a string like 'Magic function' or 'System alias'
401 # can also be a string like 'Magic function' or 'System alias'
403 'type_name' : str,
402 'type_name' : str,
404
403
405 'string_form' : str,
404 'string_form' : str,
406
405
407 # For objects with a __class__ attribute this will be set
406 # For objects with a __class__ attribute this will be set
408 'base_class' : str,
407 'base_class' : str,
409
408
410 # For objects with a __len__ attribute this will be set
409 # For objects with a __len__ attribute this will be set
411 'length' : int,
410 'length' : int,
412
411
413 # If the object is a function, class or method whose file we can find,
412 # If the object is a function, class or method whose file we can find,
414 # we give its full path
413 # we give its full path
415 'file' : str,
414 'file' : str,
416
415
417 # For pure Python callable objects, we can reconstruct the object
416 # For pure Python callable objects, we can reconstruct the object
418 # definition line which provides its call signature. For convenience this
417 # definition line which provides its call signature. For convenience this
419 # is returned as a single 'definition' field, but below the raw parts that
418 # is returned as a single 'definition' field, but below the raw parts that
420 # compose it are also returned as the argspec field.
419 # compose it are also returned as the argspec field.
421 'definition' : str,
420 'definition' : str,
422
421
423 # The individual parts that together form the definition string. Clients
422 # The individual parts that together form the definition string. Clients
424 # with rich display capabilities may use this to provide a richer and more
423 # with rich display capabilities may use this to provide a richer and more
425 # precise representation of the definition line (e.g. by highlighting
424 # precise representation of the definition line (e.g. by highlighting
426 # arguments based on the user's cursor position). For non-callable
425 # arguments based on the user's cursor position). For non-callable
427 # objects, this field is empty.
426 # objects, this field is empty.
428 'argspec' : { # The names of all the arguments
427 'argspec' : { # The names of all the arguments
429 args : list,
428 args : list,
430 # The name of the varargs (*args), if any
429 # The name of the varargs (*args), if any
431 varargs : str,
430 varargs : str,
432 # The name of the varkw (**kw), if any
431 # The name of the varkw (**kw), if any
433 varkw : str,
432 varkw : str,
434 # The values (as strings) of all default arguments. Note
433 # The values (as strings) of all default arguments. Note
435 # that these must be matched *in reverse* with the 'args'
434 # that these must be matched *in reverse* with the 'args'
436 # list above, since the first positional args have no default
435 # list above, since the first positional args have no default
437 # value at all.
436 # value at all.
438 func_defaults : list,
437 func_defaults : list,
439 },
438 },
440
439
441 # For instances, provide the constructor signature (the definition of
440 # For instances, provide the constructor signature (the definition of
442 # the __init__ method):
441 # the __init__ method):
443 'init_definition' : str,
442 'init_definition' : str,
444
443
445 # Docstrings: for any object (function, method, module, package) with a
444 # Docstrings: for any object (function, method, module, package) with a
446 # docstring, we show it. But in addition, we may provide additional
445 # docstring, we show it. But in addition, we may provide additional
447 # docstrings. For example, for instances we will show the constructor
446 # docstrings. For example, for instances we will show the constructor
448 # and class docstrings as well, if available.
447 # and class docstrings as well, if available.
449 'docstring' : str,
448 'docstring' : str,
450
449
451 # For instances, provide the constructor and class docstrings
450 # For instances, provide the constructor and class docstrings
452 'init_docstring' : str,
451 'init_docstring' : str,
453 'class_docstring' : str,
452 'class_docstring' : str,
454
453
455 # If detail_level was 1, we also try to find the source code that
454 # If detail_level was 1, we also try to find the source code that
456 # defines the object, if possible. The string 'None' will indicate
455 # defines the object, if possible. The string 'None' will indicate
457 # that no source was found.
456 # that no source was found.
458 'source' : str,
457 'source' : str,
459 }
458 }
460
459
461
460
462 Complete
461 Complete
463 --------
462 --------
464
463
465 Message type: ``complete_request``::
464 Message type: ``complete_request``::
466
465
467 content = {
466 content = {
468 # The text to be completed, such as 'a.is'
467 # The text to be completed, such as 'a.is'
469 'text' : str,
468 'text' : str,
470
469
471 # The full line, such as 'print a.is'. This allows completers to
470 # The full line, such as 'print a.is'. This allows completers to
472 # make decisions that may require information about more than just the
471 # make decisions that may require information about more than just the
473 # current word.
472 # current word.
474 'line' : str,
473 'line' : str,
475
474
476 # The entire block of text where the line is. This may be useful in the
475 # The entire block of text where the line is. This may be useful in the
477 # case of multiline completions where more context may be needed. Note: if
476 # case of multiline completions where more context may be needed. Note: if
478 # in practice this field proves unnecessary, remove it to lighten the
477 # in practice this field proves unnecessary, remove it to lighten the
479 # messages.
478 # messages.
480
479
481 'block' : str,
480 'block' : str,
482
481
483 # The position of the cursor where the user hit 'TAB' on the line.
482 # The position of the cursor where the user hit 'TAB' on the line.
484 'cursor_pos' : int,
483 'cursor_pos' : int,
485 }
484 }
486
485
487 Message type: ``complete_reply``::
486 Message type: ``complete_reply``::
488
487
489 content = {
488 content = {
490 # The list of all matches to the completion request, such as
489 # The list of all matches to the completion request, such as
491 # ['a.isalnum', 'a.isalpha'] for the above example.
490 # ['a.isalnum', 'a.isalpha'] for the above example.
492 'matches' : list
491 'matches' : list
493 }
492 }
494
493
495
494
496 History
495 History
497 -------
496 -------
498
497
499 For clients to explicitly request history from a kernel. The kernel has all
498 For clients to explicitly request history from a kernel. The kernel has all
500 the actual execution history stored in a single location, so clients can
499 the actual execution history stored in a single location, so clients can
501 request it from the kernel when needed.
500 request it from the kernel when needed.
502
501
503 Message type: ``history_request``::
502 Message type: ``history_request``::
504
503
505 content = {
504 content = {
506
505
507 # If True, also return output history in the resulting dict.
506 # If True, also return output history in the resulting dict.
508 'output' : bool,
507 'output' : bool,
509
508
510 # If True, return the raw input history, else the transformed input.
509 # If True, return the raw input history, else the transformed input.
511 'raw' : bool,
510 'raw' : bool,
512
511
513 # This parameter can be one of: A number, a pair of numbers, None
512 # This parameter can be one of: A number, a pair of numbers, None
514 # If not given, last 40 are returned.
513 # If not given, last 40 are returned.
515 # - number n: return the last n entries.
514 # - number n: return the last n entries.
516 # - pair n1, n2: return entries in the range(n1, n2).
515 # - pair n1, n2: return entries in the range(n1, n2).
517 # - None: return all history
516 # - None: return all history
518 'index' : n or (n1, n2) or None,
517 'index' : n or (n1, n2) or None,
519 }
518 }
520
519
521 Message type: ``history_reply``::
520 Message type: ``history_reply``::
522
521
523 content = {
522 content = {
524 # A dict with prompt numbers as keys and either (input, output) or input
523 # A dict with prompt numbers as keys and either (input, output) or input
525 # as the value depending on whether output was True or False,
524 # as the value depending on whether output was True or False,
526 # respectively.
525 # respectively.
527 'history' : dict,
526 'history' : dict,
528 }
527 }
529
528
530 Messages on the PUB/SUB socket
529 Messages on the PUB/SUB socket
531 ==============================
530 ==============================
532
531
533 Streams (stdout, stderr, etc)
532 Streams (stdout, stderr, etc)
534 ------------------------------
533 ------------------------------
535
534
536 Message type: ``stream``::
535 Message type: ``stream``::
537
536
538 content = {
537 content = {
539 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
538 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
540 'name' : str,
539 'name' : str,
541
540
542 # The data is an arbitrary string to be written to that stream
541 # The data is an arbitrary string to be written to that stream
543 'data' : str,
542 'data' : str,
544 }
543 }
545
544
546 When a kernel receives a raw_input call, it should also broadcast it on the pub
545 When a kernel receives a raw_input call, it should also broadcast it on the pub
547 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
546 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
548 to monitor/display kernel interactions and possibly replay them to their user
547 to monitor/display kernel interactions and possibly replay them to their user
549 or otherwise expose them.
548 or otherwise expose them.
550
549
551 Python inputs
550 Python inputs
552 -------------
551 -------------
553
552
554 These messages are the re-broadcast of the ``execute_request``.
553 These messages are the re-broadcast of the ``execute_request``.
555
554
556 Message type: ``pyin``::
555 Message type: ``pyin``::
557
556
558 content = {
557 content = {
559 # Source code to be executed, one or more lines
558 # Source code to be executed, one or more lines
560 'code' : str
559 'code' : str
561 }
560 }
562
561
563 Python outputs
562 Python outputs
564 --------------
563 --------------
565
564
566 When Python produces output from code that has been compiled in with the
565 When Python produces output from code that has been compiled in with the
567 'single' flag to :func:`compile`, any expression that produces a value (such as
566 'single' flag to :func:`compile`, any expression that produces a value (such as
568 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
567 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
569 this value whatever it wants. The default behavior of ``sys.displayhook`` in
568 this value whatever it wants. The default behavior of ``sys.displayhook`` in
570 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
569 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
571 the value as long as it is not ``None`` (which isn't printed at all). In our
570 the value as long as it is not ``None`` (which isn't printed at all). In our
572 case, the kernel instantiates as ``sys.displayhook`` an object which has
571 case, the kernel instantiates as ``sys.displayhook`` an object which has
573 similar behavior, but which instead of printing to stdout, broadcasts these
572 similar behavior, but which instead of printing to stdout, broadcasts these
574 values as ``pyout`` messages for clients to display appropriately.
573 values as ``pyout`` messages for clients to display appropriately.
575
574
576 Message type: ``pyout``::
575 Message type: ``pyout``::
577
576
578 content = {
577 content = {
579 # The data is typically the repr() of the object.
578 # The data is typically the repr() of the object.
580 'data' : str,
579 'data' : str,
581
580
582 # The counter for this execution is also provided so that clients can
581 # The counter for this execution is also provided so that clients can
583 # display it, since IPython automatically creates variables called _N (for
582 # display it, since IPython automatically creates variables called _N (for
584 # prompt N).
583 # prompt N).
585 'execution_count' : int,
584 'execution_count' : int,
586 }
585 }
587
586
588 Python errors
587 Python errors
589 -------------
588 -------------
590
589
591 When an error occurs during code execution
590 When an error occurs during code execution
592
591
593 Message type: ``pyerr``::
592 Message type: ``pyerr``::
594
593
595 content = {
594 content = {
596 # Similar content to the execute_reply messages for the 'error' case,
595 # Similar content to the execute_reply messages for the 'error' case,
597 # except the 'status' field is omitted.
596 # except the 'status' field is omitted.
598 }
597 }
599
598
600 Kernel crashes
599 Kernel crashes
601 --------------
600 --------------
602
601
603 When the kernel has an unexpected exception, caught by the last-resort
602 When the kernel has an unexpected exception, caught by the last-resort
604 sys.excepthook, we should broadcast the crash handler's output before exiting.
603 sys.excepthook, we should broadcast the crash handler's output before exiting.
605 This will allow clients to notice that a kernel died, inform the user and
604 This will allow clients to notice that a kernel died, inform the user and
606 propose further actions.
605 propose further actions.
607
606
608 Message type: ``crash``::
607 Message type: ``crash``::
609
608
610 content = {
609 content = {
611 # Similarly to the 'error' case for execute_reply messages, this will
610 # Similarly to the 'error' case for execute_reply messages, this will
612 # contain exc_name, exc_type and traceback fields.
611 # contain exc_name, exc_type and traceback fields.
613
612
614 # An additional field with supplementary information such as where to
613 # An additional field with supplementary information such as where to
615 # send the crash message
614 # send the crash message
616 'info' : str,
615 'info' : str,
617 }
616 }
618
617
619
618
620 Future ideas
619 Future ideas
621 ------------
620 ------------
622
621
623 Other potential message types, currently unimplemented, listed below as ideas.
622 Other potential message types, currently unimplemented, listed below as ideas.
624
623
625 Message type: ``file``::
624 Message type: ``file``::
626
625
627 content = {
626 content = {
628 'path' : 'cool.jpg',
627 'path' : 'cool.jpg',
629 'mimetype' : str,
628 'mimetype' : str,
630 'data' : str,
629 'data' : str,
631 }
630 }
632
631
633
632
634 Messages on the REQ/REP socket
633 Messages on the REQ/REP socket
635 ==============================
634 ==============================
636
635
637 This is a socket that goes in the opposite direction: from the kernel to a
636 This is a socket that goes in the opposite direction: from the kernel to a
638 *single* frontend, and its purpose is to allow ``raw_input`` and similar
637 *single* frontend, and its purpose is to allow ``raw_input`` and similar
639 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
638 operations that read from ``sys.stdin`` on the kernel to be fulfilled by the
640 client. For now we will keep these messages as simple as possible, since they
639 client. For now we will keep these messages as simple as possible, since they
641 basically only mean to convey the ``raw_input(prompt)`` call.
640 basically only mean to convey the ``raw_input(prompt)`` call.
642
641
643 Message type: ``input_request``::
642 Message type: ``input_request``::
644
643
645 content = { 'prompt' : str }
644 content = { 'prompt' : str }
646
645
647 Message type: ``input_reply``::
646 Message type: ``input_reply``::
648
647
649 content = { 'value' : str }
648 content = { 'value' : str }
650
649
651 .. Note::
650 .. Note::
652
651
653 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
652 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
654 practice the kernel should behave like an interactive program. When a
653 practice the kernel should behave like an interactive program. When a
655 program is opened on the console, the keyboard effectively takes over the
654 program is opened on the console, the keyboard effectively takes over the
656 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
655 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
657 Since the IPython kernel effectively behaves like a console program (albeit
656 Since the IPython kernel effectively behaves like a console program (albeit
658 one whose "keyboard" is actually living in a separate process and
657 one whose "keyboard" is actually living in a separate process and
659 transported over the zmq connection), raw ``stdin`` isn't expected to be
658 transported over the zmq connection), raw ``stdin`` isn't expected to be
660 available.
659 available.
661
660
662
661
663 Heartbeat for kernels
662 Heartbeat for kernels
664 =====================
663 =====================
665
664
666 Initially we had considered using messages like those above over ZMQ for a
665 Initially we had considered using messages like those above over ZMQ for a
667 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
666 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
668 alive at all, even if it may be busy executing user code). But this has the
667 alive at all, even if it may be busy executing user code). But this has the
669 problem that if the kernel is locked inside extension code, it wouldn't execute
668 problem that if the kernel is locked inside extension code, it wouldn't execute
670 the python heartbeat code. But it turns out that we can implement a basic
669 the python heartbeat code. But it turns out that we can implement a basic
671 heartbeat with pure ZMQ, without using any Python messaging at all.
670 heartbeat with pure ZMQ, without using any Python messaging at all.
672
671
673 The monitor sends out a single zmq message (right now, it is a str of the
672 The monitor sends out a single zmq message (right now, it is a str of the
674 monitor's lifetime in seconds), and gets the same message right back, prefixed
673 monitor's lifetime in seconds), and gets the same message right back, prefixed
675 with the zmq identity of the XREQ socket in the heartbeat process. This can be
674 with the zmq identity of the XREQ socket in the heartbeat process. This can be
676 a uuid, or even a full message, but there doesn't seem to be a need for packing
675 a uuid, or even a full message, but there doesn't seem to be a need for packing
677 up a message when the sender and receiver are the exact same Python object.
676 up a message when the sender and receiver are the exact same Python object.
678
677
679 The model is this::
678 The model is this::
680
679
681 monitor.send(str(self.lifetime)) # '1.2345678910'
680 monitor.send(str(self.lifetime)) # '1.2345678910'
682
681
683 and the monitor receives some number of messages of the form::
682 and the monitor receives some number of messages of the form::
684
683
685 ['uuid-abcd-dead-beef', '1.2345678910']
684 ['uuid-abcd-dead-beef', '1.2345678910']
686
685
687 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
686 where the first part is the zmq.IDENTITY of the heart's XREQ on the engine, and
688 the rest is the message sent by the monitor. No Python code ever has any
687 the rest is the message sent by the monitor. No Python code ever has any
689 access to the message between the monitor's send, and the monitor's recv.
688 access to the message between the monitor's send, and the monitor's recv.
690
689
691
690
692 ToDo
691 ToDo
693 ====
692 ====
694
693
695 Missing things include:
694 Missing things include:
696
695
697 * Important: finish thinking through the payload concept and API.
696 * Important: finish thinking through the payload concept and API.
698
697
699 * Important: ensure that we have a good solution for magics like %edit. It's
698 * Important: ensure that we have a good solution for magics like %edit. It's
700 likely that with the payload concept we can build a full solution, but not
699 likely that with the payload concept we can build a full solution, but not
701 100% clear yet.
700 100% clear yet.
702
701
703 * Finishing the details of the heartbeat protocol.
702 * Finishing the details of the heartbeat protocol.
704
703
705 * Signal handling: specify what kind of information kernel should broadcast (or
704 * Signal handling: specify what kind of information kernel should broadcast (or
706 not) when it receives signals.
705 not) when it receives signals.
707
706
708 .. include:: ../links.rst
707 .. include:: ../links.rst
General Comments 0
You need to be logged in to leave comments. Login now