##// END OF EJS Templates
Merge branch 'newkernel' into upstream-newkernel...
Brian Granger -
r2873:087388fb merge
parent child Browse files
Show More
@@ -1,2151 +1,2151 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 prefilter
35 from IPython.core import prefilter
36 from IPython.core import shadowns
36 from IPython.core import shadowns
37 from IPython.core import ultratb
37 from IPython.core import ultratb
38 from IPython.core.alias import AliasManager
38 from IPython.core.alias import AliasManager
39 from IPython.core.builtin_trap import BuiltinTrap
39 from IPython.core.builtin_trap import BuiltinTrap
40 from IPython.core.display_trap import DisplayTrap
40 from IPython.core.display_trap import DisplayTrap
41 from IPython.core.displayhook import DisplayHook
41 from IPython.core.displayhook import DisplayHook
42 from IPython.core.error import UsageError
42 from IPython.core.error import UsageError
43 from IPython.core.extensions import ExtensionManager
43 from IPython.core.extensions import ExtensionManager
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
44 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
45 from IPython.core.inputlist import InputList
45 from IPython.core.inputlist import InputList
46 from IPython.core.logger import Logger
46 from IPython.core.logger import Logger
47 from IPython.core.magic import Magic
47 from IPython.core.magic import Magic
48 from IPython.core.payload import PayloadManager
48 from IPython.core.payload import PayloadManager
49 from IPython.core.plugin import PluginManager
49 from IPython.core.plugin import PluginManager
50 from IPython.core.prefilter import PrefilterManager
50 from IPython.core.prefilter import PrefilterManager
51 from IPython.external.Itpl import ItplNS
51 from IPython.external.Itpl import ItplNS
52 from IPython.utils import PyColorize
52 from IPython.utils import PyColorize
53 from IPython.utils import io
53 from IPython.utils import io
54 from IPython.utils import pickleshare
54 from IPython.utils import pickleshare
55 from IPython.utils.doctestreload import doctest_reload
55 from IPython.utils.doctestreload import doctest_reload
56 from IPython.utils.io import ask_yes_no, rprint
56 from IPython.utils.io import ask_yes_no, rprint
57 from IPython.utils.ipstruct import Struct
57 from IPython.utils.ipstruct import Struct
58 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
58 from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError
59 from IPython.utils.process import getoutput, getoutputerror
59 from IPython.utils.process import getoutput, getoutputerror
60 from IPython.utils.strdispatch import StrDispatch
60 from IPython.utils.strdispatch import StrDispatch
61 from IPython.utils.syspathcontext import prepended_to_syspath
61 from IPython.utils.syspathcontext import prepended_to_syspath
62 from IPython.utils.text import num_ini_spaces
62 from IPython.utils.text import num_ini_spaces
63 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
63 from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum,
64 List, Unicode, Instance, Type)
64 List, Unicode, Instance, Type)
65 from IPython.utils.warn import warn, error, fatal
65 from IPython.utils.warn import warn, error, fatal
66 import IPython.core.hooks
66 import IPython.core.hooks
67
67
68 # from IPython.utils import growl
68 # from IPython.utils import growl
69 # growl.start("IPython")
69 # growl.start("IPython")
70
70
71 #-----------------------------------------------------------------------------
71 #-----------------------------------------------------------------------------
72 # Globals
72 # Globals
73 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
74
74
75 # compiled regexps for autoindent management
75 # compiled regexps for autoindent management
76 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
76 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
77
77
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79 # Utilities
79 # Utilities
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81
81
82 # store the builtin raw_input globally, and use this always, in case user code
82 # store the builtin raw_input globally, and use this always, in case user code
83 # overwrites it (like wx.py.PyShell does)
83 # overwrites it (like wx.py.PyShell does)
84 raw_input_original = raw_input
84 raw_input_original = raw_input
85
85
86 def softspace(file, newvalue):
86 def softspace(file, newvalue):
87 """Copied from code.py, to remove the dependency"""
87 """Copied from code.py, to remove the dependency"""
88
88
89 oldvalue = 0
89 oldvalue = 0
90 try:
90 try:
91 oldvalue = file.softspace
91 oldvalue = file.softspace
92 except AttributeError:
92 except AttributeError:
93 pass
93 pass
94 try:
94 try:
95 file.softspace = newvalue
95 file.softspace = newvalue
96 except (AttributeError, TypeError):
96 except (AttributeError, TypeError):
97 # "attribute-less object" or "read-only attributes"
97 # "attribute-less object" or "read-only attributes"
98 pass
98 pass
99 return oldvalue
99 return oldvalue
100
100
101
101
102 def no_op(*a, **kw): pass
102 def no_op(*a, **kw): pass
103
103
104 class SpaceInInput(exceptions.Exception): pass
104 class SpaceInInput(exceptions.Exception): pass
105
105
106 class Bunch: pass
106 class Bunch: pass
107
107
108
108
109 def get_default_colors():
109 def get_default_colors():
110 if sys.platform=='darwin':
110 if sys.platform=='darwin':
111 return "LightBG"
111 return "LightBG"
112 elif os.name=='nt':
112 elif os.name=='nt':
113 return 'Linux'
113 return 'Linux'
114 else:
114 else:
115 return 'Linux'
115 return 'Linux'
116
116
117
117
118 class SeparateStr(Str):
118 class SeparateStr(Str):
119 """A Str subclass to validate separate_in, separate_out, etc.
119 """A Str subclass to validate separate_in, separate_out, etc.
120
120
121 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
121 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
122 """
122 """
123
123
124 def validate(self, obj, value):
124 def validate(self, obj, value):
125 if value == '0': value = ''
125 if value == '0': value = ''
126 value = value.replace('\\n','\n')
126 value = value.replace('\\n','\n')
127 return super(SeparateStr, self).validate(obj, value)
127 return super(SeparateStr, self).validate(obj, value)
128
128
129 class MultipleInstanceError(Exception):
129 class MultipleInstanceError(Exception):
130 pass
130 pass
131
131
132
132
133 #-----------------------------------------------------------------------------
133 #-----------------------------------------------------------------------------
134 # Main IPython class
134 # Main IPython class
135 #-----------------------------------------------------------------------------
135 #-----------------------------------------------------------------------------
136
136
137
137
138 class InteractiveShell(Configurable, Magic):
138 class InteractiveShell(Configurable, Magic):
139 """An enhanced, interactive shell for Python."""
139 """An enhanced, interactive shell for Python."""
140
140
141 _instance = None
141 _instance = None
142 autocall = Enum((0,1,2), default_value=1, config=True)
142 autocall = Enum((0,1,2), default_value=1, config=True)
143 # TODO: remove all autoindent logic and put into frontends.
143 # TODO: remove all autoindent logic and put into frontends.
144 # We can't do this yet because even runlines uses the autoindent.
144 # We can't do this yet because even runlines uses the autoindent.
145 autoindent = CBool(True, config=True)
145 autoindent = CBool(True, config=True)
146 automagic = CBool(True, config=True)
146 automagic = CBool(True, config=True)
147 cache_size = Int(1000, config=True)
147 cache_size = Int(1000, config=True)
148 color_info = CBool(True, config=True)
148 color_info = CBool(True, config=True)
149 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
149 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
150 default_value=get_default_colors(), config=True)
150 default_value=get_default_colors(), config=True)
151 debug = CBool(False, config=True)
151 debug = CBool(False, config=True)
152 deep_reload = CBool(False, config=True)
152 deep_reload = CBool(False, config=True)
153 displayhook_class = Type(DisplayHook)
153 displayhook_class = Type(DisplayHook)
154 filename = Str("<ipython console>")
154 filename = Str("<ipython console>")
155 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
155 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
156 logstart = CBool(False, config=True)
156 logstart = CBool(False, config=True)
157 logfile = Str('', config=True)
157 logfile = Str('', config=True)
158 logappend = Str('', config=True)
158 logappend = Str('', config=True)
159 object_info_string_level = Enum((0,1,2), default_value=0,
159 object_info_string_level = Enum((0,1,2), default_value=0,
160 config=True)
160 config=True)
161 pdb = CBool(False, config=True)
161 pdb = CBool(False, config=True)
162 pprint = CBool(True, config=True)
162 pprint = CBool(True, config=True)
163 profile = Str('', config=True)
163 profile = Str('', config=True)
164 prompt_in1 = Str('In [\\#]: ', config=True)
164 prompt_in1 = Str('In [\\#]: ', config=True)
165 prompt_in2 = Str(' .\\D.: ', config=True)
165 prompt_in2 = Str(' .\\D.: ', config=True)
166 prompt_out = Str('Out[\\#]: ', config=True)
166 prompt_out = Str('Out[\\#]: ', config=True)
167 prompts_pad_left = CBool(True, config=True)
167 prompts_pad_left = CBool(True, config=True)
168 quiet = CBool(False, config=True)
168 quiet = CBool(False, config=True)
169
169
170 # The readline stuff will eventually be moved to the terminal subclass
170 # The readline stuff will eventually be moved to the terminal subclass
171 # but for now, we can't do that as readline is welded in everywhere.
171 # but for now, we can't do that as readline is welded in everywhere.
172 readline_use = CBool(True, config=True)
172 readline_use = CBool(True, config=True)
173 readline_merge_completions = CBool(True, config=True)
173 readline_merge_completions = CBool(True, config=True)
174 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
174 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
175 readline_remove_delims = Str('-/~', config=True)
175 readline_remove_delims = Str('-/~', config=True)
176 readline_parse_and_bind = List([
176 readline_parse_and_bind = List([
177 'tab: complete',
177 'tab: complete',
178 '"\C-l": clear-screen',
178 '"\C-l": clear-screen',
179 'set show-all-if-ambiguous on',
179 'set show-all-if-ambiguous on',
180 '"\C-o": tab-insert',
180 '"\C-o": tab-insert',
181 '"\M-i": " "',
181 '"\M-i": " "',
182 '"\M-o": "\d\d\d\d"',
182 '"\M-o": "\d\d\d\d"',
183 '"\M-I": "\d\d\d\d"',
183 '"\M-I": "\d\d\d\d"',
184 '"\C-r": reverse-search-history',
184 '"\C-r": reverse-search-history',
185 '"\C-s": forward-search-history',
185 '"\C-s": forward-search-history',
186 '"\C-p": history-search-backward',
186 '"\C-p": history-search-backward',
187 '"\C-n": history-search-forward',
187 '"\C-n": history-search-forward',
188 '"\e[A": history-search-backward',
188 '"\e[A": history-search-backward',
189 '"\e[B": history-search-forward',
189 '"\e[B": history-search-forward',
190 '"\C-k": kill-line',
190 '"\C-k": kill-line',
191 '"\C-u": unix-line-discard',
191 '"\C-u": unix-line-discard',
192 ], allow_none=False, config=True)
192 ], allow_none=False, config=True)
193
193
194 # TODO: this part of prompt management should be moved to the frontends.
194 # TODO: this part of prompt management should be moved to the frontends.
195 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
195 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
196 separate_in = SeparateStr('\n', config=True)
196 separate_in = SeparateStr('\n', config=True)
197 separate_out = SeparateStr('\n', config=True)
197 separate_out = SeparateStr('', config=True)
198 separate_out2 = SeparateStr('\n', config=True)
198 separate_out2 = SeparateStr('', config=True)
199 system_header = Str('IPython system call: ', config=True)
199 system_header = Str('IPython system call: ', config=True)
200 system_verbose = CBool(False, config=True)
200 system_verbose = CBool(False, config=True)
201 wildcards_case_sensitive = CBool(True, config=True)
201 wildcards_case_sensitive = CBool(True, config=True)
202 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
202 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
203 default_value='Context', config=True)
203 default_value='Context', config=True)
204
204
205 # Subcomponents of InteractiveShell
205 # Subcomponents of InteractiveShell
206 alias_manager = Instance('IPython.core.alias.AliasManager')
206 alias_manager = Instance('IPython.core.alias.AliasManager')
207 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
207 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
208 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
208 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
209 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
209 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
210 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
210 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
211 plugin_manager = Instance('IPython.core.plugin.PluginManager')
211 plugin_manager = Instance('IPython.core.plugin.PluginManager')
212 payload_manager = Instance('IPython.core.payload.PayloadManager')
212 payload_manager = Instance('IPython.core.payload.PayloadManager')
213
213
214 def __init__(self, config=None, ipython_dir=None,
214 def __init__(self, config=None, ipython_dir=None,
215 user_ns=None, user_global_ns=None,
215 user_ns=None, user_global_ns=None,
216 custom_exceptions=((),None)):
216 custom_exceptions=((),None)):
217
217
218 # This is where traits with a config_key argument are updated
218 # This is where traits with a config_key argument are updated
219 # from the values on config.
219 # from the values on config.
220 super(InteractiveShell, self).__init__(config=config)
220 super(InteractiveShell, self).__init__(config=config)
221
221
222 # These are relatively independent and stateless
222 # These are relatively independent and stateless
223 self.init_ipython_dir(ipython_dir)
223 self.init_ipython_dir(ipython_dir)
224 self.init_instance_attrs()
224 self.init_instance_attrs()
225
225
226 # Create namespaces (user_ns, user_global_ns, etc.)
226 # Create namespaces (user_ns, user_global_ns, etc.)
227 self.init_create_namespaces(user_ns, user_global_ns)
227 self.init_create_namespaces(user_ns, user_global_ns)
228 # This has to be done after init_create_namespaces because it uses
228 # This has to be done after init_create_namespaces because it uses
229 # something in self.user_ns, but before init_sys_modules, which
229 # something in self.user_ns, but before init_sys_modules, which
230 # is the first thing to modify sys.
230 # is the first thing to modify sys.
231 # TODO: When we override sys.stdout and sys.stderr before this class
231 # TODO: When we override sys.stdout and sys.stderr before this class
232 # is created, we are saving the overridden ones here. Not sure if this
232 # is created, we are saving the overridden ones here. Not sure if this
233 # is what we want to do.
233 # is what we want to do.
234 self.save_sys_module_state()
234 self.save_sys_module_state()
235 self.init_sys_modules()
235 self.init_sys_modules()
236
236
237 self.init_history()
237 self.init_history()
238 self.init_encoding()
238 self.init_encoding()
239 self.init_prefilter()
239 self.init_prefilter()
240
240
241 Magic.__init__(self, self)
241 Magic.__init__(self, self)
242
242
243 self.init_syntax_highlighting()
243 self.init_syntax_highlighting()
244 self.init_hooks()
244 self.init_hooks()
245 self.init_pushd_popd_magic()
245 self.init_pushd_popd_magic()
246 # self.init_traceback_handlers use to be here, but we moved it below
246 # self.init_traceback_handlers use to be here, but we moved it below
247 # because it and init_io have to come after init_readline.
247 # because it and init_io have to come after init_readline.
248 self.init_user_ns()
248 self.init_user_ns()
249 self.init_logger()
249 self.init_logger()
250 self.init_alias()
250 self.init_alias()
251 self.init_builtins()
251 self.init_builtins()
252
252
253 # pre_config_initialization
253 # pre_config_initialization
254 self.init_shadow_hist()
254 self.init_shadow_hist()
255
255
256 # The next section should contain averything that was in ipmaker.
256 # The next section should contain averything that was in ipmaker.
257 self.init_logstart()
257 self.init_logstart()
258
258
259 # The following was in post_config_initialization
259 # The following was in post_config_initialization
260 self.init_inspector()
260 self.init_inspector()
261 # init_readline() must come before init_io(), because init_io uses
261 # init_readline() must come before init_io(), because init_io uses
262 # readline related things.
262 # readline related things.
263 self.init_readline()
263 self.init_readline()
264 # TODO: init_io() needs to happen before init_traceback handlers
264 # TODO: init_io() needs to happen before init_traceback handlers
265 # because the traceback handlers hardcode the stdout/stderr streams.
265 # because the traceback handlers hardcode the stdout/stderr streams.
266 # This logic in in debugger.Pdb and should eventually be changed.
266 # This logic in in debugger.Pdb and should eventually be changed.
267 self.init_io()
267 self.init_io()
268 self.init_traceback_handlers(custom_exceptions)
268 self.init_traceback_handlers(custom_exceptions)
269 self.init_prompts()
269 self.init_prompts()
270 self.init_displayhook()
270 self.init_displayhook()
271 self.init_reload_doctest()
271 self.init_reload_doctest()
272 self.init_magics()
272 self.init_magics()
273 self.init_pdb()
273 self.init_pdb()
274 self.init_extension_manager()
274 self.init_extension_manager()
275 self.init_plugin_manager()
275 self.init_plugin_manager()
276 self.init_payload()
276 self.init_payload()
277 self.hooks.late_startup_hook()
277 self.hooks.late_startup_hook()
278
278
279 @classmethod
279 @classmethod
280 def instance(cls, *args, **kwargs):
280 def instance(cls, *args, **kwargs):
281 """Returns a global InteractiveShell instance."""
281 """Returns a global InteractiveShell instance."""
282 if cls._instance is None:
282 if cls._instance is None:
283 inst = cls(*args, **kwargs)
283 inst = cls(*args, **kwargs)
284 # Now make sure that the instance will also be returned by
284 # Now make sure that the instance will also be returned by
285 # the subclasses instance attribute.
285 # the subclasses instance attribute.
286 for subclass in cls.mro():
286 for subclass in cls.mro():
287 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
287 if issubclass(cls, subclass) and issubclass(subclass, InteractiveShell):
288 subclass._instance = inst
288 subclass._instance = inst
289 else:
289 else:
290 break
290 break
291 if isinstance(cls._instance, cls):
291 if isinstance(cls._instance, cls):
292 return cls._instance
292 return cls._instance
293 else:
293 else:
294 raise MultipleInstanceError(
294 raise MultipleInstanceError(
295 'Multiple incompatible subclass instances of '
295 'Multiple incompatible subclass instances of '
296 'InteractiveShell are being created.'
296 'InteractiveShell are being created.'
297 )
297 )
298
298
299 @classmethod
299 @classmethod
300 def initialized(cls):
300 def initialized(cls):
301 return hasattr(cls, "_instance")
301 return hasattr(cls, "_instance")
302
302
303 def get_ipython(self):
303 def get_ipython(self):
304 """Return the currently running IPython instance."""
304 """Return the currently running IPython instance."""
305 return self
305 return self
306
306
307 #-------------------------------------------------------------------------
307 #-------------------------------------------------------------------------
308 # Trait changed handlers
308 # Trait changed handlers
309 #-------------------------------------------------------------------------
309 #-------------------------------------------------------------------------
310
310
311 def _ipython_dir_changed(self, name, new):
311 def _ipython_dir_changed(self, name, new):
312 if not os.path.isdir(new):
312 if not os.path.isdir(new):
313 os.makedirs(new, mode = 0777)
313 os.makedirs(new, mode = 0777)
314
314
315 def set_autoindent(self,value=None):
315 def set_autoindent(self,value=None):
316 """Set the autoindent flag, checking for readline support.
316 """Set the autoindent flag, checking for readline support.
317
317
318 If called with no arguments, it acts as a toggle."""
318 If called with no arguments, it acts as a toggle."""
319
319
320 if not self.has_readline:
320 if not self.has_readline:
321 if os.name == 'posix':
321 if os.name == 'posix':
322 warn("The auto-indent feature requires the readline library")
322 warn("The auto-indent feature requires the readline library")
323 self.autoindent = 0
323 self.autoindent = 0
324 return
324 return
325 if value is None:
325 if value is None:
326 self.autoindent = not self.autoindent
326 self.autoindent = not self.autoindent
327 else:
327 else:
328 self.autoindent = value
328 self.autoindent = value
329
329
330 #-------------------------------------------------------------------------
330 #-------------------------------------------------------------------------
331 # init_* methods called by __init__
331 # init_* methods called by __init__
332 #-------------------------------------------------------------------------
332 #-------------------------------------------------------------------------
333
333
334 def init_ipython_dir(self, ipython_dir):
334 def init_ipython_dir(self, ipython_dir):
335 if ipython_dir is not None:
335 if ipython_dir is not None:
336 self.ipython_dir = ipython_dir
336 self.ipython_dir = ipython_dir
337 self.config.Global.ipython_dir = self.ipython_dir
337 self.config.Global.ipython_dir = self.ipython_dir
338 return
338 return
339
339
340 if hasattr(self.config.Global, 'ipython_dir'):
340 if hasattr(self.config.Global, 'ipython_dir'):
341 self.ipython_dir = self.config.Global.ipython_dir
341 self.ipython_dir = self.config.Global.ipython_dir
342 else:
342 else:
343 self.ipython_dir = get_ipython_dir()
343 self.ipython_dir = get_ipython_dir()
344
344
345 # All children can just read this
345 # All children can just read this
346 self.config.Global.ipython_dir = self.ipython_dir
346 self.config.Global.ipython_dir = self.ipython_dir
347
347
348 def init_instance_attrs(self):
348 def init_instance_attrs(self):
349 self.more = False
349 self.more = False
350
350
351 # command compiler
351 # command compiler
352 self.compile = codeop.CommandCompiler()
352 self.compile = codeop.CommandCompiler()
353
353
354 # User input buffer
354 # User input buffer
355 self.buffer = []
355 self.buffer = []
356
356
357 # Make an empty namespace, which extension writers can rely on both
357 # Make an empty namespace, which extension writers can rely on both
358 # existing and NEVER being used by ipython itself. This gives them a
358 # existing and NEVER being used by ipython itself. This gives them a
359 # convenient location for storing additional information and state
359 # convenient location for storing additional information and state
360 # their extensions may require, without fear of collisions with other
360 # their extensions may require, without fear of collisions with other
361 # ipython names that may develop later.
361 # ipython names that may develop later.
362 self.meta = Struct()
362 self.meta = Struct()
363
363
364 # Object variable to store code object waiting execution. This is
364 # Object variable to store code object waiting execution. This is
365 # used mainly by the multithreaded shells, but it can come in handy in
365 # used mainly by the multithreaded shells, but it can come in handy in
366 # other situations. No need to use a Queue here, since it's a single
366 # other situations. No need to use a Queue here, since it's a single
367 # item which gets cleared once run.
367 # item which gets cleared once run.
368 self.code_to_run = None
368 self.code_to_run = None
369
369
370 # Temporary files used for various purposes. Deleted at exit.
370 # Temporary files used for various purposes. Deleted at exit.
371 self.tempfiles = []
371 self.tempfiles = []
372
372
373 # Keep track of readline usage (later set by init_readline)
373 # Keep track of readline usage (later set by init_readline)
374 self.has_readline = False
374 self.has_readline = False
375
375
376 # keep track of where we started running (mainly for crash post-mortem)
376 # keep track of where we started running (mainly for crash post-mortem)
377 # This is not being used anywhere currently.
377 # This is not being used anywhere currently.
378 self.starting_dir = os.getcwd()
378 self.starting_dir = os.getcwd()
379
379
380 # Indentation management
380 # Indentation management
381 self.indent_current_nsp = 0
381 self.indent_current_nsp = 0
382
382
383 def init_encoding(self):
383 def init_encoding(self):
384 # Get system encoding at startup time. Certain terminals (like Emacs
384 # Get system encoding at startup time. Certain terminals (like Emacs
385 # under Win32 have it set to None, and we need to have a known valid
385 # under Win32 have it set to None, and we need to have a known valid
386 # encoding to use in the raw_input() method
386 # encoding to use in the raw_input() method
387 try:
387 try:
388 self.stdin_encoding = sys.stdin.encoding or 'ascii'
388 self.stdin_encoding = sys.stdin.encoding or 'ascii'
389 except AttributeError:
389 except AttributeError:
390 self.stdin_encoding = 'ascii'
390 self.stdin_encoding = 'ascii'
391
391
392 def init_syntax_highlighting(self):
392 def init_syntax_highlighting(self):
393 # Python source parser/formatter for syntax highlighting
393 # Python source parser/formatter for syntax highlighting
394 pyformat = PyColorize.Parser().format
394 pyformat = PyColorize.Parser().format
395 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
395 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
396
396
397 def init_pushd_popd_magic(self):
397 def init_pushd_popd_magic(self):
398 # for pushd/popd management
398 # for pushd/popd management
399 try:
399 try:
400 self.home_dir = get_home_dir()
400 self.home_dir = get_home_dir()
401 except HomeDirError, msg:
401 except HomeDirError, msg:
402 fatal(msg)
402 fatal(msg)
403
403
404 self.dir_stack = []
404 self.dir_stack = []
405
405
406 def init_logger(self):
406 def init_logger(self):
407 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
407 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
408 # local shortcut, this is used a LOT
408 # local shortcut, this is used a LOT
409 self.log = self.logger.log
409 self.log = self.logger.log
410
410
411 def init_logstart(self):
411 def init_logstart(self):
412 if self.logappend:
412 if self.logappend:
413 self.magic_logstart(self.logappend + ' append')
413 self.magic_logstart(self.logappend + ' append')
414 elif self.logfile:
414 elif self.logfile:
415 self.magic_logstart(self.logfile)
415 self.magic_logstart(self.logfile)
416 elif self.logstart:
416 elif self.logstart:
417 self.magic_logstart()
417 self.magic_logstart()
418
418
419 def init_builtins(self):
419 def init_builtins(self):
420 self.builtin_trap = BuiltinTrap(shell=self)
420 self.builtin_trap = BuiltinTrap(shell=self)
421
421
422 def init_inspector(self):
422 def init_inspector(self):
423 # Object inspector
423 # Object inspector
424 self.inspector = oinspect.Inspector(oinspect.InspectColors,
424 self.inspector = oinspect.Inspector(oinspect.InspectColors,
425 PyColorize.ANSICodeColors,
425 PyColorize.ANSICodeColors,
426 'NoColor',
426 'NoColor',
427 self.object_info_string_level)
427 self.object_info_string_level)
428
428
429 def init_io(self):
429 def init_io(self):
430 import IPython.utils.io
430 import IPython.utils.io
431 if sys.platform == 'win32' and self.has_readline:
431 if sys.platform == 'win32' and self.has_readline:
432 Term = io.IOTerm(
432 Term = io.IOTerm(
433 cout=self.readline._outputfile,cerr=self.readline._outputfile
433 cout=self.readline._outputfile,cerr=self.readline._outputfile
434 )
434 )
435 else:
435 else:
436 Term = io.IOTerm()
436 Term = io.IOTerm()
437 io.Term = Term
437 io.Term = Term
438
438
439 def init_prompts(self):
439 def init_prompts(self):
440 # TODO: This is a pass for now because the prompts are managed inside
440 # TODO: This is a pass for now because the prompts are managed inside
441 # the DisplayHook. Once there is a separate prompt manager, this
441 # the DisplayHook. Once there is a separate prompt manager, this
442 # will initialize that object and all prompt related information.
442 # will initialize that object and all prompt related information.
443 pass
443 pass
444
444
445 def init_displayhook(self):
445 def init_displayhook(self):
446 # Initialize displayhook, set in/out prompts and printing system
446 # Initialize displayhook, set in/out prompts and printing system
447 self.displayhook = self.displayhook_class(
447 self.displayhook = self.displayhook_class(
448 shell=self,
448 shell=self,
449 cache_size=self.cache_size,
449 cache_size=self.cache_size,
450 input_sep = self.separate_in,
450 input_sep = self.separate_in,
451 output_sep = self.separate_out,
451 output_sep = self.separate_out,
452 output_sep2 = self.separate_out2,
452 output_sep2 = self.separate_out2,
453 ps1 = self.prompt_in1,
453 ps1 = self.prompt_in1,
454 ps2 = self.prompt_in2,
454 ps2 = self.prompt_in2,
455 ps_out = self.prompt_out,
455 ps_out = self.prompt_out,
456 pad_left = self.prompts_pad_left
456 pad_left = self.prompts_pad_left
457 )
457 )
458 # This is a context manager that installs/revmoes the displayhook at
458 # This is a context manager that installs/revmoes the displayhook at
459 # the appropriate time.
459 # the appropriate time.
460 self.display_trap = DisplayTrap(hook=self.displayhook)
460 self.display_trap = DisplayTrap(hook=self.displayhook)
461
461
462 def init_reload_doctest(self):
462 def init_reload_doctest(self):
463 # Do a proper resetting of doctest, including the necessary displayhook
463 # Do a proper resetting of doctest, including the necessary displayhook
464 # monkeypatching
464 # monkeypatching
465 try:
465 try:
466 doctest_reload()
466 doctest_reload()
467 except ImportError:
467 except ImportError:
468 warn("doctest module does not exist.")
468 warn("doctest module does not exist.")
469
469
470 #-------------------------------------------------------------------------
470 #-------------------------------------------------------------------------
471 # Things related to injections into the sys module
471 # Things related to injections into the sys module
472 #-------------------------------------------------------------------------
472 #-------------------------------------------------------------------------
473
473
474 def save_sys_module_state(self):
474 def save_sys_module_state(self):
475 """Save the state of hooks in the sys module.
475 """Save the state of hooks in the sys module.
476
476
477 This has to be called after self.user_ns is created.
477 This has to be called after self.user_ns is created.
478 """
478 """
479 self._orig_sys_module_state = {}
479 self._orig_sys_module_state = {}
480 self._orig_sys_module_state['stdin'] = sys.stdin
480 self._orig_sys_module_state['stdin'] = sys.stdin
481 self._orig_sys_module_state['stdout'] = sys.stdout
481 self._orig_sys_module_state['stdout'] = sys.stdout
482 self._orig_sys_module_state['stderr'] = sys.stderr
482 self._orig_sys_module_state['stderr'] = sys.stderr
483 self._orig_sys_module_state['excepthook'] = sys.excepthook
483 self._orig_sys_module_state['excepthook'] = sys.excepthook
484 try:
484 try:
485 self._orig_sys_modules_main_name = self.user_ns['__name__']
485 self._orig_sys_modules_main_name = self.user_ns['__name__']
486 except KeyError:
486 except KeyError:
487 pass
487 pass
488
488
489 def restore_sys_module_state(self):
489 def restore_sys_module_state(self):
490 """Restore the state of the sys module."""
490 """Restore the state of the sys module."""
491 try:
491 try:
492 for k, v in self._orig_sys_module_state.items():
492 for k, v in self._orig_sys_module_state.items():
493 setattr(sys, k, v)
493 setattr(sys, k, v)
494 except AttributeError:
494 except AttributeError:
495 pass
495 pass
496 try:
496 try:
497 delattr(sys, 'ipcompleter')
497 delattr(sys, 'ipcompleter')
498 except AttributeError:
498 except AttributeError:
499 pass
499 pass
500 # Reset what what done in self.init_sys_modules
500 # Reset what what done in self.init_sys_modules
501 try:
501 try:
502 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
502 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
503 except (AttributeError, KeyError):
503 except (AttributeError, KeyError):
504 pass
504 pass
505
505
506 #-------------------------------------------------------------------------
506 #-------------------------------------------------------------------------
507 # Things related to hooks
507 # Things related to hooks
508 #-------------------------------------------------------------------------
508 #-------------------------------------------------------------------------
509
509
510 def init_hooks(self):
510 def init_hooks(self):
511 # hooks holds pointers used for user-side customizations
511 # hooks holds pointers used for user-side customizations
512 self.hooks = Struct()
512 self.hooks = Struct()
513
513
514 self.strdispatchers = {}
514 self.strdispatchers = {}
515
515
516 # Set all default hooks, defined in the IPython.hooks module.
516 # Set all default hooks, defined in the IPython.hooks module.
517 hooks = IPython.core.hooks
517 hooks = IPython.core.hooks
518 for hook_name in hooks.__all__:
518 for hook_name in hooks.__all__:
519 # default hooks have priority 100, i.e. low; user hooks should have
519 # default hooks have priority 100, i.e. low; user hooks should have
520 # 0-100 priority
520 # 0-100 priority
521 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
521 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
522
522
523 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
523 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
524 """set_hook(name,hook) -> sets an internal IPython hook.
524 """set_hook(name,hook) -> sets an internal IPython hook.
525
525
526 IPython exposes some of its internal API as user-modifiable hooks. By
526 IPython exposes some of its internal API as user-modifiable hooks. By
527 adding your function to one of these hooks, you can modify IPython's
527 adding your function to one of these hooks, you can modify IPython's
528 behavior to call at runtime your own routines."""
528 behavior to call at runtime your own routines."""
529
529
530 # At some point in the future, this should validate the hook before it
530 # At some point in the future, this should validate the hook before it
531 # accepts it. Probably at least check that the hook takes the number
531 # accepts it. Probably at least check that the hook takes the number
532 # of args it's supposed to.
532 # of args it's supposed to.
533
533
534 f = new.instancemethod(hook,self,self.__class__)
534 f = new.instancemethod(hook,self,self.__class__)
535
535
536 # check if the hook is for strdispatcher first
536 # check if the hook is for strdispatcher first
537 if str_key is not None:
537 if str_key is not None:
538 sdp = self.strdispatchers.get(name, StrDispatch())
538 sdp = self.strdispatchers.get(name, StrDispatch())
539 sdp.add_s(str_key, f, priority )
539 sdp.add_s(str_key, f, priority )
540 self.strdispatchers[name] = sdp
540 self.strdispatchers[name] = sdp
541 return
541 return
542 if re_key is not None:
542 if re_key is not None:
543 sdp = self.strdispatchers.get(name, StrDispatch())
543 sdp = self.strdispatchers.get(name, StrDispatch())
544 sdp.add_re(re.compile(re_key), f, priority )
544 sdp.add_re(re.compile(re_key), f, priority )
545 self.strdispatchers[name] = sdp
545 self.strdispatchers[name] = sdp
546 return
546 return
547
547
548 dp = getattr(self.hooks, name, None)
548 dp = getattr(self.hooks, name, None)
549 if name not in IPython.core.hooks.__all__:
549 if name not in IPython.core.hooks.__all__:
550 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
550 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
551 if not dp:
551 if not dp:
552 dp = IPython.core.hooks.CommandChainDispatcher()
552 dp = IPython.core.hooks.CommandChainDispatcher()
553
553
554 try:
554 try:
555 dp.add(f,priority)
555 dp.add(f,priority)
556 except AttributeError:
556 except AttributeError:
557 # it was not commandchain, plain old func - replace
557 # it was not commandchain, plain old func - replace
558 dp = f
558 dp = f
559
559
560 setattr(self.hooks,name, dp)
560 setattr(self.hooks,name, dp)
561
561
562 #-------------------------------------------------------------------------
562 #-------------------------------------------------------------------------
563 # Things related to the "main" module
563 # Things related to the "main" module
564 #-------------------------------------------------------------------------
564 #-------------------------------------------------------------------------
565
565
566 def new_main_mod(self,ns=None):
566 def new_main_mod(self,ns=None):
567 """Return a new 'main' module object for user code execution.
567 """Return a new 'main' module object for user code execution.
568 """
568 """
569 main_mod = self._user_main_module
569 main_mod = self._user_main_module
570 init_fakemod_dict(main_mod,ns)
570 init_fakemod_dict(main_mod,ns)
571 return main_mod
571 return main_mod
572
572
573 def cache_main_mod(self,ns,fname):
573 def cache_main_mod(self,ns,fname):
574 """Cache a main module's namespace.
574 """Cache a main module's namespace.
575
575
576 When scripts are executed via %run, we must keep a reference to the
576 When scripts are executed via %run, we must keep a reference to the
577 namespace of their __main__ module (a FakeModule instance) around so
577 namespace of their __main__ module (a FakeModule instance) around so
578 that Python doesn't clear it, rendering objects defined therein
578 that Python doesn't clear it, rendering objects defined therein
579 useless.
579 useless.
580
580
581 This method keeps said reference in a private dict, keyed by the
581 This method keeps said reference in a private dict, keyed by the
582 absolute path of the module object (which corresponds to the script
582 absolute path of the module object (which corresponds to the script
583 path). This way, for multiple executions of the same script we only
583 path). This way, for multiple executions of the same script we only
584 keep one copy of the namespace (the last one), thus preventing memory
584 keep one copy of the namespace (the last one), thus preventing memory
585 leaks from old references while allowing the objects from the last
585 leaks from old references while allowing the objects from the last
586 execution to be accessible.
586 execution to be accessible.
587
587
588 Note: we can not allow the actual FakeModule instances to be deleted,
588 Note: we can not allow the actual FakeModule instances to be deleted,
589 because of how Python tears down modules (it hard-sets all their
589 because of how Python tears down modules (it hard-sets all their
590 references to None without regard for reference counts). This method
590 references to None without regard for reference counts). This method
591 must therefore make a *copy* of the given namespace, to allow the
591 must therefore make a *copy* of the given namespace, to allow the
592 original module's __dict__ to be cleared and reused.
592 original module's __dict__ to be cleared and reused.
593
593
594
594
595 Parameters
595 Parameters
596 ----------
596 ----------
597 ns : a namespace (a dict, typically)
597 ns : a namespace (a dict, typically)
598
598
599 fname : str
599 fname : str
600 Filename associated with the namespace.
600 Filename associated with the namespace.
601
601
602 Examples
602 Examples
603 --------
603 --------
604
604
605 In [10]: import IPython
605 In [10]: import IPython
606
606
607 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
607 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
608
608
609 In [12]: IPython.__file__ in _ip._main_ns_cache
609 In [12]: IPython.__file__ in _ip._main_ns_cache
610 Out[12]: True
610 Out[12]: True
611 """
611 """
612 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
612 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
613
613
614 def clear_main_mod_cache(self):
614 def clear_main_mod_cache(self):
615 """Clear the cache of main modules.
615 """Clear the cache of main modules.
616
616
617 Mainly for use by utilities like %reset.
617 Mainly for use by utilities like %reset.
618
618
619 Examples
619 Examples
620 --------
620 --------
621
621
622 In [15]: import IPython
622 In [15]: import IPython
623
623
624 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
624 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
625
625
626 In [17]: len(_ip._main_ns_cache) > 0
626 In [17]: len(_ip._main_ns_cache) > 0
627 Out[17]: True
627 Out[17]: True
628
628
629 In [18]: _ip.clear_main_mod_cache()
629 In [18]: _ip.clear_main_mod_cache()
630
630
631 In [19]: len(_ip._main_ns_cache) == 0
631 In [19]: len(_ip._main_ns_cache) == 0
632 Out[19]: True
632 Out[19]: True
633 """
633 """
634 self._main_ns_cache.clear()
634 self._main_ns_cache.clear()
635
635
636 #-------------------------------------------------------------------------
636 #-------------------------------------------------------------------------
637 # Things related to debugging
637 # Things related to debugging
638 #-------------------------------------------------------------------------
638 #-------------------------------------------------------------------------
639
639
640 def init_pdb(self):
640 def init_pdb(self):
641 # Set calling of pdb on exceptions
641 # Set calling of pdb on exceptions
642 # self.call_pdb is a property
642 # self.call_pdb is a property
643 self.call_pdb = self.pdb
643 self.call_pdb = self.pdb
644
644
645 def _get_call_pdb(self):
645 def _get_call_pdb(self):
646 return self._call_pdb
646 return self._call_pdb
647
647
648 def _set_call_pdb(self,val):
648 def _set_call_pdb(self,val):
649
649
650 if val not in (0,1,False,True):
650 if val not in (0,1,False,True):
651 raise ValueError,'new call_pdb value must be boolean'
651 raise ValueError,'new call_pdb value must be boolean'
652
652
653 # store value in instance
653 # store value in instance
654 self._call_pdb = val
654 self._call_pdb = val
655
655
656 # notify the actual exception handlers
656 # notify the actual exception handlers
657 self.InteractiveTB.call_pdb = val
657 self.InteractiveTB.call_pdb = val
658
658
659 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
659 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
660 'Control auto-activation of pdb at exceptions')
660 'Control auto-activation of pdb at exceptions')
661
661
662 def debugger(self,force=False):
662 def debugger(self,force=False):
663 """Call the pydb/pdb debugger.
663 """Call the pydb/pdb debugger.
664
664
665 Keywords:
665 Keywords:
666
666
667 - force(False): by default, this routine checks the instance call_pdb
667 - force(False): by default, this routine checks the instance call_pdb
668 flag and does not actually invoke the debugger if the flag is false.
668 flag and does not actually invoke the debugger if the flag is false.
669 The 'force' option forces the debugger to activate even if the flag
669 The 'force' option forces the debugger to activate even if the flag
670 is false.
670 is false.
671 """
671 """
672
672
673 if not (force or self.call_pdb):
673 if not (force or self.call_pdb):
674 return
674 return
675
675
676 if not hasattr(sys,'last_traceback'):
676 if not hasattr(sys,'last_traceback'):
677 error('No traceback has been produced, nothing to debug.')
677 error('No traceback has been produced, nothing to debug.')
678 return
678 return
679
679
680 # use pydb if available
680 # use pydb if available
681 if debugger.has_pydb:
681 if debugger.has_pydb:
682 from pydb import pm
682 from pydb import pm
683 else:
683 else:
684 # fallback to our internal debugger
684 # fallback to our internal debugger
685 pm = lambda : self.InteractiveTB.debugger(force=True)
685 pm = lambda : self.InteractiveTB.debugger(force=True)
686 self.history_saving_wrapper(pm)()
686 self.history_saving_wrapper(pm)()
687
687
688 #-------------------------------------------------------------------------
688 #-------------------------------------------------------------------------
689 # Things related to IPython's various namespaces
689 # Things related to IPython's various namespaces
690 #-------------------------------------------------------------------------
690 #-------------------------------------------------------------------------
691
691
692 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
692 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
693 # Create the namespace where the user will operate. user_ns is
693 # Create the namespace where the user will operate. user_ns is
694 # normally the only one used, and it is passed to the exec calls as
694 # normally the only one used, and it is passed to the exec calls as
695 # the locals argument. But we do carry a user_global_ns namespace
695 # the locals argument. But we do carry a user_global_ns namespace
696 # given as the exec 'globals' argument, This is useful in embedding
696 # given as the exec 'globals' argument, This is useful in embedding
697 # situations where the ipython shell opens in a context where the
697 # situations where the ipython shell opens in a context where the
698 # distinction between locals and globals is meaningful. For
698 # distinction between locals and globals is meaningful. For
699 # non-embedded contexts, it is just the same object as the user_ns dict.
699 # non-embedded contexts, it is just the same object as the user_ns dict.
700
700
701 # FIXME. For some strange reason, __builtins__ is showing up at user
701 # FIXME. For some strange reason, __builtins__ is showing up at user
702 # level as a dict instead of a module. This is a manual fix, but I
702 # level as a dict instead of a module. This is a manual fix, but I
703 # should really track down where the problem is coming from. Alex
703 # should really track down where the problem is coming from. Alex
704 # Schmolck reported this problem first.
704 # Schmolck reported this problem first.
705
705
706 # A useful post by Alex Martelli on this topic:
706 # A useful post by Alex Martelli on this topic:
707 # Re: inconsistent value from __builtins__
707 # Re: inconsistent value from __builtins__
708 # Von: Alex Martelli <aleaxit@yahoo.com>
708 # Von: Alex Martelli <aleaxit@yahoo.com>
709 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
709 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
710 # Gruppen: comp.lang.python
710 # Gruppen: comp.lang.python
711
711
712 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
712 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
713 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
713 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
714 # > <type 'dict'>
714 # > <type 'dict'>
715 # > >>> print type(__builtins__)
715 # > >>> print type(__builtins__)
716 # > <type 'module'>
716 # > <type 'module'>
717 # > Is this difference in return value intentional?
717 # > Is this difference in return value intentional?
718
718
719 # Well, it's documented that '__builtins__' can be either a dictionary
719 # Well, it's documented that '__builtins__' can be either a dictionary
720 # or a module, and it's been that way for a long time. Whether it's
720 # or a module, and it's been that way for a long time. Whether it's
721 # intentional (or sensible), I don't know. In any case, the idea is
721 # intentional (or sensible), I don't know. In any case, the idea is
722 # that if you need to access the built-in namespace directly, you
722 # that if you need to access the built-in namespace directly, you
723 # should start with "import __builtin__" (note, no 's') which will
723 # should start with "import __builtin__" (note, no 's') which will
724 # definitely give you a module. Yeah, it's somewhat confusing:-(.
724 # definitely give you a module. Yeah, it's somewhat confusing:-(.
725
725
726 # These routines return properly built dicts as needed by the rest of
726 # These routines return properly built dicts as needed by the rest of
727 # the code, and can also be used by extension writers to generate
727 # the code, and can also be used by extension writers to generate
728 # properly initialized namespaces.
728 # properly initialized namespaces.
729 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
729 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
730
730
731 # Assign namespaces
731 # Assign namespaces
732 # This is the namespace where all normal user variables live
732 # This is the namespace where all normal user variables live
733 self.user_ns = user_ns
733 self.user_ns = user_ns
734 self.user_global_ns = user_global_ns
734 self.user_global_ns = user_global_ns
735
735
736 # An auxiliary namespace that checks what parts of the user_ns were
736 # An auxiliary namespace that checks what parts of the user_ns were
737 # loaded at startup, so we can list later only variables defined in
737 # loaded at startup, so we can list later only variables defined in
738 # actual interactive use. Since it is always a subset of user_ns, it
738 # actual interactive use. Since it is always a subset of user_ns, it
739 # doesn't need to be separately tracked in the ns_table.
739 # doesn't need to be separately tracked in the ns_table.
740 self.user_ns_hidden = {}
740 self.user_ns_hidden = {}
741
741
742 # A namespace to keep track of internal data structures to prevent
742 # A namespace to keep track of internal data structures to prevent
743 # them from cluttering user-visible stuff. Will be updated later
743 # them from cluttering user-visible stuff. Will be updated later
744 self.internal_ns = {}
744 self.internal_ns = {}
745
745
746 # Now that FakeModule produces a real module, we've run into a nasty
746 # Now that FakeModule produces a real module, we've run into a nasty
747 # problem: after script execution (via %run), the module where the user
747 # problem: after script execution (via %run), the module where the user
748 # code ran is deleted. Now that this object is a true module (needed
748 # code ran is deleted. Now that this object is a true module (needed
749 # so docetst and other tools work correctly), the Python module
749 # so docetst and other tools work correctly), the Python module
750 # teardown mechanism runs over it, and sets to None every variable
750 # teardown mechanism runs over it, and sets to None every variable
751 # present in that module. Top-level references to objects from the
751 # present in that module. Top-level references to objects from the
752 # script survive, because the user_ns is updated with them. However,
752 # script survive, because the user_ns is updated with them. However,
753 # calling functions defined in the script that use other things from
753 # calling functions defined in the script that use other things from
754 # the script will fail, because the function's closure had references
754 # the script will fail, because the function's closure had references
755 # to the original objects, which are now all None. So we must protect
755 # to the original objects, which are now all None. So we must protect
756 # these modules from deletion by keeping a cache.
756 # these modules from deletion by keeping a cache.
757 #
757 #
758 # To avoid keeping stale modules around (we only need the one from the
758 # To avoid keeping stale modules around (we only need the one from the
759 # last run), we use a dict keyed with the full path to the script, so
759 # last run), we use a dict keyed with the full path to the script, so
760 # only the last version of the module is held in the cache. Note,
760 # only the last version of the module is held in the cache. Note,
761 # however, that we must cache the module *namespace contents* (their
761 # however, that we must cache the module *namespace contents* (their
762 # __dict__). Because if we try to cache the actual modules, old ones
762 # __dict__). Because if we try to cache the actual modules, old ones
763 # (uncached) could be destroyed while still holding references (such as
763 # (uncached) could be destroyed while still holding references (such as
764 # those held by GUI objects that tend to be long-lived)>
764 # those held by GUI objects that tend to be long-lived)>
765 #
765 #
766 # The %reset command will flush this cache. See the cache_main_mod()
766 # The %reset command will flush this cache. See the cache_main_mod()
767 # and clear_main_mod_cache() methods for details on use.
767 # and clear_main_mod_cache() methods for details on use.
768
768
769 # This is the cache used for 'main' namespaces
769 # This is the cache used for 'main' namespaces
770 self._main_ns_cache = {}
770 self._main_ns_cache = {}
771 # And this is the single instance of FakeModule whose __dict__ we keep
771 # And this is the single instance of FakeModule whose __dict__ we keep
772 # copying and clearing for reuse on each %run
772 # copying and clearing for reuse on each %run
773 self._user_main_module = FakeModule()
773 self._user_main_module = FakeModule()
774
774
775 # A table holding all the namespaces IPython deals with, so that
775 # A table holding all the namespaces IPython deals with, so that
776 # introspection facilities can search easily.
776 # introspection facilities can search easily.
777 self.ns_table = {'user':user_ns,
777 self.ns_table = {'user':user_ns,
778 'user_global':user_global_ns,
778 'user_global':user_global_ns,
779 'internal':self.internal_ns,
779 'internal':self.internal_ns,
780 'builtin':__builtin__.__dict__
780 'builtin':__builtin__.__dict__
781 }
781 }
782
782
783 # Similarly, track all namespaces where references can be held and that
783 # Similarly, track all namespaces where references can be held and that
784 # we can safely clear (so it can NOT include builtin). This one can be
784 # we can safely clear (so it can NOT include builtin). This one can be
785 # a simple list.
785 # a simple list.
786 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
786 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
787 self.internal_ns, self._main_ns_cache ]
787 self.internal_ns, self._main_ns_cache ]
788
788
789 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
789 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
790 """Return a valid local and global user interactive namespaces.
790 """Return a valid local and global user interactive namespaces.
791
791
792 This builds a dict with the minimal information needed to operate as a
792 This builds a dict with the minimal information needed to operate as a
793 valid IPython user namespace, which you can pass to the various
793 valid IPython user namespace, which you can pass to the various
794 embedding classes in ipython. The default implementation returns the
794 embedding classes in ipython. The default implementation returns the
795 same dict for both the locals and the globals to allow functions to
795 same dict for both the locals and the globals to allow functions to
796 refer to variables in the namespace. Customized implementations can
796 refer to variables in the namespace. Customized implementations can
797 return different dicts. The locals dictionary can actually be anything
797 return different dicts. The locals dictionary can actually be anything
798 following the basic mapping protocol of a dict, but the globals dict
798 following the basic mapping protocol of a dict, but the globals dict
799 must be a true dict, not even a subclass. It is recommended that any
799 must be a true dict, not even a subclass. It is recommended that any
800 custom object for the locals namespace synchronize with the globals
800 custom object for the locals namespace synchronize with the globals
801 dict somehow.
801 dict somehow.
802
802
803 Raises TypeError if the provided globals namespace is not a true dict.
803 Raises TypeError if the provided globals namespace is not a true dict.
804
804
805 Parameters
805 Parameters
806 ----------
806 ----------
807 user_ns : dict-like, optional
807 user_ns : dict-like, optional
808 The current user namespace. The items in this namespace should
808 The current user namespace. The items in this namespace should
809 be included in the output. If None, an appropriate blank
809 be included in the output. If None, an appropriate blank
810 namespace should be created.
810 namespace should be created.
811 user_global_ns : dict, optional
811 user_global_ns : dict, optional
812 The current user global namespace. The items in this namespace
812 The current user global namespace. The items in this namespace
813 should be included in the output. If None, an appropriate
813 should be included in the output. If None, an appropriate
814 blank namespace should be created.
814 blank namespace should be created.
815
815
816 Returns
816 Returns
817 -------
817 -------
818 A pair of dictionary-like object to be used as the local namespace
818 A pair of dictionary-like object to be used as the local namespace
819 of the interpreter and a dict to be used as the global namespace.
819 of the interpreter and a dict to be used as the global namespace.
820 """
820 """
821
821
822
822
823 # We must ensure that __builtin__ (without the final 's') is always
823 # We must ensure that __builtin__ (without the final 's') is always
824 # available and pointing to the __builtin__ *module*. For more details:
824 # available and pointing to the __builtin__ *module*. For more details:
825 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
825 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
826
826
827 if user_ns is None:
827 if user_ns is None:
828 # Set __name__ to __main__ to better match the behavior of the
828 # Set __name__ to __main__ to better match the behavior of the
829 # normal interpreter.
829 # normal interpreter.
830 user_ns = {'__name__' :'__main__',
830 user_ns = {'__name__' :'__main__',
831 '__builtin__' : __builtin__,
831 '__builtin__' : __builtin__,
832 '__builtins__' : __builtin__,
832 '__builtins__' : __builtin__,
833 }
833 }
834 else:
834 else:
835 user_ns.setdefault('__name__','__main__')
835 user_ns.setdefault('__name__','__main__')
836 user_ns.setdefault('__builtin__',__builtin__)
836 user_ns.setdefault('__builtin__',__builtin__)
837 user_ns.setdefault('__builtins__',__builtin__)
837 user_ns.setdefault('__builtins__',__builtin__)
838
838
839 if user_global_ns is None:
839 if user_global_ns is None:
840 user_global_ns = user_ns
840 user_global_ns = user_ns
841 if type(user_global_ns) is not dict:
841 if type(user_global_ns) is not dict:
842 raise TypeError("user_global_ns must be a true dict; got %r"
842 raise TypeError("user_global_ns must be a true dict; got %r"
843 % type(user_global_ns))
843 % type(user_global_ns))
844
844
845 return user_ns, user_global_ns
845 return user_ns, user_global_ns
846
846
847 def init_sys_modules(self):
847 def init_sys_modules(self):
848 # We need to insert into sys.modules something that looks like a
848 # We need to insert into sys.modules something that looks like a
849 # module but which accesses the IPython namespace, for shelve and
849 # module but which accesses the IPython namespace, for shelve and
850 # pickle to work interactively. Normally they rely on getting
850 # pickle to work interactively. Normally they rely on getting
851 # everything out of __main__, but for embedding purposes each IPython
851 # everything out of __main__, but for embedding purposes each IPython
852 # instance has its own private namespace, so we can't go shoving
852 # instance has its own private namespace, so we can't go shoving
853 # everything into __main__.
853 # everything into __main__.
854
854
855 # note, however, that we should only do this for non-embedded
855 # note, however, that we should only do this for non-embedded
856 # ipythons, which really mimic the __main__.__dict__ with their own
856 # ipythons, which really mimic the __main__.__dict__ with their own
857 # namespace. Embedded instances, on the other hand, should not do
857 # namespace. Embedded instances, on the other hand, should not do
858 # this because they need to manage the user local/global namespaces
858 # this because they need to manage the user local/global namespaces
859 # only, but they live within a 'normal' __main__ (meaning, they
859 # only, but they live within a 'normal' __main__ (meaning, they
860 # shouldn't overtake the execution environment of the script they're
860 # shouldn't overtake the execution environment of the script they're
861 # embedded in).
861 # embedded in).
862
862
863 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
863 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
864
864
865 try:
865 try:
866 main_name = self.user_ns['__name__']
866 main_name = self.user_ns['__name__']
867 except KeyError:
867 except KeyError:
868 raise KeyError('user_ns dictionary MUST have a "__name__" key')
868 raise KeyError('user_ns dictionary MUST have a "__name__" key')
869 else:
869 else:
870 sys.modules[main_name] = FakeModule(self.user_ns)
870 sys.modules[main_name] = FakeModule(self.user_ns)
871
871
872 def init_user_ns(self):
872 def init_user_ns(self):
873 """Initialize all user-visible namespaces to their minimum defaults.
873 """Initialize all user-visible namespaces to their minimum defaults.
874
874
875 Certain history lists are also initialized here, as they effectively
875 Certain history lists are also initialized here, as they effectively
876 act as user namespaces.
876 act as user namespaces.
877
877
878 Notes
878 Notes
879 -----
879 -----
880 All data structures here are only filled in, they are NOT reset by this
880 All data structures here are only filled in, they are NOT reset by this
881 method. If they were not empty before, data will simply be added to
881 method. If they were not empty before, data will simply be added to
882 therm.
882 therm.
883 """
883 """
884 # This function works in two parts: first we put a few things in
884 # This function works in two parts: first we put a few things in
885 # user_ns, and we sync that contents into user_ns_hidden so that these
885 # user_ns, and we sync that contents into user_ns_hidden so that these
886 # initial variables aren't shown by %who. After the sync, we add the
886 # initial variables aren't shown by %who. After the sync, we add the
887 # rest of what we *do* want the user to see with %who even on a new
887 # rest of what we *do* want the user to see with %who even on a new
888 # session (probably nothing, so theye really only see their own stuff)
888 # session (probably nothing, so theye really only see their own stuff)
889
889
890 # The user dict must *always* have a __builtin__ reference to the
890 # The user dict must *always* have a __builtin__ reference to the
891 # Python standard __builtin__ namespace, which must be imported.
891 # Python standard __builtin__ namespace, which must be imported.
892 # This is so that certain operations in prompt evaluation can be
892 # This is so that certain operations in prompt evaluation can be
893 # reliably executed with builtins. Note that we can NOT use
893 # reliably executed with builtins. Note that we can NOT use
894 # __builtins__ (note the 's'), because that can either be a dict or a
894 # __builtins__ (note the 's'), because that can either be a dict or a
895 # module, and can even mutate at runtime, depending on the context
895 # module, and can even mutate at runtime, depending on the context
896 # (Python makes no guarantees on it). In contrast, __builtin__ is
896 # (Python makes no guarantees on it). In contrast, __builtin__ is
897 # always a module object, though it must be explicitly imported.
897 # always a module object, though it must be explicitly imported.
898
898
899 # For more details:
899 # For more details:
900 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
900 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
901 ns = dict(__builtin__ = __builtin__)
901 ns = dict(__builtin__ = __builtin__)
902
902
903 # Put 'help' in the user namespace
903 # Put 'help' in the user namespace
904 try:
904 try:
905 from site import _Helper
905 from site import _Helper
906 ns['help'] = _Helper()
906 ns['help'] = _Helper()
907 except ImportError:
907 except ImportError:
908 warn('help() not available - check site.py')
908 warn('help() not available - check site.py')
909
909
910 # make global variables for user access to the histories
910 # make global variables for user access to the histories
911 ns['_ih'] = self.input_hist
911 ns['_ih'] = self.input_hist
912 ns['_oh'] = self.output_hist
912 ns['_oh'] = self.output_hist
913 ns['_dh'] = self.dir_hist
913 ns['_dh'] = self.dir_hist
914
914
915 ns['_sh'] = shadowns
915 ns['_sh'] = shadowns
916
916
917 # user aliases to input and output histories. These shouldn't show up
917 # user aliases to input and output histories. These shouldn't show up
918 # in %who, as they can have very large reprs.
918 # in %who, as they can have very large reprs.
919 ns['In'] = self.input_hist
919 ns['In'] = self.input_hist
920 ns['Out'] = self.output_hist
920 ns['Out'] = self.output_hist
921
921
922 # Store myself as the public api!!!
922 # Store myself as the public api!!!
923 ns['get_ipython'] = self.get_ipython
923 ns['get_ipython'] = self.get_ipython
924
924
925 # Sync what we've added so far to user_ns_hidden so these aren't seen
925 # Sync what we've added so far to user_ns_hidden so these aren't seen
926 # by %who
926 # by %who
927 self.user_ns_hidden.update(ns)
927 self.user_ns_hidden.update(ns)
928
928
929 # Anything put into ns now would show up in %who. Think twice before
929 # Anything put into ns now would show up in %who. Think twice before
930 # putting anything here, as we really want %who to show the user their
930 # putting anything here, as we really want %who to show the user their
931 # stuff, not our variables.
931 # stuff, not our variables.
932
932
933 # Finally, update the real user's namespace
933 # Finally, update the real user's namespace
934 self.user_ns.update(ns)
934 self.user_ns.update(ns)
935
935
936
936
937 def reset(self):
937 def reset(self):
938 """Clear all internal namespaces.
938 """Clear all internal namespaces.
939
939
940 Note that this is much more aggressive than %reset, since it clears
940 Note that this is much more aggressive than %reset, since it clears
941 fully all namespaces, as well as all input/output lists.
941 fully all namespaces, as well as all input/output lists.
942 """
942 """
943 for ns in self.ns_refs_table:
943 for ns in self.ns_refs_table:
944 ns.clear()
944 ns.clear()
945
945
946 self.alias_manager.clear_aliases()
946 self.alias_manager.clear_aliases()
947
947
948 # Clear input and output histories
948 # Clear input and output histories
949 self.input_hist[:] = []
949 self.input_hist[:] = []
950 self.input_hist_raw[:] = []
950 self.input_hist_raw[:] = []
951 self.output_hist.clear()
951 self.output_hist.clear()
952
952
953 # Restore the user namespaces to minimal usability
953 # Restore the user namespaces to minimal usability
954 self.init_user_ns()
954 self.init_user_ns()
955
955
956 # Restore the default and user aliases
956 # Restore the default and user aliases
957 self.alias_manager.init_aliases()
957 self.alias_manager.init_aliases()
958
958
959 def reset_selective(self, regex=None):
959 def reset_selective(self, regex=None):
960 """Clear selective variables from internal namespaces based on a specified regular expression.
960 """Clear selective variables from internal namespaces based on a specified regular expression.
961
961
962 Parameters
962 Parameters
963 ----------
963 ----------
964 regex : string or compiled pattern, optional
964 regex : string or compiled pattern, optional
965 A regular expression pattern that will be used in searching variable names in the users
965 A regular expression pattern that will be used in searching variable names in the users
966 namespaces.
966 namespaces.
967 """
967 """
968 if regex is not None:
968 if regex is not None:
969 try:
969 try:
970 m = re.compile(regex)
970 m = re.compile(regex)
971 except TypeError:
971 except TypeError:
972 raise TypeError('regex must be a string or compiled pattern')
972 raise TypeError('regex must be a string or compiled pattern')
973 # Search for keys in each namespace that match the given regex
973 # Search for keys in each namespace that match the given regex
974 # If a match is found, delete the key/value pair.
974 # If a match is found, delete the key/value pair.
975 for ns in self.ns_refs_table:
975 for ns in self.ns_refs_table:
976 for var in ns:
976 for var in ns:
977 if m.search(var):
977 if m.search(var):
978 del ns[var]
978 del ns[var]
979
979
980 def push(self, variables, interactive=True):
980 def push(self, variables, interactive=True):
981 """Inject a group of variables into the IPython user namespace.
981 """Inject a group of variables into the IPython user namespace.
982
982
983 Parameters
983 Parameters
984 ----------
984 ----------
985 variables : dict, str or list/tuple of str
985 variables : dict, str or list/tuple of str
986 The variables to inject into the user's namespace. If a dict,
986 The variables to inject into the user's namespace. If a dict,
987 a simple update is done. If a str, the string is assumed to
987 a simple update is done. If a str, the string is assumed to
988 have variable names separated by spaces. A list/tuple of str
988 have variable names separated by spaces. A list/tuple of str
989 can also be used to give the variable names. If just the variable
989 can also be used to give the variable names. If just the variable
990 names are give (list/tuple/str) then the variable values looked
990 names are give (list/tuple/str) then the variable values looked
991 up in the callers frame.
991 up in the callers frame.
992 interactive : bool
992 interactive : bool
993 If True (default), the variables will be listed with the ``who``
993 If True (default), the variables will be listed with the ``who``
994 magic.
994 magic.
995 """
995 """
996 vdict = None
996 vdict = None
997
997
998 # We need a dict of name/value pairs to do namespace updates.
998 # We need a dict of name/value pairs to do namespace updates.
999 if isinstance(variables, dict):
999 if isinstance(variables, dict):
1000 vdict = variables
1000 vdict = variables
1001 elif isinstance(variables, (basestring, list, tuple)):
1001 elif isinstance(variables, (basestring, list, tuple)):
1002 if isinstance(variables, basestring):
1002 if isinstance(variables, basestring):
1003 vlist = variables.split()
1003 vlist = variables.split()
1004 else:
1004 else:
1005 vlist = variables
1005 vlist = variables
1006 vdict = {}
1006 vdict = {}
1007 cf = sys._getframe(1)
1007 cf = sys._getframe(1)
1008 for name in vlist:
1008 for name in vlist:
1009 try:
1009 try:
1010 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1010 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1011 except:
1011 except:
1012 print ('Could not get variable %s from %s' %
1012 print ('Could not get variable %s from %s' %
1013 (name,cf.f_code.co_name))
1013 (name,cf.f_code.co_name))
1014 else:
1014 else:
1015 raise ValueError('variables must be a dict/str/list/tuple')
1015 raise ValueError('variables must be a dict/str/list/tuple')
1016
1016
1017 # Propagate variables to user namespace
1017 # Propagate variables to user namespace
1018 self.user_ns.update(vdict)
1018 self.user_ns.update(vdict)
1019
1019
1020 # And configure interactive visibility
1020 # And configure interactive visibility
1021 config_ns = self.user_ns_hidden
1021 config_ns = self.user_ns_hidden
1022 if interactive:
1022 if interactive:
1023 for name, val in vdict.iteritems():
1023 for name, val in vdict.iteritems():
1024 config_ns.pop(name, None)
1024 config_ns.pop(name, None)
1025 else:
1025 else:
1026 for name,val in vdict.iteritems():
1026 for name,val in vdict.iteritems():
1027 config_ns[name] = val
1027 config_ns[name] = val
1028
1028
1029 #-------------------------------------------------------------------------
1029 #-------------------------------------------------------------------------
1030 # Things related to history management
1030 # Things related to history management
1031 #-------------------------------------------------------------------------
1031 #-------------------------------------------------------------------------
1032
1032
1033 def init_history(self):
1033 def init_history(self):
1034 # List of input with multi-line handling.
1034 # List of input with multi-line handling.
1035 self.input_hist = InputList()
1035 self.input_hist = InputList()
1036 # This one will hold the 'raw' input history, without any
1036 # This one will hold the 'raw' input history, without any
1037 # pre-processing. This will allow users to retrieve the input just as
1037 # pre-processing. This will allow users to retrieve the input just as
1038 # it was exactly typed in by the user, with %hist -r.
1038 # it was exactly typed in by the user, with %hist -r.
1039 self.input_hist_raw = InputList()
1039 self.input_hist_raw = InputList()
1040
1040
1041 # list of visited directories
1041 # list of visited directories
1042 try:
1042 try:
1043 self.dir_hist = [os.getcwd()]
1043 self.dir_hist = [os.getcwd()]
1044 except OSError:
1044 except OSError:
1045 self.dir_hist = []
1045 self.dir_hist = []
1046
1046
1047 # dict of output history
1047 # dict of output history
1048 self.output_hist = {}
1048 self.output_hist = {}
1049
1049
1050 # Now the history file
1050 # Now the history file
1051 if self.profile:
1051 if self.profile:
1052 histfname = 'history-%s' % self.profile
1052 histfname = 'history-%s' % self.profile
1053 else:
1053 else:
1054 histfname = 'history'
1054 histfname = 'history'
1055 self.histfile = os.path.join(self.ipython_dir, histfname)
1055 self.histfile = os.path.join(self.ipython_dir, histfname)
1056
1056
1057 # Fill the history zero entry, user counter starts at 1
1057 # Fill the history zero entry, user counter starts at 1
1058 self.input_hist.append('\n')
1058 self.input_hist.append('\n')
1059 self.input_hist_raw.append('\n')
1059 self.input_hist_raw.append('\n')
1060
1060
1061 def init_shadow_hist(self):
1061 def init_shadow_hist(self):
1062 try:
1062 try:
1063 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1063 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1064 except exceptions.UnicodeDecodeError:
1064 except exceptions.UnicodeDecodeError:
1065 print "Your ipython_dir can't be decoded to unicode!"
1065 print "Your ipython_dir can't be decoded to unicode!"
1066 print "Please set HOME environment variable to something that"
1066 print "Please set HOME environment variable to something that"
1067 print r"only has ASCII characters, e.g. c:\home"
1067 print r"only has ASCII characters, e.g. c:\home"
1068 print "Now it is", self.ipython_dir
1068 print "Now it is", self.ipython_dir
1069 sys.exit()
1069 sys.exit()
1070 self.shadowhist = ipcorehist.ShadowHist(self.db)
1070 self.shadowhist = ipcorehist.ShadowHist(self.db)
1071
1071
1072 def savehist(self):
1072 def savehist(self):
1073 """Save input history to a file (via readline library)."""
1073 """Save input history to a file (via readline library)."""
1074
1074
1075 try:
1075 try:
1076 self.readline.write_history_file(self.histfile)
1076 self.readline.write_history_file(self.histfile)
1077 except:
1077 except:
1078 print 'Unable to save IPython command history to file: ' + \
1078 print 'Unable to save IPython command history to file: ' + \
1079 `self.histfile`
1079 `self.histfile`
1080
1080
1081 def reloadhist(self):
1081 def reloadhist(self):
1082 """Reload the input history from disk file."""
1082 """Reload the input history from disk file."""
1083
1083
1084 try:
1084 try:
1085 self.readline.clear_history()
1085 self.readline.clear_history()
1086 self.readline.read_history_file(self.shell.histfile)
1086 self.readline.read_history_file(self.shell.histfile)
1087 except AttributeError:
1087 except AttributeError:
1088 pass
1088 pass
1089
1089
1090 def history_saving_wrapper(self, func):
1090 def history_saving_wrapper(self, func):
1091 """ Wrap func for readline history saving
1091 """ Wrap func for readline history saving
1092
1092
1093 Convert func into callable that saves & restores
1093 Convert func into callable that saves & restores
1094 history around the call """
1094 history around the call """
1095
1095
1096 if self.has_readline:
1096 if self.has_readline:
1097 from IPython.utils import rlineimpl as readline
1097 from IPython.utils import rlineimpl as readline
1098 else:
1098 else:
1099 return func
1099 return func
1100
1100
1101 def wrapper():
1101 def wrapper():
1102 self.savehist()
1102 self.savehist()
1103 try:
1103 try:
1104 func()
1104 func()
1105 finally:
1105 finally:
1106 readline.read_history_file(self.histfile)
1106 readline.read_history_file(self.histfile)
1107 return wrapper
1107 return wrapper
1108
1108
1109 def get_history(self, index=None, raw=False, output=True):
1109 def get_history(self, index=None, raw=False, output=True):
1110 """Get the history list.
1110 """Get the history list.
1111
1111
1112 Get the input and output history.
1112 Get the input and output history.
1113
1113
1114 Parameters
1114 Parameters
1115 ----------
1115 ----------
1116 index : n or (n1, n2) or None
1116 index : n or (n1, n2) or None
1117 If n, then the last entries. If a tuple, then all in
1117 If n, then the last entries. If a tuple, then all in
1118 range(n1, n2). If None, then all entries. Raises IndexError if
1118 range(n1, n2). If None, then all entries. Raises IndexError if
1119 the format of index is incorrect.
1119 the format of index is incorrect.
1120 raw : bool
1120 raw : bool
1121 If True, return the raw input.
1121 If True, return the raw input.
1122 output : bool
1122 output : bool
1123 If True, then return the output as well.
1123 If True, then return the output as well.
1124
1124
1125 Returns
1125 Returns
1126 -------
1126 -------
1127 If output is True, then return a dict of tuples, keyed by the prompt
1127 If output is True, then return a dict of tuples, keyed by the prompt
1128 numbers and with values of (input, output). If output is False, then
1128 numbers and with values of (input, output). If output is False, then
1129 a dict, keyed by the prompt number with the values of input. Raises
1129 a dict, keyed by the prompt number with the values of input. Raises
1130 IndexError if no history is found.
1130 IndexError if no history is found.
1131 """
1131 """
1132 if raw:
1132 if raw:
1133 input_hist = self.input_hist_raw
1133 input_hist = self.input_hist_raw
1134 else:
1134 else:
1135 input_hist = self.input_hist
1135 input_hist = self.input_hist
1136 if output:
1136 if output:
1137 output_hist = self.user_ns['Out']
1137 output_hist = self.user_ns['Out']
1138 n = len(input_hist)
1138 n = len(input_hist)
1139 if index is None:
1139 if index is None:
1140 start=0; stop=n
1140 start=0; stop=n
1141 elif isinstance(index, int):
1141 elif isinstance(index, int):
1142 start=n-index; stop=n
1142 start=n-index; stop=n
1143 elif isinstance(index, tuple) and len(index) == 2:
1143 elif isinstance(index, tuple) and len(index) == 2:
1144 start=index[0]; stop=index[1]
1144 start=index[0]; stop=index[1]
1145 else:
1145 else:
1146 raise IndexError('Not a valid index for the input history: %r' % index)
1146 raise IndexError('Not a valid index for the input history: %r' % index)
1147 hist = {}
1147 hist = {}
1148 for i in range(start, stop):
1148 for i in range(start, stop):
1149 if output:
1149 if output:
1150 hist[i] = (input_hist[i], output_hist.get(i))
1150 hist[i] = (input_hist[i], output_hist.get(i))
1151 else:
1151 else:
1152 hist[i] = input_hist[i]
1152 hist[i] = input_hist[i]
1153 if len(hist)==0:
1153 if len(hist)==0:
1154 raise IndexError('No history for range of indices: %r' % index)
1154 raise IndexError('No history for range of indices: %r' % index)
1155 return hist
1155 return hist
1156
1156
1157 #-------------------------------------------------------------------------
1157 #-------------------------------------------------------------------------
1158 # Things related to exception handling and tracebacks (not debugging)
1158 # Things related to exception handling and tracebacks (not debugging)
1159 #-------------------------------------------------------------------------
1159 #-------------------------------------------------------------------------
1160
1160
1161 def init_traceback_handlers(self, custom_exceptions):
1161 def init_traceback_handlers(self, custom_exceptions):
1162 # Syntax error handler.
1162 # Syntax error handler.
1163 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1163 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1164
1164
1165 # The interactive one is initialized with an offset, meaning we always
1165 # The interactive one is initialized with an offset, meaning we always
1166 # want to remove the topmost item in the traceback, which is our own
1166 # want to remove the topmost item in the traceback, which is our own
1167 # internal code. Valid modes: ['Plain','Context','Verbose']
1167 # internal code. Valid modes: ['Plain','Context','Verbose']
1168 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1168 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1169 color_scheme='NoColor',
1169 color_scheme='NoColor',
1170 tb_offset = 1)
1170 tb_offset = 1)
1171
1171
1172 # The instance will store a pointer to the system-wide exception hook,
1172 # The instance will store a pointer to the system-wide exception hook,
1173 # so that runtime code (such as magics) can access it. This is because
1173 # so that runtime code (such as magics) can access it. This is because
1174 # during the read-eval loop, it may get temporarily overwritten.
1174 # during the read-eval loop, it may get temporarily overwritten.
1175 self.sys_excepthook = sys.excepthook
1175 self.sys_excepthook = sys.excepthook
1176
1176
1177 # and add any custom exception handlers the user may have specified
1177 # and add any custom exception handlers the user may have specified
1178 self.set_custom_exc(*custom_exceptions)
1178 self.set_custom_exc(*custom_exceptions)
1179
1179
1180 # Set the exception mode
1180 # Set the exception mode
1181 self.InteractiveTB.set_mode(mode=self.xmode)
1181 self.InteractiveTB.set_mode(mode=self.xmode)
1182
1182
1183 def set_custom_exc(self, exc_tuple, handler):
1183 def set_custom_exc(self, exc_tuple, handler):
1184 """set_custom_exc(exc_tuple,handler)
1184 """set_custom_exc(exc_tuple,handler)
1185
1185
1186 Set a custom exception handler, which will be called if any of the
1186 Set a custom exception handler, which will be called if any of the
1187 exceptions in exc_tuple occur in the mainloop (specifically, in the
1187 exceptions in exc_tuple occur in the mainloop (specifically, in the
1188 runcode() method.
1188 runcode() method.
1189
1189
1190 Inputs:
1190 Inputs:
1191
1191
1192 - exc_tuple: a *tuple* of valid exceptions to call the defined
1192 - exc_tuple: a *tuple* of valid exceptions to call the defined
1193 handler for. It is very important that you use a tuple, and NOT A
1193 handler for. It is very important that you use a tuple, and NOT A
1194 LIST here, because of the way Python's except statement works. If
1194 LIST here, because of the way Python's except statement works. If
1195 you only want to trap a single exception, use a singleton tuple:
1195 you only want to trap a single exception, use a singleton tuple:
1196
1196
1197 exc_tuple == (MyCustomException,)
1197 exc_tuple == (MyCustomException,)
1198
1198
1199 - handler: this must be defined as a function with the following
1199 - handler: this must be defined as a function with the following
1200 basic interface::
1200 basic interface::
1201
1201
1202 def my_handler(self, etype, value, tb, tb_offset=None)
1202 def my_handler(self, etype, value, tb, tb_offset=None)
1203 ...
1203 ...
1204 # The return value must be
1204 # The return value must be
1205 return structured_traceback
1205 return structured_traceback
1206
1206
1207 This will be made into an instance method (via new.instancemethod)
1207 This will be made into an instance method (via new.instancemethod)
1208 of IPython itself, and it will be called if any of the exceptions
1208 of IPython itself, and it will be called if any of the exceptions
1209 listed in the exc_tuple are caught. If the handler is None, an
1209 listed in the exc_tuple are caught. If the handler is None, an
1210 internal basic one is used, which just prints basic info.
1210 internal basic one is used, which just prints basic info.
1211
1211
1212 WARNING: by putting in your own exception handler into IPython's main
1212 WARNING: by putting in your own exception handler into IPython's main
1213 execution loop, you run a very good chance of nasty crashes. This
1213 execution loop, you run a very good chance of nasty crashes. This
1214 facility should only be used if you really know what you are doing."""
1214 facility should only be used if you really know what you are doing."""
1215
1215
1216 assert type(exc_tuple)==type(()) , \
1216 assert type(exc_tuple)==type(()) , \
1217 "The custom exceptions must be given AS A TUPLE."
1217 "The custom exceptions must be given AS A TUPLE."
1218
1218
1219 def dummy_handler(self,etype,value,tb):
1219 def dummy_handler(self,etype,value,tb):
1220 print '*** Simple custom exception handler ***'
1220 print '*** Simple custom exception handler ***'
1221 print 'Exception type :',etype
1221 print 'Exception type :',etype
1222 print 'Exception value:',value
1222 print 'Exception value:',value
1223 print 'Traceback :',tb
1223 print 'Traceback :',tb
1224 print 'Source code :','\n'.join(self.buffer)
1224 print 'Source code :','\n'.join(self.buffer)
1225
1225
1226 if handler is None: handler = dummy_handler
1226 if handler is None: handler = dummy_handler
1227
1227
1228 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1228 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1229 self.custom_exceptions = exc_tuple
1229 self.custom_exceptions = exc_tuple
1230
1230
1231 def excepthook(self, etype, value, tb):
1231 def excepthook(self, etype, value, tb):
1232 """One more defense for GUI apps that call sys.excepthook.
1232 """One more defense for GUI apps that call sys.excepthook.
1233
1233
1234 GUI frameworks like wxPython trap exceptions and call
1234 GUI frameworks like wxPython trap exceptions and call
1235 sys.excepthook themselves. I guess this is a feature that
1235 sys.excepthook themselves. I guess this is a feature that
1236 enables them to keep running after exceptions that would
1236 enables them to keep running after exceptions that would
1237 otherwise kill their mainloop. This is a bother for IPython
1237 otherwise kill their mainloop. This is a bother for IPython
1238 which excepts to catch all of the program exceptions with a try:
1238 which excepts to catch all of the program exceptions with a try:
1239 except: statement.
1239 except: statement.
1240
1240
1241 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1241 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1242 any app directly invokes sys.excepthook, it will look to the user like
1242 any app directly invokes sys.excepthook, it will look to the user like
1243 IPython crashed. In order to work around this, we can disable the
1243 IPython crashed. In order to work around this, we can disable the
1244 CrashHandler and replace it with this excepthook instead, which prints a
1244 CrashHandler and replace it with this excepthook instead, which prints a
1245 regular traceback using our InteractiveTB. In this fashion, apps which
1245 regular traceback using our InteractiveTB. In this fashion, apps which
1246 call sys.excepthook will generate a regular-looking exception from
1246 call sys.excepthook will generate a regular-looking exception from
1247 IPython, and the CrashHandler will only be triggered by real IPython
1247 IPython, and the CrashHandler will only be triggered by real IPython
1248 crashes.
1248 crashes.
1249
1249
1250 This hook should be used sparingly, only in places which are not likely
1250 This hook should be used sparingly, only in places which are not likely
1251 to be true IPython errors.
1251 to be true IPython errors.
1252 """
1252 """
1253 self.showtraceback((etype,value,tb),tb_offset=0)
1253 self.showtraceback((etype,value,tb),tb_offset=0)
1254
1254
1255 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1255 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1256 exception_only=False):
1256 exception_only=False):
1257 """Display the exception that just occurred.
1257 """Display the exception that just occurred.
1258
1258
1259 If nothing is known about the exception, this is the method which
1259 If nothing is known about the exception, this is the method which
1260 should be used throughout the code for presenting user tracebacks,
1260 should be used throughout the code for presenting user tracebacks,
1261 rather than directly invoking the InteractiveTB object.
1261 rather than directly invoking the InteractiveTB object.
1262
1262
1263 A specific showsyntaxerror() also exists, but this method can take
1263 A specific showsyntaxerror() also exists, but this method can take
1264 care of calling it if needed, so unless you are explicitly catching a
1264 care of calling it if needed, so unless you are explicitly catching a
1265 SyntaxError exception, don't try to analyze the stack manually and
1265 SyntaxError exception, don't try to analyze the stack manually and
1266 simply call this method."""
1266 simply call this method."""
1267
1267
1268 try:
1268 try:
1269 if exc_tuple is None:
1269 if exc_tuple is None:
1270 etype, value, tb = sys.exc_info()
1270 etype, value, tb = sys.exc_info()
1271 else:
1271 else:
1272 etype, value, tb = exc_tuple
1272 etype, value, tb = exc_tuple
1273
1273
1274 if etype is None:
1274 if etype is None:
1275 if hasattr(sys, 'last_type'):
1275 if hasattr(sys, 'last_type'):
1276 etype, value, tb = sys.last_type, sys.last_value, \
1276 etype, value, tb = sys.last_type, sys.last_value, \
1277 sys.last_traceback
1277 sys.last_traceback
1278 else:
1278 else:
1279 self.write_err('No traceback available to show.\n')
1279 self.write_err('No traceback available to show.\n')
1280 return
1280 return
1281
1281
1282 if etype is SyntaxError:
1282 if etype is SyntaxError:
1283 # Though this won't be called by syntax errors in the input
1283 # Though this won't be called by syntax errors in the input
1284 # line, there may be SyntaxError cases whith imported code.
1284 # line, there may be SyntaxError cases whith imported code.
1285 self.showsyntaxerror(filename)
1285 self.showsyntaxerror(filename)
1286 elif etype is UsageError:
1286 elif etype is UsageError:
1287 print "UsageError:", value
1287 print "UsageError:", value
1288 else:
1288 else:
1289 # WARNING: these variables are somewhat deprecated and not
1289 # WARNING: these variables are somewhat deprecated and not
1290 # necessarily safe to use in a threaded environment, but tools
1290 # necessarily safe to use in a threaded environment, but tools
1291 # like pdb depend on their existence, so let's set them. If we
1291 # like pdb depend on their existence, so let's set them. If we
1292 # find problems in the field, we'll need to revisit their use.
1292 # find problems in the field, we'll need to revisit their use.
1293 sys.last_type = etype
1293 sys.last_type = etype
1294 sys.last_value = value
1294 sys.last_value = value
1295 sys.last_traceback = tb
1295 sys.last_traceback = tb
1296
1296
1297 if etype in self.custom_exceptions:
1297 if etype in self.custom_exceptions:
1298 # FIXME: Old custom traceback objects may just return a
1298 # FIXME: Old custom traceback objects may just return a
1299 # string, in that case we just put it into a list
1299 # string, in that case we just put it into a list
1300 stb = self.CustomTB(etype, value, tb, tb_offset)
1300 stb = self.CustomTB(etype, value, tb, tb_offset)
1301 if isinstance(ctb, basestring):
1301 if isinstance(ctb, basestring):
1302 stb = [stb]
1302 stb = [stb]
1303 else:
1303 else:
1304 if exception_only:
1304 if exception_only:
1305 stb = ['An exception has occurred, use %tb to see '
1305 stb = ['An exception has occurred, use %tb to see '
1306 'the full traceback.\n']
1306 'the full traceback.\n']
1307 stb.extend(self.InteractiveTB.get_exception_only(etype,
1307 stb.extend(self.InteractiveTB.get_exception_only(etype,
1308 value))
1308 value))
1309 else:
1309 else:
1310 stb = self.InteractiveTB.structured_traceback(etype,
1310 stb = self.InteractiveTB.structured_traceback(etype,
1311 value, tb, tb_offset=tb_offset)
1311 value, tb, tb_offset=tb_offset)
1312 # FIXME: the pdb calling should be done by us, not by
1312 # FIXME: the pdb calling should be done by us, not by
1313 # the code computing the traceback.
1313 # the code computing the traceback.
1314 if self.InteractiveTB.call_pdb:
1314 if self.InteractiveTB.call_pdb:
1315 # pdb mucks up readline, fix it back
1315 # pdb mucks up readline, fix it back
1316 self.set_completer()
1316 self.set_completer()
1317
1317
1318 # Actually show the traceback
1318 # Actually show the traceback
1319 self._showtraceback(etype, value, stb)
1319 self._showtraceback(etype, value, stb)
1320
1320
1321 except KeyboardInterrupt:
1321 except KeyboardInterrupt:
1322 self.write_err("\nKeyboardInterrupt\n")
1322 self.write_err("\nKeyboardInterrupt\n")
1323
1323
1324 def _showtraceback(self, etype, evalue, stb):
1324 def _showtraceback(self, etype, evalue, stb):
1325 """Actually show a traceback.
1325 """Actually show a traceback.
1326
1326
1327 Subclasses may override this method to put the traceback on a different
1327 Subclasses may override this method to put the traceback on a different
1328 place, like a side channel.
1328 place, like a side channel.
1329 """
1329 """
1330 # FIXME: this should use the proper write channels, but our test suite
1330 # FIXME: this should use the proper write channels, but our test suite
1331 # relies on it coming out of stdout...
1331 # relies on it coming out of stdout...
1332 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1332 print >> sys.stdout, self.InteractiveTB.stb2text(stb)
1333
1333
1334 def showsyntaxerror(self, filename=None):
1334 def showsyntaxerror(self, filename=None):
1335 """Display the syntax error that just occurred.
1335 """Display the syntax error that just occurred.
1336
1336
1337 This doesn't display a stack trace because there isn't one.
1337 This doesn't display a stack trace because there isn't one.
1338
1338
1339 If a filename is given, it is stuffed in the exception instead
1339 If a filename is given, it is stuffed in the exception instead
1340 of what was there before (because Python's parser always uses
1340 of what was there before (because Python's parser always uses
1341 "<string>" when reading from a string).
1341 "<string>" when reading from a string).
1342 """
1342 """
1343 etype, value, last_traceback = sys.exc_info()
1343 etype, value, last_traceback = sys.exc_info()
1344
1344
1345 # See note about these variables in showtraceback() above
1345 # See note about these variables in showtraceback() above
1346 sys.last_type = etype
1346 sys.last_type = etype
1347 sys.last_value = value
1347 sys.last_value = value
1348 sys.last_traceback = last_traceback
1348 sys.last_traceback = last_traceback
1349
1349
1350 if filename and etype is SyntaxError:
1350 if filename and etype is SyntaxError:
1351 # Work hard to stuff the correct filename in the exception
1351 # Work hard to stuff the correct filename in the exception
1352 try:
1352 try:
1353 msg, (dummy_filename, lineno, offset, line) = value
1353 msg, (dummy_filename, lineno, offset, line) = value
1354 except:
1354 except:
1355 # Not the format we expect; leave it alone
1355 # Not the format we expect; leave it alone
1356 pass
1356 pass
1357 else:
1357 else:
1358 # Stuff in the right filename
1358 # Stuff in the right filename
1359 try:
1359 try:
1360 # Assume SyntaxError is a class exception
1360 # Assume SyntaxError is a class exception
1361 value = SyntaxError(msg, (filename, lineno, offset, line))
1361 value = SyntaxError(msg, (filename, lineno, offset, line))
1362 except:
1362 except:
1363 # If that failed, assume SyntaxError is a string
1363 # If that failed, assume SyntaxError is a string
1364 value = msg, (filename, lineno, offset, line)
1364 value = msg, (filename, lineno, offset, line)
1365 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1365 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1366 self._showtraceback(etype, value, stb)
1366 self._showtraceback(etype, value, stb)
1367
1367
1368 #-------------------------------------------------------------------------
1368 #-------------------------------------------------------------------------
1369 # Things related to tab completion
1369 # Things related to tab completion
1370 #-------------------------------------------------------------------------
1370 #-------------------------------------------------------------------------
1371
1371
1372 def complete(self, text, line=None, cursor_pos=None):
1372 def complete(self, text, line=None, cursor_pos=None):
1373 """Return the completed text and a list of completions.
1373 """Return the completed text and a list of completions.
1374
1374
1375 Parameters
1375 Parameters
1376 ----------
1376 ----------
1377
1377
1378 text : string
1378 text : string
1379 A string of text to be completed on. It can be given as empty and
1379 A string of text to be completed on. It can be given as empty and
1380 instead a line/position pair are given. In this case, the
1380 instead a line/position pair are given. In this case, the
1381 completer itself will split the line like readline does.
1381 completer itself will split the line like readline does.
1382
1382
1383 line : string, optional
1383 line : string, optional
1384 The complete line that text is part of.
1384 The complete line that text is part of.
1385
1385
1386 cursor_pos : int, optional
1386 cursor_pos : int, optional
1387 The position of the cursor on the input line.
1387 The position of the cursor on the input line.
1388
1388
1389 Returns
1389 Returns
1390 -------
1390 -------
1391 text : string
1391 text : string
1392 The actual text that was completed.
1392 The actual text that was completed.
1393
1393
1394 matches : list
1394 matches : list
1395 A sorted list with all possible completions.
1395 A sorted list with all possible completions.
1396
1396
1397 The optional arguments allow the completion to take more context into
1397 The optional arguments allow the completion to take more context into
1398 account, and are part of the low-level completion API.
1398 account, and are part of the low-level completion API.
1399
1399
1400 This is a wrapper around the completion mechanism, similar to what
1400 This is a wrapper around the completion mechanism, similar to what
1401 readline does at the command line when the TAB key is hit. By
1401 readline does at the command line when the TAB key is hit. By
1402 exposing it as a method, it can be used by other non-readline
1402 exposing it as a method, it can be used by other non-readline
1403 environments (such as GUIs) for text completion.
1403 environments (such as GUIs) for text completion.
1404
1404
1405 Simple usage example:
1405 Simple usage example:
1406
1406
1407 In [1]: x = 'hello'
1407 In [1]: x = 'hello'
1408
1408
1409 In [2]: _ip.complete('x.l')
1409 In [2]: _ip.complete('x.l')
1410 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1410 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
1411 """
1411 """
1412
1412
1413 # Inject names into __builtin__ so we can complete on the added names.
1413 # Inject names into __builtin__ so we can complete on the added names.
1414 with self.builtin_trap:
1414 with self.builtin_trap:
1415 return self.Completer.complete(text, line, cursor_pos)
1415 return self.Completer.complete(text, line, cursor_pos)
1416
1416
1417 def set_custom_completer(self, completer, pos=0):
1417 def set_custom_completer(self, completer, pos=0):
1418 """Adds a new custom completer function.
1418 """Adds a new custom completer function.
1419
1419
1420 The position argument (defaults to 0) is the index in the completers
1420 The position argument (defaults to 0) is the index in the completers
1421 list where you want the completer to be inserted."""
1421 list where you want the completer to be inserted."""
1422
1422
1423 newcomp = new.instancemethod(completer,self.Completer,
1423 newcomp = new.instancemethod(completer,self.Completer,
1424 self.Completer.__class__)
1424 self.Completer.__class__)
1425 self.Completer.matchers.insert(pos,newcomp)
1425 self.Completer.matchers.insert(pos,newcomp)
1426
1426
1427 def set_completer(self):
1427 def set_completer(self):
1428 """Reset readline's completer to be our own."""
1428 """Reset readline's completer to be our own."""
1429 self.readline.set_completer(self.Completer.rlcomplete)
1429 self.readline.set_completer(self.Completer.rlcomplete)
1430
1430
1431 def set_completer_frame(self, frame=None):
1431 def set_completer_frame(self, frame=None):
1432 """Set the frame of the completer."""
1432 """Set the frame of the completer."""
1433 if frame:
1433 if frame:
1434 self.Completer.namespace = frame.f_locals
1434 self.Completer.namespace = frame.f_locals
1435 self.Completer.global_namespace = frame.f_globals
1435 self.Completer.global_namespace = frame.f_globals
1436 else:
1436 else:
1437 self.Completer.namespace = self.user_ns
1437 self.Completer.namespace = self.user_ns
1438 self.Completer.global_namespace = self.user_global_ns
1438 self.Completer.global_namespace = self.user_global_ns
1439
1439
1440 #-------------------------------------------------------------------------
1440 #-------------------------------------------------------------------------
1441 # Things related to readline
1441 # Things related to readline
1442 #-------------------------------------------------------------------------
1442 #-------------------------------------------------------------------------
1443
1443
1444 def init_readline(self):
1444 def init_readline(self):
1445 """Command history completion/saving/reloading."""
1445 """Command history completion/saving/reloading."""
1446
1446
1447 if self.readline_use:
1447 if self.readline_use:
1448 import IPython.utils.rlineimpl as readline
1448 import IPython.utils.rlineimpl as readline
1449
1449
1450 self.rl_next_input = None
1450 self.rl_next_input = None
1451 self.rl_do_indent = False
1451 self.rl_do_indent = False
1452
1452
1453 if not self.readline_use or not readline.have_readline:
1453 if not self.readline_use or not readline.have_readline:
1454 self.has_readline = False
1454 self.has_readline = False
1455 self.readline = None
1455 self.readline = None
1456 # Set a number of methods that depend on readline to be no-op
1456 # Set a number of methods that depend on readline to be no-op
1457 self.savehist = no_op
1457 self.savehist = no_op
1458 self.reloadhist = no_op
1458 self.reloadhist = no_op
1459 self.set_completer = no_op
1459 self.set_completer = no_op
1460 self.set_custom_completer = no_op
1460 self.set_custom_completer = no_op
1461 self.set_completer_frame = no_op
1461 self.set_completer_frame = no_op
1462 warn('Readline services not available or not loaded.')
1462 warn('Readline services not available or not loaded.')
1463 else:
1463 else:
1464 self.has_readline = True
1464 self.has_readline = True
1465 self.readline = readline
1465 self.readline = readline
1466 sys.modules['readline'] = readline
1466 sys.modules['readline'] = readline
1467 import atexit
1467 import atexit
1468 from IPython.core.completer import IPCompleter
1468 from IPython.core.completer import IPCompleter
1469 self.Completer = IPCompleter(self,
1469 self.Completer = IPCompleter(self,
1470 self.user_ns,
1470 self.user_ns,
1471 self.user_global_ns,
1471 self.user_global_ns,
1472 self.readline_omit__names,
1472 self.readline_omit__names,
1473 self.alias_manager.alias_table)
1473 self.alias_manager.alias_table)
1474 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1474 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1475 self.strdispatchers['complete_command'] = sdisp
1475 self.strdispatchers['complete_command'] = sdisp
1476 self.Completer.custom_completers = sdisp
1476 self.Completer.custom_completers = sdisp
1477 # Platform-specific configuration
1477 # Platform-specific configuration
1478 if os.name == 'nt':
1478 if os.name == 'nt':
1479 self.readline_startup_hook = readline.set_pre_input_hook
1479 self.readline_startup_hook = readline.set_pre_input_hook
1480 else:
1480 else:
1481 self.readline_startup_hook = readline.set_startup_hook
1481 self.readline_startup_hook = readline.set_startup_hook
1482
1482
1483 # Load user's initrc file (readline config)
1483 # Load user's initrc file (readline config)
1484 # Or if libedit is used, load editrc.
1484 # Or if libedit is used, load editrc.
1485 inputrc_name = os.environ.get('INPUTRC')
1485 inputrc_name = os.environ.get('INPUTRC')
1486 if inputrc_name is None:
1486 if inputrc_name is None:
1487 home_dir = get_home_dir()
1487 home_dir = get_home_dir()
1488 if home_dir is not None:
1488 if home_dir is not None:
1489 inputrc_name = '.inputrc'
1489 inputrc_name = '.inputrc'
1490 if readline.uses_libedit:
1490 if readline.uses_libedit:
1491 inputrc_name = '.editrc'
1491 inputrc_name = '.editrc'
1492 inputrc_name = os.path.join(home_dir, inputrc_name)
1492 inputrc_name = os.path.join(home_dir, inputrc_name)
1493 if os.path.isfile(inputrc_name):
1493 if os.path.isfile(inputrc_name):
1494 try:
1494 try:
1495 readline.read_init_file(inputrc_name)
1495 readline.read_init_file(inputrc_name)
1496 except:
1496 except:
1497 warn('Problems reading readline initialization file <%s>'
1497 warn('Problems reading readline initialization file <%s>'
1498 % inputrc_name)
1498 % inputrc_name)
1499
1499
1500 # save this in sys so embedded copies can restore it properly
1500 # save this in sys so embedded copies can restore it properly
1501 sys.ipcompleter = self.Completer.rlcomplete
1501 sys.ipcompleter = self.Completer.rlcomplete
1502 self.set_completer()
1502 self.set_completer()
1503
1503
1504 # Configure readline according to user's prefs
1504 # Configure readline according to user's prefs
1505 # This is only done if GNU readline is being used. If libedit
1505 # This is only done if GNU readline is being used. If libedit
1506 # is being used (as on Leopard) the readline config is
1506 # is being used (as on Leopard) the readline config is
1507 # not run as the syntax for libedit is different.
1507 # not run as the syntax for libedit is different.
1508 if not readline.uses_libedit:
1508 if not readline.uses_libedit:
1509 for rlcommand in self.readline_parse_and_bind:
1509 for rlcommand in self.readline_parse_and_bind:
1510 #print "loading rl:",rlcommand # dbg
1510 #print "loading rl:",rlcommand # dbg
1511 readline.parse_and_bind(rlcommand)
1511 readline.parse_and_bind(rlcommand)
1512
1512
1513 # Remove some chars from the delimiters list. If we encounter
1513 # Remove some chars from the delimiters list. If we encounter
1514 # unicode chars, discard them.
1514 # unicode chars, discard them.
1515 delims = readline.get_completer_delims().encode("ascii", "ignore")
1515 delims = readline.get_completer_delims().encode("ascii", "ignore")
1516 delims = delims.translate(string._idmap,
1516 delims = delims.translate(string._idmap,
1517 self.readline_remove_delims)
1517 self.readline_remove_delims)
1518 readline.set_completer_delims(delims)
1518 readline.set_completer_delims(delims)
1519 # otherwise we end up with a monster history after a while:
1519 # otherwise we end up with a monster history after a while:
1520 readline.set_history_length(1000)
1520 readline.set_history_length(1000)
1521 try:
1521 try:
1522 #print '*** Reading readline history' # dbg
1522 #print '*** Reading readline history' # dbg
1523 readline.read_history_file(self.histfile)
1523 readline.read_history_file(self.histfile)
1524 except IOError:
1524 except IOError:
1525 pass # It doesn't exist yet.
1525 pass # It doesn't exist yet.
1526
1526
1527 atexit.register(self.atexit_operations)
1527 atexit.register(self.atexit_operations)
1528 del atexit
1528 del atexit
1529
1529
1530 # Configure auto-indent for all platforms
1530 # Configure auto-indent for all platforms
1531 self.set_autoindent(self.autoindent)
1531 self.set_autoindent(self.autoindent)
1532
1532
1533 def set_next_input(self, s):
1533 def set_next_input(self, s):
1534 """ Sets the 'default' input string for the next command line.
1534 """ Sets the 'default' input string for the next command line.
1535
1535
1536 Requires readline.
1536 Requires readline.
1537
1537
1538 Example:
1538 Example:
1539
1539
1540 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1540 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1541 [D:\ipython]|2> Hello Word_ # cursor is here
1541 [D:\ipython]|2> Hello Word_ # cursor is here
1542 """
1542 """
1543
1543
1544 self.rl_next_input = s
1544 self.rl_next_input = s
1545
1545
1546 # Maybe move this to the terminal subclass?
1546 # Maybe move this to the terminal subclass?
1547 def pre_readline(self):
1547 def pre_readline(self):
1548 """readline hook to be used at the start of each line.
1548 """readline hook to be used at the start of each line.
1549
1549
1550 Currently it handles auto-indent only."""
1550 Currently it handles auto-indent only."""
1551
1551
1552 if self.rl_do_indent:
1552 if self.rl_do_indent:
1553 self.readline.insert_text(self._indent_current_str())
1553 self.readline.insert_text(self._indent_current_str())
1554 if self.rl_next_input is not None:
1554 if self.rl_next_input is not None:
1555 self.readline.insert_text(self.rl_next_input)
1555 self.readline.insert_text(self.rl_next_input)
1556 self.rl_next_input = None
1556 self.rl_next_input = None
1557
1557
1558 def _indent_current_str(self):
1558 def _indent_current_str(self):
1559 """return the current level of indentation as a string"""
1559 """return the current level of indentation as a string"""
1560 return self.indent_current_nsp * ' '
1560 return self.indent_current_nsp * ' '
1561
1561
1562 #-------------------------------------------------------------------------
1562 #-------------------------------------------------------------------------
1563 # Things related to magics
1563 # Things related to magics
1564 #-------------------------------------------------------------------------
1564 #-------------------------------------------------------------------------
1565
1565
1566 def init_magics(self):
1566 def init_magics(self):
1567 # FIXME: Move the color initialization to the DisplayHook, which
1567 # FIXME: Move the color initialization to the DisplayHook, which
1568 # should be split into a prompt manager and displayhook. We probably
1568 # should be split into a prompt manager and displayhook. We probably
1569 # even need a centralize colors management object.
1569 # even need a centralize colors management object.
1570 self.magic_colors(self.colors)
1570 self.magic_colors(self.colors)
1571 # History was moved to a separate module
1571 # History was moved to a separate module
1572 from . import history
1572 from . import history
1573 history.init_ipython(self)
1573 history.init_ipython(self)
1574
1574
1575 def magic(self,arg_s):
1575 def magic(self,arg_s):
1576 """Call a magic function by name.
1576 """Call a magic function by name.
1577
1577
1578 Input: a string containing the name of the magic function to call and any
1578 Input: a string containing the name of the magic function to call and any
1579 additional arguments to be passed to the magic.
1579 additional arguments to be passed to the magic.
1580
1580
1581 magic('name -opt foo bar') is equivalent to typing at the ipython
1581 magic('name -opt foo bar') is equivalent to typing at the ipython
1582 prompt:
1582 prompt:
1583
1583
1584 In[1]: %name -opt foo bar
1584 In[1]: %name -opt foo bar
1585
1585
1586 To call a magic without arguments, simply use magic('name').
1586 To call a magic without arguments, simply use magic('name').
1587
1587
1588 This provides a proper Python function to call IPython's magics in any
1588 This provides a proper Python function to call IPython's magics in any
1589 valid Python code you can type at the interpreter, including loops and
1589 valid Python code you can type at the interpreter, including loops and
1590 compound statements.
1590 compound statements.
1591 """
1591 """
1592 args = arg_s.split(' ',1)
1592 args = arg_s.split(' ',1)
1593 magic_name = args[0]
1593 magic_name = args[0]
1594 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1594 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1595
1595
1596 try:
1596 try:
1597 magic_args = args[1]
1597 magic_args = args[1]
1598 except IndexError:
1598 except IndexError:
1599 magic_args = ''
1599 magic_args = ''
1600 fn = getattr(self,'magic_'+magic_name,None)
1600 fn = getattr(self,'magic_'+magic_name,None)
1601 if fn is None:
1601 if fn is None:
1602 error("Magic function `%s` not found." % magic_name)
1602 error("Magic function `%s` not found." % magic_name)
1603 else:
1603 else:
1604 magic_args = self.var_expand(magic_args,1)
1604 magic_args = self.var_expand(magic_args,1)
1605 with nested(self.builtin_trap,):
1605 with nested(self.builtin_trap,):
1606 result = fn(magic_args)
1606 result = fn(magic_args)
1607 return result
1607 return result
1608
1608
1609 def define_magic(self, magicname, func):
1609 def define_magic(self, magicname, func):
1610 """Expose own function as magic function for ipython
1610 """Expose own function as magic function for ipython
1611
1611
1612 def foo_impl(self,parameter_s=''):
1612 def foo_impl(self,parameter_s=''):
1613 'My very own magic!. (Use docstrings, IPython reads them).'
1613 'My very own magic!. (Use docstrings, IPython reads them).'
1614 print 'Magic function. Passed parameter is between < >:'
1614 print 'Magic function. Passed parameter is between < >:'
1615 print '<%s>' % parameter_s
1615 print '<%s>' % parameter_s
1616 print 'The self object is:',self
1616 print 'The self object is:',self
1617
1617
1618 self.define_magic('foo',foo_impl)
1618 self.define_magic('foo',foo_impl)
1619 """
1619 """
1620
1620
1621 import new
1621 import new
1622 im = new.instancemethod(func,self, self.__class__)
1622 im = new.instancemethod(func,self, self.__class__)
1623 old = getattr(self, "magic_" + magicname, None)
1623 old = getattr(self, "magic_" + magicname, None)
1624 setattr(self, "magic_" + magicname, im)
1624 setattr(self, "magic_" + magicname, im)
1625 return old
1625 return old
1626
1626
1627 #-------------------------------------------------------------------------
1627 #-------------------------------------------------------------------------
1628 # Things related to macros
1628 # Things related to macros
1629 #-------------------------------------------------------------------------
1629 #-------------------------------------------------------------------------
1630
1630
1631 def define_macro(self, name, themacro):
1631 def define_macro(self, name, themacro):
1632 """Define a new macro
1632 """Define a new macro
1633
1633
1634 Parameters
1634 Parameters
1635 ----------
1635 ----------
1636 name : str
1636 name : str
1637 The name of the macro.
1637 The name of the macro.
1638 themacro : str or Macro
1638 themacro : str or Macro
1639 The action to do upon invoking the macro. If a string, a new
1639 The action to do upon invoking the macro. If a string, a new
1640 Macro object is created by passing the string to it.
1640 Macro object is created by passing the string to it.
1641 """
1641 """
1642
1642
1643 from IPython.core import macro
1643 from IPython.core import macro
1644
1644
1645 if isinstance(themacro, basestring):
1645 if isinstance(themacro, basestring):
1646 themacro = macro.Macro(themacro)
1646 themacro = macro.Macro(themacro)
1647 if not isinstance(themacro, macro.Macro):
1647 if not isinstance(themacro, macro.Macro):
1648 raise ValueError('A macro must be a string or a Macro instance.')
1648 raise ValueError('A macro must be a string or a Macro instance.')
1649 self.user_ns[name] = themacro
1649 self.user_ns[name] = themacro
1650
1650
1651 #-------------------------------------------------------------------------
1651 #-------------------------------------------------------------------------
1652 # Things related to the running of system commands
1652 # Things related to the running of system commands
1653 #-------------------------------------------------------------------------
1653 #-------------------------------------------------------------------------
1654
1654
1655 def system(self, cmd):
1655 def system(self, cmd):
1656 """Make a system call, using IPython."""
1656 """Make a system call, using IPython."""
1657 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1657 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1658
1658
1659 #-------------------------------------------------------------------------
1659 #-------------------------------------------------------------------------
1660 # Things related to aliases
1660 # Things related to aliases
1661 #-------------------------------------------------------------------------
1661 #-------------------------------------------------------------------------
1662
1662
1663 def init_alias(self):
1663 def init_alias(self):
1664 self.alias_manager = AliasManager(shell=self, config=self.config)
1664 self.alias_manager = AliasManager(shell=self, config=self.config)
1665 self.ns_table['alias'] = self.alias_manager.alias_table,
1665 self.ns_table['alias'] = self.alias_manager.alias_table,
1666
1666
1667 #-------------------------------------------------------------------------
1667 #-------------------------------------------------------------------------
1668 # Things related to extensions and plugins
1668 # Things related to extensions and plugins
1669 #-------------------------------------------------------------------------
1669 #-------------------------------------------------------------------------
1670
1670
1671 def init_extension_manager(self):
1671 def init_extension_manager(self):
1672 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1672 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1673
1673
1674 def init_plugin_manager(self):
1674 def init_plugin_manager(self):
1675 self.plugin_manager = PluginManager(config=self.config)
1675 self.plugin_manager = PluginManager(config=self.config)
1676
1676
1677 #-------------------------------------------------------------------------
1677 #-------------------------------------------------------------------------
1678 # Things related to payloads
1678 # Things related to payloads
1679 #-------------------------------------------------------------------------
1679 #-------------------------------------------------------------------------
1680
1680
1681 def init_payload(self):
1681 def init_payload(self):
1682 self.payload_manager = PayloadManager(config=self.config)
1682 self.payload_manager = PayloadManager(config=self.config)
1683
1683
1684 #-------------------------------------------------------------------------
1684 #-------------------------------------------------------------------------
1685 # Things related to the prefilter
1685 # Things related to the prefilter
1686 #-------------------------------------------------------------------------
1686 #-------------------------------------------------------------------------
1687
1687
1688 def init_prefilter(self):
1688 def init_prefilter(self):
1689 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1689 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1690 # Ultimately this will be refactored in the new interpreter code, but
1690 # Ultimately this will be refactored in the new interpreter code, but
1691 # for now, we should expose the main prefilter method (there's legacy
1691 # for now, we should expose the main prefilter method (there's legacy
1692 # code out there that may rely on this).
1692 # code out there that may rely on this).
1693 self.prefilter = self.prefilter_manager.prefilter_lines
1693 self.prefilter = self.prefilter_manager.prefilter_lines
1694
1694
1695 #-------------------------------------------------------------------------
1695 #-------------------------------------------------------------------------
1696 # Things related to the running of code
1696 # Things related to the running of code
1697 #-------------------------------------------------------------------------
1697 #-------------------------------------------------------------------------
1698
1698
1699 def ex(self, cmd):
1699 def ex(self, cmd):
1700 """Execute a normal python statement in user namespace."""
1700 """Execute a normal python statement in user namespace."""
1701 with nested(self.builtin_trap,):
1701 with nested(self.builtin_trap,):
1702 exec cmd in self.user_global_ns, self.user_ns
1702 exec cmd in self.user_global_ns, self.user_ns
1703
1703
1704 def ev(self, expr):
1704 def ev(self, expr):
1705 """Evaluate python expression expr in user namespace.
1705 """Evaluate python expression expr in user namespace.
1706
1706
1707 Returns the result of evaluation
1707 Returns the result of evaluation
1708 """
1708 """
1709 with nested(self.builtin_trap,):
1709 with nested(self.builtin_trap,):
1710 return eval(expr, self.user_global_ns, self.user_ns)
1710 return eval(expr, self.user_global_ns, self.user_ns)
1711
1711
1712 def safe_execfile(self, fname, *where, **kw):
1712 def safe_execfile(self, fname, *where, **kw):
1713 """A safe version of the builtin execfile().
1713 """A safe version of the builtin execfile().
1714
1714
1715 This version will never throw an exception, but instead print
1715 This version will never throw an exception, but instead print
1716 helpful error messages to the screen. This only works on pure
1716 helpful error messages to the screen. This only works on pure
1717 Python files with the .py extension.
1717 Python files with the .py extension.
1718
1718
1719 Parameters
1719 Parameters
1720 ----------
1720 ----------
1721 fname : string
1721 fname : string
1722 The name of the file to be executed.
1722 The name of the file to be executed.
1723 where : tuple
1723 where : tuple
1724 One or two namespaces, passed to execfile() as (globals,locals).
1724 One or two namespaces, passed to execfile() as (globals,locals).
1725 If only one is given, it is passed as both.
1725 If only one is given, it is passed as both.
1726 exit_ignore : bool (False)
1726 exit_ignore : bool (False)
1727 If True, then silence SystemExit for non-zero status (it is always
1727 If True, then silence SystemExit for non-zero status (it is always
1728 silenced for zero status, as it is so common).
1728 silenced for zero status, as it is so common).
1729 """
1729 """
1730 kw.setdefault('exit_ignore', False)
1730 kw.setdefault('exit_ignore', False)
1731
1731
1732 fname = os.path.abspath(os.path.expanduser(fname))
1732 fname = os.path.abspath(os.path.expanduser(fname))
1733
1733
1734 # Make sure we have a .py file
1734 # Make sure we have a .py file
1735 if not fname.endswith('.py'):
1735 if not fname.endswith('.py'):
1736 warn('File must end with .py to be run using execfile: <%s>' % fname)
1736 warn('File must end with .py to be run using execfile: <%s>' % fname)
1737
1737
1738 # Make sure we can open the file
1738 # Make sure we can open the file
1739 try:
1739 try:
1740 with open(fname) as thefile:
1740 with open(fname) as thefile:
1741 pass
1741 pass
1742 except:
1742 except:
1743 warn('Could not open file <%s> for safe execution.' % fname)
1743 warn('Could not open file <%s> for safe execution.' % fname)
1744 return
1744 return
1745
1745
1746 # Find things also in current directory. This is needed to mimic the
1746 # Find things also in current directory. This is needed to mimic the
1747 # behavior of running a script from the system command line, where
1747 # behavior of running a script from the system command line, where
1748 # Python inserts the script's directory into sys.path
1748 # Python inserts the script's directory into sys.path
1749 dname = os.path.dirname(fname)
1749 dname = os.path.dirname(fname)
1750
1750
1751 with prepended_to_syspath(dname):
1751 with prepended_to_syspath(dname):
1752 try:
1752 try:
1753 execfile(fname,*where)
1753 execfile(fname,*where)
1754 except SystemExit, status:
1754 except SystemExit, status:
1755 # If the call was made with 0 or None exit status (sys.exit(0)
1755 # If the call was made with 0 or None exit status (sys.exit(0)
1756 # or sys.exit() ), don't bother showing a traceback, as both of
1756 # or sys.exit() ), don't bother showing a traceback, as both of
1757 # these are considered normal by the OS:
1757 # these are considered normal by the OS:
1758 # > python -c'import sys;sys.exit(0)'; echo $?
1758 # > python -c'import sys;sys.exit(0)'; echo $?
1759 # 0
1759 # 0
1760 # > python -c'import sys;sys.exit()'; echo $?
1760 # > python -c'import sys;sys.exit()'; echo $?
1761 # 0
1761 # 0
1762 # For other exit status, we show the exception unless
1762 # For other exit status, we show the exception unless
1763 # explicitly silenced, but only in short form.
1763 # explicitly silenced, but only in short form.
1764 if status.code not in (0, None) and not kw['exit_ignore']:
1764 if status.code not in (0, None) and not kw['exit_ignore']:
1765 self.showtraceback(exception_only=True)
1765 self.showtraceback(exception_only=True)
1766 except:
1766 except:
1767 self.showtraceback()
1767 self.showtraceback()
1768
1768
1769 def safe_execfile_ipy(self, fname):
1769 def safe_execfile_ipy(self, fname):
1770 """Like safe_execfile, but for .ipy files with IPython syntax.
1770 """Like safe_execfile, but for .ipy files with IPython syntax.
1771
1771
1772 Parameters
1772 Parameters
1773 ----------
1773 ----------
1774 fname : str
1774 fname : str
1775 The name of the file to execute. The filename must have a
1775 The name of the file to execute. The filename must have a
1776 .ipy extension.
1776 .ipy extension.
1777 """
1777 """
1778 fname = os.path.abspath(os.path.expanduser(fname))
1778 fname = os.path.abspath(os.path.expanduser(fname))
1779
1779
1780 # Make sure we have a .py file
1780 # Make sure we have a .py file
1781 if not fname.endswith('.ipy'):
1781 if not fname.endswith('.ipy'):
1782 warn('File must end with .py to be run using execfile: <%s>' % fname)
1782 warn('File must end with .py to be run using execfile: <%s>' % fname)
1783
1783
1784 # Make sure we can open the file
1784 # Make sure we can open the file
1785 try:
1785 try:
1786 with open(fname) as thefile:
1786 with open(fname) as thefile:
1787 pass
1787 pass
1788 except:
1788 except:
1789 warn('Could not open file <%s> for safe execution.' % fname)
1789 warn('Could not open file <%s> for safe execution.' % fname)
1790 return
1790 return
1791
1791
1792 # Find things also in current directory. This is needed to mimic the
1792 # Find things also in current directory. This is needed to mimic the
1793 # behavior of running a script from the system command line, where
1793 # behavior of running a script from the system command line, where
1794 # Python inserts the script's directory into sys.path
1794 # Python inserts the script's directory into sys.path
1795 dname = os.path.dirname(fname)
1795 dname = os.path.dirname(fname)
1796
1796
1797 with prepended_to_syspath(dname):
1797 with prepended_to_syspath(dname):
1798 try:
1798 try:
1799 with open(fname) as thefile:
1799 with open(fname) as thefile:
1800 script = thefile.read()
1800 script = thefile.read()
1801 # self.runlines currently captures all exceptions
1801 # self.runlines currently captures all exceptions
1802 # raise in user code. It would be nice if there were
1802 # raise in user code. It would be nice if there were
1803 # versions of runlines, execfile that did raise, so
1803 # versions of runlines, execfile that did raise, so
1804 # we could catch the errors.
1804 # we could catch the errors.
1805 self.runlines(script, clean=True)
1805 self.runlines(script, clean=True)
1806 except:
1806 except:
1807 self.showtraceback()
1807 self.showtraceback()
1808 warn('Unknown failure executing file: <%s>' % fname)
1808 warn('Unknown failure executing file: <%s>' % fname)
1809
1809
1810 def runlines(self, lines, clean=False):
1810 def runlines(self, lines, clean=False):
1811 """Run a string of one or more lines of source.
1811 """Run a string of one or more lines of source.
1812
1812
1813 This method is capable of running a string containing multiple source
1813 This method is capable of running a string containing multiple source
1814 lines, as if they had been entered at the IPython prompt. Since it
1814 lines, as if they had been entered at the IPython prompt. Since it
1815 exposes IPython's processing machinery, the given strings can contain
1815 exposes IPython's processing machinery, the given strings can contain
1816 magic calls (%magic), special shell access (!cmd), etc.
1816 magic calls (%magic), special shell access (!cmd), etc.
1817 """
1817 """
1818
1818
1819 if isinstance(lines, (list, tuple)):
1819 if isinstance(lines, (list, tuple)):
1820 lines = '\n'.join(lines)
1820 lines = '\n'.join(lines)
1821
1821
1822 if clean:
1822 if clean:
1823 lines = self._cleanup_ipy_script(lines)
1823 lines = self._cleanup_ipy_script(lines)
1824
1824
1825 # We must start with a clean buffer, in case this is run from an
1825 # We must start with a clean buffer, in case this is run from an
1826 # interactive IPython session (via a magic, for example).
1826 # interactive IPython session (via a magic, for example).
1827 self.resetbuffer()
1827 self.resetbuffer()
1828 lines = lines.splitlines()
1828 lines = lines.splitlines()
1829 more = 0
1829 more = 0
1830
1830
1831 with nested(self.builtin_trap, self.display_trap):
1831 with nested(self.builtin_trap, self.display_trap):
1832 for line in lines:
1832 for line in lines:
1833 # skip blank lines so we don't mess up the prompt counter, but do
1833 # skip blank lines so we don't mess up the prompt counter, but do
1834 # NOT skip even a blank line if we are in a code block (more is
1834 # NOT skip even a blank line if we are in a code block (more is
1835 # true)
1835 # true)
1836
1836
1837 if line or more:
1837 if line or more:
1838 # push to raw history, so hist line numbers stay in sync
1838 # push to raw history, so hist line numbers stay in sync
1839 self.input_hist_raw.append("# " + line + "\n")
1839 self.input_hist_raw.append("# " + line + "\n")
1840 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1840 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1841 more = self.push_line(prefiltered)
1841 more = self.push_line(prefiltered)
1842 # IPython's runsource returns None if there was an error
1842 # IPython's runsource returns None if there was an error
1843 # compiling the code. This allows us to stop processing right
1843 # compiling the code. This allows us to stop processing right
1844 # away, so the user gets the error message at the right place.
1844 # away, so the user gets the error message at the right place.
1845 if more is None:
1845 if more is None:
1846 break
1846 break
1847 else:
1847 else:
1848 self.input_hist_raw.append("\n")
1848 self.input_hist_raw.append("\n")
1849 # final newline in case the input didn't have it, so that the code
1849 # final newline in case the input didn't have it, so that the code
1850 # actually does get executed
1850 # actually does get executed
1851 if more:
1851 if more:
1852 self.push_line('\n')
1852 self.push_line('\n')
1853
1853
1854 def runsource(self, source, filename='<input>', symbol='single'):
1854 def runsource(self, source, filename='<input>', symbol='single'):
1855 """Compile and run some source in the interpreter.
1855 """Compile and run some source in the interpreter.
1856
1856
1857 Arguments are as for compile_command().
1857 Arguments are as for compile_command().
1858
1858
1859 One several things can happen:
1859 One several things can happen:
1860
1860
1861 1) The input is incorrect; compile_command() raised an
1861 1) The input is incorrect; compile_command() raised an
1862 exception (SyntaxError or OverflowError). A syntax traceback
1862 exception (SyntaxError or OverflowError). A syntax traceback
1863 will be printed by calling the showsyntaxerror() method.
1863 will be printed by calling the showsyntaxerror() method.
1864
1864
1865 2) The input is incomplete, and more input is required;
1865 2) The input is incomplete, and more input is required;
1866 compile_command() returned None. Nothing happens.
1866 compile_command() returned None. Nothing happens.
1867
1867
1868 3) The input is complete; compile_command() returned a code
1868 3) The input is complete; compile_command() returned a code
1869 object. The code is executed by calling self.runcode() (which
1869 object. The code is executed by calling self.runcode() (which
1870 also handles run-time exceptions, except for SystemExit).
1870 also handles run-time exceptions, except for SystemExit).
1871
1871
1872 The return value is:
1872 The return value is:
1873
1873
1874 - True in case 2
1874 - True in case 2
1875
1875
1876 - False in the other cases, unless an exception is raised, where
1876 - False in the other cases, unless an exception is raised, where
1877 None is returned instead. This can be used by external callers to
1877 None is returned instead. This can be used by external callers to
1878 know whether to continue feeding input or not.
1878 know whether to continue feeding input or not.
1879
1879
1880 The return value can be used to decide whether to use sys.ps1 or
1880 The return value can be used to decide whether to use sys.ps1 or
1881 sys.ps2 to prompt the next line."""
1881 sys.ps2 to prompt the next line."""
1882
1882
1883 # if the source code has leading blanks, add 'if 1:\n' to it
1883 # if the source code has leading blanks, add 'if 1:\n' to it
1884 # this allows execution of indented pasted code. It is tempting
1884 # this allows execution of indented pasted code. It is tempting
1885 # to add '\n' at the end of source to run commands like ' a=1'
1885 # to add '\n' at the end of source to run commands like ' a=1'
1886 # directly, but this fails for more complicated scenarios
1886 # directly, but this fails for more complicated scenarios
1887 source=source.encode(self.stdin_encoding)
1887 source=source.encode(self.stdin_encoding)
1888 if source[:1] in [' ', '\t']:
1888 if source[:1] in [' ', '\t']:
1889 source = 'if 1:\n%s' % source
1889 source = 'if 1:\n%s' % source
1890
1890
1891 try:
1891 try:
1892 code = self.compile(source,filename,symbol)
1892 code = self.compile(source,filename,symbol)
1893 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1893 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1894 # Case 1
1894 # Case 1
1895 self.showsyntaxerror(filename)
1895 self.showsyntaxerror(filename)
1896 return None
1896 return None
1897
1897
1898 if code is None:
1898 if code is None:
1899 # Case 2
1899 # Case 2
1900 return True
1900 return True
1901
1901
1902 # Case 3
1902 # Case 3
1903 # We store the code object so that threaded shells and
1903 # We store the code object so that threaded shells and
1904 # custom exception handlers can access all this info if needed.
1904 # custom exception handlers can access all this info if needed.
1905 # The source corresponding to this can be obtained from the
1905 # The source corresponding to this can be obtained from the
1906 # buffer attribute as '\n'.join(self.buffer).
1906 # buffer attribute as '\n'.join(self.buffer).
1907 self.code_to_run = code
1907 self.code_to_run = code
1908 # now actually execute the code object
1908 # now actually execute the code object
1909 if self.runcode(code) == 0:
1909 if self.runcode(code) == 0:
1910 return False
1910 return False
1911 else:
1911 else:
1912 return None
1912 return None
1913
1913
1914 def runcode(self,code_obj):
1914 def runcode(self,code_obj):
1915 """Execute a code object.
1915 """Execute a code object.
1916
1916
1917 When an exception occurs, self.showtraceback() is called to display a
1917 When an exception occurs, self.showtraceback() is called to display a
1918 traceback.
1918 traceback.
1919
1919
1920 Return value: a flag indicating whether the code to be run completed
1920 Return value: a flag indicating whether the code to be run completed
1921 successfully:
1921 successfully:
1922
1922
1923 - 0: successful execution.
1923 - 0: successful execution.
1924 - 1: an error occurred.
1924 - 1: an error occurred.
1925 """
1925 """
1926
1926
1927 # Set our own excepthook in case the user code tries to call it
1927 # Set our own excepthook in case the user code tries to call it
1928 # directly, so that the IPython crash handler doesn't get triggered
1928 # directly, so that the IPython crash handler doesn't get triggered
1929 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1929 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1930
1930
1931 # we save the original sys.excepthook in the instance, in case config
1931 # we save the original sys.excepthook in the instance, in case config
1932 # code (such as magics) needs access to it.
1932 # code (such as magics) needs access to it.
1933 self.sys_excepthook = old_excepthook
1933 self.sys_excepthook = old_excepthook
1934 outflag = 1 # happens in more places, so it's easier as default
1934 outflag = 1 # happens in more places, so it's easier as default
1935 try:
1935 try:
1936 try:
1936 try:
1937 self.hooks.pre_runcode_hook()
1937 self.hooks.pre_runcode_hook()
1938 #rprint('Running code') # dbg
1938 #rprint('Running code') # dbg
1939 exec code_obj in self.user_global_ns, self.user_ns
1939 exec code_obj in self.user_global_ns, self.user_ns
1940 finally:
1940 finally:
1941 # Reset our crash handler in place
1941 # Reset our crash handler in place
1942 sys.excepthook = old_excepthook
1942 sys.excepthook = old_excepthook
1943 except SystemExit:
1943 except SystemExit:
1944 self.resetbuffer()
1944 self.resetbuffer()
1945 self.showtraceback(exception_only=True)
1945 self.showtraceback(exception_only=True)
1946 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1946 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1947 except self.custom_exceptions:
1947 except self.custom_exceptions:
1948 etype,value,tb = sys.exc_info()
1948 etype,value,tb = sys.exc_info()
1949 self.CustomTB(etype,value,tb)
1949 self.CustomTB(etype,value,tb)
1950 except:
1950 except:
1951 self.showtraceback()
1951 self.showtraceback()
1952 else:
1952 else:
1953 outflag = 0
1953 outflag = 0
1954 if softspace(sys.stdout, 0):
1954 if softspace(sys.stdout, 0):
1955 print
1955 print
1956 # Flush out code object which has been run (and source)
1956 # Flush out code object which has been run (and source)
1957 self.code_to_run = None
1957 self.code_to_run = None
1958 return outflag
1958 return outflag
1959
1959
1960 def push_line(self, line):
1960 def push_line(self, line):
1961 """Push a line to the interpreter.
1961 """Push a line to the interpreter.
1962
1962
1963 The line should not have a trailing newline; it may have
1963 The line should not have a trailing newline; it may have
1964 internal newlines. The line is appended to a buffer and the
1964 internal newlines. The line is appended to a buffer and the
1965 interpreter's runsource() method is called with the
1965 interpreter's runsource() method is called with the
1966 concatenated contents of the buffer as source. If this
1966 concatenated contents of the buffer as source. If this
1967 indicates that the command was executed or invalid, the buffer
1967 indicates that the command was executed or invalid, the buffer
1968 is reset; otherwise, the command is incomplete, and the buffer
1968 is reset; otherwise, the command is incomplete, and the buffer
1969 is left as it was after the line was appended. The return
1969 is left as it was after the line was appended. The return
1970 value is 1 if more input is required, 0 if the line was dealt
1970 value is 1 if more input is required, 0 if the line was dealt
1971 with in some way (this is the same as runsource()).
1971 with in some way (this is the same as runsource()).
1972 """
1972 """
1973
1973
1974 # autoindent management should be done here, and not in the
1974 # autoindent management should be done here, and not in the
1975 # interactive loop, since that one is only seen by keyboard input. We
1975 # interactive loop, since that one is only seen by keyboard input. We
1976 # need this done correctly even for code run via runlines (which uses
1976 # need this done correctly even for code run via runlines (which uses
1977 # push).
1977 # push).
1978
1978
1979 #print 'push line: <%s>' % line # dbg
1979 #print 'push line: <%s>' % line # dbg
1980 for subline in line.splitlines():
1980 for subline in line.splitlines():
1981 self._autoindent_update(subline)
1981 self._autoindent_update(subline)
1982 self.buffer.append(line)
1982 self.buffer.append(line)
1983 more = self.runsource('\n'.join(self.buffer), self.filename)
1983 more = self.runsource('\n'.join(self.buffer), self.filename)
1984 if not more:
1984 if not more:
1985 self.resetbuffer()
1985 self.resetbuffer()
1986 return more
1986 return more
1987
1987
1988 def resetbuffer(self):
1988 def resetbuffer(self):
1989 """Reset the input buffer."""
1989 """Reset the input buffer."""
1990 self.buffer[:] = []
1990 self.buffer[:] = []
1991
1991
1992 def _is_secondary_block_start(self, s):
1992 def _is_secondary_block_start(self, s):
1993 if not s.endswith(':'):
1993 if not s.endswith(':'):
1994 return False
1994 return False
1995 if (s.startswith('elif') or
1995 if (s.startswith('elif') or
1996 s.startswith('else') or
1996 s.startswith('else') or
1997 s.startswith('except') or
1997 s.startswith('except') or
1998 s.startswith('finally')):
1998 s.startswith('finally')):
1999 return True
1999 return True
2000
2000
2001 def _cleanup_ipy_script(self, script):
2001 def _cleanup_ipy_script(self, script):
2002 """Make a script safe for self.runlines()
2002 """Make a script safe for self.runlines()
2003
2003
2004 Currently, IPython is lines based, with blocks being detected by
2004 Currently, IPython is lines based, with blocks being detected by
2005 empty lines. This is a problem for block based scripts that may
2005 empty lines. This is a problem for block based scripts that may
2006 not have empty lines after blocks. This script adds those empty
2006 not have empty lines after blocks. This script adds those empty
2007 lines to make scripts safe for running in the current line based
2007 lines to make scripts safe for running in the current line based
2008 IPython.
2008 IPython.
2009 """
2009 """
2010 res = []
2010 res = []
2011 lines = script.splitlines()
2011 lines = script.splitlines()
2012 level = 0
2012 level = 0
2013
2013
2014 for l in lines:
2014 for l in lines:
2015 lstripped = l.lstrip()
2015 lstripped = l.lstrip()
2016 stripped = l.strip()
2016 stripped = l.strip()
2017 if not stripped:
2017 if not stripped:
2018 continue
2018 continue
2019 newlevel = len(l) - len(lstripped)
2019 newlevel = len(l) - len(lstripped)
2020 if level > 0 and newlevel == 0 and \
2020 if level > 0 and newlevel == 0 and \
2021 not self._is_secondary_block_start(stripped):
2021 not self._is_secondary_block_start(stripped):
2022 # add empty line
2022 # add empty line
2023 res.append('')
2023 res.append('')
2024 res.append(l)
2024 res.append(l)
2025 level = newlevel
2025 level = newlevel
2026
2026
2027 return '\n'.join(res) + '\n'
2027 return '\n'.join(res) + '\n'
2028
2028
2029 def _autoindent_update(self,line):
2029 def _autoindent_update(self,line):
2030 """Keep track of the indent level."""
2030 """Keep track of the indent level."""
2031
2031
2032 #debugx('line')
2032 #debugx('line')
2033 #debugx('self.indent_current_nsp')
2033 #debugx('self.indent_current_nsp')
2034 if self.autoindent:
2034 if self.autoindent:
2035 if line:
2035 if line:
2036 inisp = num_ini_spaces(line)
2036 inisp = num_ini_spaces(line)
2037 if inisp < self.indent_current_nsp:
2037 if inisp < self.indent_current_nsp:
2038 self.indent_current_nsp = inisp
2038 self.indent_current_nsp = inisp
2039
2039
2040 if line[-1] == ':':
2040 if line[-1] == ':':
2041 self.indent_current_nsp += 4
2041 self.indent_current_nsp += 4
2042 elif dedent_re.match(line):
2042 elif dedent_re.match(line):
2043 self.indent_current_nsp -= 4
2043 self.indent_current_nsp -= 4
2044 else:
2044 else:
2045 self.indent_current_nsp = 0
2045 self.indent_current_nsp = 0
2046
2046
2047 #-------------------------------------------------------------------------
2047 #-------------------------------------------------------------------------
2048 # Things related to GUI support and pylab
2048 # Things related to GUI support and pylab
2049 #-------------------------------------------------------------------------
2049 #-------------------------------------------------------------------------
2050
2050
2051 def enable_pylab(self, gui=None):
2051 def enable_pylab(self, gui=None):
2052 raise NotImplementedError('Implement enable_pylab in a subclass')
2052 raise NotImplementedError('Implement enable_pylab in a subclass')
2053
2053
2054 #-------------------------------------------------------------------------
2054 #-------------------------------------------------------------------------
2055 # Utilities
2055 # Utilities
2056 #-------------------------------------------------------------------------
2056 #-------------------------------------------------------------------------
2057
2057
2058 def getoutput(self, cmd):
2058 def getoutput(self, cmd):
2059 return getoutput(self.var_expand(cmd,depth=2),
2059 return getoutput(self.var_expand(cmd,depth=2),
2060 header=self.system_header,
2060 header=self.system_header,
2061 verbose=self.system_verbose)
2061 verbose=self.system_verbose)
2062
2062
2063 def getoutputerror(self, cmd):
2063 def getoutputerror(self, cmd):
2064 return getoutputerror(self.var_expand(cmd,depth=2),
2064 return getoutputerror(self.var_expand(cmd,depth=2),
2065 header=self.system_header,
2065 header=self.system_header,
2066 verbose=self.system_verbose)
2066 verbose=self.system_verbose)
2067
2067
2068 def var_expand(self,cmd,depth=0):
2068 def var_expand(self,cmd,depth=0):
2069 """Expand python variables in a string.
2069 """Expand python variables in a string.
2070
2070
2071 The depth argument indicates how many frames above the caller should
2071 The depth argument indicates how many frames above the caller should
2072 be walked to look for the local namespace where to expand variables.
2072 be walked to look for the local namespace where to expand variables.
2073
2073
2074 The global namespace for expansion is always the user's interactive
2074 The global namespace for expansion is always the user's interactive
2075 namespace.
2075 namespace.
2076 """
2076 """
2077
2077
2078 return str(ItplNS(cmd,
2078 return str(ItplNS(cmd,
2079 self.user_ns, # globals
2079 self.user_ns, # globals
2080 # Skip our own frame in searching for locals:
2080 # Skip our own frame in searching for locals:
2081 sys._getframe(depth+1).f_locals # locals
2081 sys._getframe(depth+1).f_locals # locals
2082 ))
2082 ))
2083
2083
2084 def mktempfile(self,data=None):
2084 def mktempfile(self,data=None):
2085 """Make a new tempfile and return its filename.
2085 """Make a new tempfile and return its filename.
2086
2086
2087 This makes a call to tempfile.mktemp, but it registers the created
2087 This makes a call to tempfile.mktemp, but it registers the created
2088 filename internally so ipython cleans it up at exit time.
2088 filename internally so ipython cleans it up at exit time.
2089
2089
2090 Optional inputs:
2090 Optional inputs:
2091
2091
2092 - data(None): if data is given, it gets written out to the temp file
2092 - data(None): if data is given, it gets written out to the temp file
2093 immediately, and the file is closed again."""
2093 immediately, and the file is closed again."""
2094
2094
2095 filename = tempfile.mktemp('.py','ipython_edit_')
2095 filename = tempfile.mktemp('.py','ipython_edit_')
2096 self.tempfiles.append(filename)
2096 self.tempfiles.append(filename)
2097
2097
2098 if data:
2098 if data:
2099 tmp_file = open(filename,'w')
2099 tmp_file = open(filename,'w')
2100 tmp_file.write(data)
2100 tmp_file.write(data)
2101 tmp_file.close()
2101 tmp_file.close()
2102 return filename
2102 return filename
2103
2103
2104 # TODO: This should be removed when Term is refactored.
2104 # TODO: This should be removed when Term is refactored.
2105 def write(self,data):
2105 def write(self,data):
2106 """Write a string to the default output"""
2106 """Write a string to the default output"""
2107 io.Term.cout.write(data)
2107 io.Term.cout.write(data)
2108
2108
2109 # TODO: This should be removed when Term is refactored.
2109 # TODO: This should be removed when Term is refactored.
2110 def write_err(self,data):
2110 def write_err(self,data):
2111 """Write a string to the default error output"""
2111 """Write a string to the default error output"""
2112 io.Term.cerr.write(data)
2112 io.Term.cerr.write(data)
2113
2113
2114 def ask_yes_no(self,prompt,default=True):
2114 def ask_yes_no(self,prompt,default=True):
2115 if self.quiet:
2115 if self.quiet:
2116 return True
2116 return True
2117 return ask_yes_no(prompt,default)
2117 return ask_yes_no(prompt,default)
2118
2118
2119 #-------------------------------------------------------------------------
2119 #-------------------------------------------------------------------------
2120 # Things related to IPython exiting
2120 # Things related to IPython exiting
2121 #-------------------------------------------------------------------------
2121 #-------------------------------------------------------------------------
2122
2122
2123 def atexit_operations(self):
2123 def atexit_operations(self):
2124 """This will be executed at the time of exit.
2124 """This will be executed at the time of exit.
2125
2125
2126 Saving of persistent data should be performed here.
2126 Saving of persistent data should be performed here.
2127 """
2127 """
2128 self.savehist()
2128 self.savehist()
2129
2129
2130 # Cleanup all tempfiles left around
2130 # Cleanup all tempfiles left around
2131 for tfile in self.tempfiles:
2131 for tfile in self.tempfiles:
2132 try:
2132 try:
2133 os.unlink(tfile)
2133 os.unlink(tfile)
2134 except OSError:
2134 except OSError:
2135 pass
2135 pass
2136
2136
2137 # Clear all user namespaces to release all references cleanly.
2137 # Clear all user namespaces to release all references cleanly.
2138 self.reset()
2138 self.reset()
2139
2139
2140 # Run user hooks
2140 # Run user hooks
2141 self.hooks.shutdown_hook()
2141 self.hooks.shutdown_hook()
2142
2142
2143 def cleanup(self):
2143 def cleanup(self):
2144 self.restore_sys_module_state()
2144 self.restore_sys_module_state()
2145
2145
2146
2146
2147 class InteractiveShellABC(object):
2147 class InteractiveShellABC(object):
2148 """An abstract base class for InteractiveShell."""
2148 """An abstract base class for InteractiveShell."""
2149 __metaclass__ = abc.ABCMeta
2149 __metaclass__ = abc.ABCMeta
2150
2150
2151 InteractiveShellABC.register(InteractiveShell)
2151 InteractiveShellABC.register(InteractiveShell)
@@ -1,1224 +1,1224 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 ultratb.py -- Spice up your tracebacks!
3 ultratb.py -- Spice up your tracebacks!
4
4
5 * ColorTB
5 * ColorTB
6 I've always found it a bit hard to visually parse tracebacks in Python. The
6 I've always found it a bit hard to visually parse tracebacks in Python. The
7 ColorTB class is a solution to that problem. It colors the different parts of a
7 ColorTB class is a solution to that problem. It colors the different parts of a
8 traceback in a manner similar to what you would expect from a syntax-highlighting
8 traceback in a manner similar to what you would expect from a syntax-highlighting
9 text editor.
9 text editor.
10
10
11 Installation instructions for ColorTB:
11 Installation instructions for ColorTB:
12 import sys,ultratb
12 import sys,ultratb
13 sys.excepthook = ultratb.ColorTB()
13 sys.excepthook = ultratb.ColorTB()
14
14
15 * VerboseTB
15 * VerboseTB
16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
17 of useful info when a traceback occurs. Ping originally had it spit out HTML
17 of useful info when a traceback occurs. Ping originally had it spit out HTML
18 and intended it for CGI programmers, but why should they have all the fun? I
18 and intended it for CGI programmers, but why should they have all the fun? I
19 altered it to spit out colored text to the terminal. It's a bit overwhelming,
19 altered it to spit out colored text to the terminal. It's a bit overwhelming,
20 but kind of neat, and maybe useful for long-running programs that you believe
20 but kind of neat, and maybe useful for long-running programs that you believe
21 are bug-free. If a crash *does* occur in that type of program you want details.
21 are bug-free. If a crash *does* occur in that type of program you want details.
22 Give it a shot--you'll love it or you'll hate it.
22 Give it a shot--you'll love it or you'll hate it.
23
23
24 Note:
24 Note:
25
25
26 The Verbose mode prints the variables currently visible where the exception
26 The Verbose mode prints the variables currently visible where the exception
27 happened (shortening their strings if too long). This can potentially be
27 happened (shortening their strings if too long). This can potentially be
28 very slow, if you happen to have a huge data structure whose string
28 very slow, if you happen to have a huge data structure whose string
29 representation is complex to compute. Your computer may appear to freeze for
29 representation is complex to compute. Your computer may appear to freeze for
30 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
30 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
31 with Ctrl-C (maybe hitting it more than once).
31 with Ctrl-C (maybe hitting it more than once).
32
32
33 If you encounter this kind of situation often, you may want to use the
33 If you encounter this kind of situation often, you may want to use the
34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
35 variables (but otherwise includes the information and context given by
35 variables (but otherwise includes the information and context given by
36 Verbose).
36 Verbose).
37
37
38
38
39 Installation instructions for ColorTB:
39 Installation instructions for ColorTB:
40 import sys,ultratb
40 import sys,ultratb
41 sys.excepthook = ultratb.VerboseTB()
41 sys.excepthook = ultratb.VerboseTB()
42
42
43 Note: Much of the code in this module was lifted verbatim from the standard
43 Note: Much of the code in this module was lifted verbatim from the standard
44 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
44 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
45
45
46 * Color schemes
46 * Color schemes
47 The colors are defined in the class TBTools through the use of the
47 The colors are defined in the class TBTools through the use of the
48 ColorSchemeTable class. Currently the following exist:
48 ColorSchemeTable class. Currently the following exist:
49
49
50 - NoColor: allows all of this module to be used in any terminal (the color
50 - NoColor: allows all of this module to be used in any terminal (the color
51 escapes are just dummy blank strings).
51 escapes are just dummy blank strings).
52
52
53 - Linux: is meant to look good in a terminal like the Linux console (black
53 - Linux: is meant to look good in a terminal like the Linux console (black
54 or very dark background).
54 or very dark background).
55
55
56 - LightBG: similar to Linux but swaps dark/light colors to be more readable
56 - LightBG: similar to Linux but swaps dark/light colors to be more readable
57 in light background terminals.
57 in light background terminals.
58
58
59 You can implement other color schemes easily, the syntax is fairly
59 You can implement other color schemes easily, the syntax is fairly
60 self-explanatory. Please send back new schemes you develop to the author for
60 self-explanatory. Please send back new schemes you develop to the author for
61 possible inclusion in future releases.
61 possible inclusion in future releases.
62 """
62 """
63
63
64 #*****************************************************************************
64 #*****************************************************************************
65 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
65 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
66 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
66 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
67 #
67 #
68 # Distributed under the terms of the BSD License. The full license is in
68 # Distributed under the terms of the BSD License. The full license is in
69 # the file COPYING, distributed as part of this software.
69 # the file COPYING, distributed as part of this software.
70 #*****************************************************************************
70 #*****************************************************************************
71
71
72 from __future__ import with_statement
72 from __future__ import with_statement
73
73
74 import inspect
74 import inspect
75 import keyword
75 import keyword
76 import linecache
76 import linecache
77 import os
77 import os
78 import pydoc
78 import pydoc
79 import re
79 import re
80 import string
80 import string
81 import sys
81 import sys
82 import time
82 import time
83 import tokenize
83 import tokenize
84 import traceback
84 import traceback
85 import types
85 import types
86
86
87 # For purposes of monkeypatching inspect to fix a bug in it.
87 # For purposes of monkeypatching inspect to fix a bug in it.
88 from inspect import getsourcefile, getfile, getmodule,\
88 from inspect import getsourcefile, getfile, getmodule,\
89 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
89 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
90
90
91 # IPython's own modules
91 # IPython's own modules
92 # Modified pdb which doesn't damage IPython's readline handling
92 # Modified pdb which doesn't damage IPython's readline handling
93 from IPython.core import debugger, ipapi
93 from IPython.core import debugger, ipapi
94 from IPython.core.display_trap import DisplayTrap
94 from IPython.core.display_trap import DisplayTrap
95 from IPython.core.excolors import exception_colors
95 from IPython.core.excolors import exception_colors
96 from IPython.utils import PyColorize
96 from IPython.utils import PyColorize
97 from IPython.utils import io
97 from IPython.utils import io
98 from IPython.utils.data import uniq_stable
98 from IPython.utils.data import uniq_stable
99 from IPython.utils.warn import info, error
99 from IPython.utils.warn import info, error
100
100
101 # Globals
101 # Globals
102 # amount of space to put line numbers before verbose tracebacks
102 # amount of space to put line numbers before verbose tracebacks
103 INDENT_SIZE = 8
103 INDENT_SIZE = 8
104
104
105 # Default color scheme. This is used, for example, by the traceback
105 # Default color scheme. This is used, for example, by the traceback
106 # formatter. When running in an actual IPython instance, the user's rc.colors
106 # formatter. When running in an actual IPython instance, the user's rc.colors
107 # value is used, but havinga module global makes this functionality available
107 # value is used, but havinga module global makes this functionality available
108 # to users of ultratb who are NOT running inside ipython.
108 # to users of ultratb who are NOT running inside ipython.
109 DEFAULT_SCHEME = 'NoColor'
109 DEFAULT_SCHEME = 'NoColor'
110
110
111 #---------------------------------------------------------------------------
111 #---------------------------------------------------------------------------
112 # Code begins
112 # Code begins
113
113
114 # Utility functions
114 # Utility functions
115 def inspect_error():
115 def inspect_error():
116 """Print a message about internal inspect errors.
116 """Print a message about internal inspect errors.
117
117
118 These are unfortunately quite common."""
118 These are unfortunately quite common."""
119
119
120 error('Internal Python error in the inspect module.\n'
120 error('Internal Python error in the inspect module.\n'
121 'Below is the traceback from this internal error.\n')
121 'Below is the traceback from this internal error.\n')
122
122
123
123
124 def findsource(object):
124 def findsource(object):
125 """Return the entire source file and starting line number for an object.
125 """Return the entire source file and starting line number for an object.
126
126
127 The argument may be a module, class, method, function, traceback, frame,
127 The argument may be a module, class, method, function, traceback, frame,
128 or code object. The source code is returned as a list of all the lines
128 or code object. The source code is returned as a list of all the lines
129 in the file and the line number indexes a line in that list. An IOError
129 in the file and the line number indexes a line in that list. An IOError
130 is raised if the source code cannot be retrieved.
130 is raised if the source code cannot be retrieved.
131
131
132 FIXED version with which we monkeypatch the stdlib to work around a bug."""
132 FIXED version with which we monkeypatch the stdlib to work around a bug."""
133
133
134 file = getsourcefile(object) or getfile(object)
134 file = getsourcefile(object) or getfile(object)
135 # If the object is a frame, then trying to get the globals dict from its
135 # If the object is a frame, then trying to get the globals dict from its
136 # module won't work. Instead, the frame object itself has the globals
136 # module won't work. Instead, the frame object itself has the globals
137 # dictionary.
137 # dictionary.
138 globals_dict = None
138 globals_dict = None
139 if inspect.isframe(object):
139 if inspect.isframe(object):
140 # XXX: can this ever be false?
140 # XXX: can this ever be false?
141 globals_dict = object.f_globals
141 globals_dict = object.f_globals
142 else:
142 else:
143 module = getmodule(object, file)
143 module = getmodule(object, file)
144 if module:
144 if module:
145 globals_dict = module.__dict__
145 globals_dict = module.__dict__
146 lines = linecache.getlines(file, globals_dict)
146 lines = linecache.getlines(file, globals_dict)
147 if not lines:
147 if not lines:
148 raise IOError('could not get source code')
148 raise IOError('could not get source code')
149
149
150 if ismodule(object):
150 if ismodule(object):
151 return lines, 0
151 return lines, 0
152
152
153 if isclass(object):
153 if isclass(object):
154 name = object.__name__
154 name = object.__name__
155 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
155 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
156 # make some effort to find the best matching class definition:
156 # make some effort to find the best matching class definition:
157 # use the one with the least indentation, which is the one
157 # use the one with the least indentation, which is the one
158 # that's most probably not inside a function definition.
158 # that's most probably not inside a function definition.
159 candidates = []
159 candidates = []
160 for i in range(len(lines)):
160 for i in range(len(lines)):
161 match = pat.match(lines[i])
161 match = pat.match(lines[i])
162 if match:
162 if match:
163 # if it's at toplevel, it's already the best one
163 # if it's at toplevel, it's already the best one
164 if lines[i][0] == 'c':
164 if lines[i][0] == 'c':
165 return lines, i
165 return lines, i
166 # else add whitespace to candidate list
166 # else add whitespace to candidate list
167 candidates.append((match.group(1), i))
167 candidates.append((match.group(1), i))
168 if candidates:
168 if candidates:
169 # this will sort by whitespace, and by line number,
169 # this will sort by whitespace, and by line number,
170 # less whitespace first
170 # less whitespace first
171 candidates.sort()
171 candidates.sort()
172 return lines, candidates[0][1]
172 return lines, candidates[0][1]
173 else:
173 else:
174 raise IOError('could not find class definition')
174 raise IOError('could not find class definition')
175
175
176 if ismethod(object):
176 if ismethod(object):
177 object = object.im_func
177 object = object.im_func
178 if isfunction(object):
178 if isfunction(object):
179 object = object.func_code
179 object = object.func_code
180 if istraceback(object):
180 if istraceback(object):
181 object = object.tb_frame
181 object = object.tb_frame
182 if isframe(object):
182 if isframe(object):
183 object = object.f_code
183 object = object.f_code
184 if iscode(object):
184 if iscode(object):
185 if not hasattr(object, 'co_firstlineno'):
185 if not hasattr(object, 'co_firstlineno'):
186 raise IOError('could not find function definition')
186 raise IOError('could not find function definition')
187 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
187 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
188 pmatch = pat.match
188 pmatch = pat.match
189 # fperez - fix: sometimes, co_firstlineno can give a number larger than
189 # fperez - fix: sometimes, co_firstlineno can give a number larger than
190 # the length of lines, which causes an error. Safeguard against that.
190 # the length of lines, which causes an error. Safeguard against that.
191 lnum = min(object.co_firstlineno,len(lines))-1
191 lnum = min(object.co_firstlineno,len(lines))-1
192 while lnum > 0:
192 while lnum > 0:
193 if pmatch(lines[lnum]): break
193 if pmatch(lines[lnum]): break
194 lnum -= 1
194 lnum -= 1
195
195
196 return lines, lnum
196 return lines, lnum
197 raise IOError('could not find code object')
197 raise IOError('could not find code object')
198
198
199 # Monkeypatch inspect to apply our bugfix. This code only works with py25
199 # Monkeypatch inspect to apply our bugfix. This code only works with py25
200 if sys.version_info[:2] >= (2,5):
200 if sys.version_info[:2] >= (2,5):
201 inspect.findsource = findsource
201 inspect.findsource = findsource
202
202
203 def fix_frame_records_filenames(records):
203 def fix_frame_records_filenames(records):
204 """Try to fix the filenames in each record from inspect.getinnerframes().
204 """Try to fix the filenames in each record from inspect.getinnerframes().
205
205
206 Particularly, modules loaded from within zip files have useless filenames
206 Particularly, modules loaded from within zip files have useless filenames
207 attached to their code object, and inspect.getinnerframes() just uses it.
207 attached to their code object, and inspect.getinnerframes() just uses it.
208 """
208 """
209 fixed_records = []
209 fixed_records = []
210 for frame, filename, line_no, func_name, lines, index in records:
210 for frame, filename, line_no, func_name, lines, index in records:
211 # Look inside the frame's globals dictionary for __file__, which should
211 # Look inside the frame's globals dictionary for __file__, which should
212 # be better.
212 # be better.
213 better_fn = frame.f_globals.get('__file__', None)
213 better_fn = frame.f_globals.get('__file__', None)
214 if isinstance(better_fn, str):
214 if isinstance(better_fn, str):
215 # Check the type just in case someone did something weird with
215 # Check the type just in case someone did something weird with
216 # __file__. It might also be None if the error occurred during
216 # __file__. It might also be None if the error occurred during
217 # import.
217 # import.
218 filename = better_fn
218 filename = better_fn
219 fixed_records.append((frame, filename, line_no, func_name, lines, index))
219 fixed_records.append((frame, filename, line_no, func_name, lines, index))
220 return fixed_records
220 return fixed_records
221
221
222
222
223 def _fixed_getinnerframes(etb, context=1,tb_offset=0):
223 def _fixed_getinnerframes(etb, context=1,tb_offset=0):
224 import linecache
224 import linecache
225 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
225 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
226
226
227 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
227 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
228
228
229 # If the error is at the console, don't build any context, since it would
229 # If the error is at the console, don't build any context, since it would
230 # otherwise produce 5 blank lines printed out (there is no file at the
230 # otherwise produce 5 blank lines printed out (there is no file at the
231 # console)
231 # console)
232 rec_check = records[tb_offset:]
232 rec_check = records[tb_offset:]
233 try:
233 try:
234 rname = rec_check[0][1]
234 rname = rec_check[0][1]
235 if rname == '<ipython console>' or rname.endswith('<string>'):
235 if rname == '<ipython console>' or rname.endswith('<string>'):
236 return rec_check
236 return rec_check
237 except IndexError:
237 except IndexError:
238 pass
238 pass
239
239
240 aux = traceback.extract_tb(etb)
240 aux = traceback.extract_tb(etb)
241 assert len(records) == len(aux)
241 assert len(records) == len(aux)
242 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
242 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
243 maybeStart = lnum-1 - context//2
243 maybeStart = lnum-1 - context//2
244 start = max(maybeStart, 0)
244 start = max(maybeStart, 0)
245 end = start + context
245 end = start + context
246 lines = linecache.getlines(file)[start:end]
246 lines = linecache.getlines(file)[start:end]
247 # pad with empty lines if necessary
247 # pad with empty lines if necessary
248 if maybeStart < 0:
248 if maybeStart < 0:
249 lines = (['\n'] * -maybeStart) + lines
249 lines = (['\n'] * -maybeStart) + lines
250 if len(lines) < context:
250 if len(lines) < context:
251 lines += ['\n'] * (context - len(lines))
251 lines += ['\n'] * (context - len(lines))
252 buf = list(records[i])
252 buf = list(records[i])
253 buf[LNUM_POS] = lnum
253 buf[LNUM_POS] = lnum
254 buf[INDEX_POS] = lnum - 1 - start
254 buf[INDEX_POS] = lnum - 1 - start
255 buf[LINES_POS] = lines
255 buf[LINES_POS] = lines
256 records[i] = tuple(buf)
256 records[i] = tuple(buf)
257 return records[tb_offset:]
257 return records[tb_offset:]
258
258
259 # Helper function -- largely belongs to VerboseTB, but we need the same
259 # Helper function -- largely belongs to VerboseTB, but we need the same
260 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
260 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
261 # can be recognized properly by ipython.el's py-traceback-line-re
261 # can be recognized properly by ipython.el's py-traceback-line-re
262 # (SyntaxErrors have to be treated specially because they have no traceback)
262 # (SyntaxErrors have to be treated specially because they have no traceback)
263
263
264 _parser = PyColorize.Parser()
264 _parser = PyColorize.Parser()
265
265
266 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
266 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
267 numbers_width = INDENT_SIZE - 1
267 numbers_width = INDENT_SIZE - 1
268 res = []
268 res = []
269 i = lnum - index
269 i = lnum - index
270
270
271 # This lets us get fully syntax-highlighted tracebacks.
271 # This lets us get fully syntax-highlighted tracebacks.
272 if scheme is None:
272 if scheme is None:
273 ipinst = ipapi.get()
273 ipinst = ipapi.get()
274 if ipinst is not None:
274 if ipinst is not None:
275 scheme = ipinst.colors
275 scheme = ipinst.colors
276 else:
276 else:
277 scheme = DEFAULT_SCHEME
277 scheme = DEFAULT_SCHEME
278
278
279 _line_format = _parser.format2
279 _line_format = _parser.format2
280
280
281 for line in lines:
281 for line in lines:
282 new_line, err = _line_format(line,'str',scheme)
282 new_line, err = _line_format(line,'str',scheme)
283 if not err: line = new_line
283 if not err: line = new_line
284
284
285 if i == lnum:
285 if i == lnum:
286 # This is the line with the error
286 # This is the line with the error
287 pad = numbers_width - len(str(i))
287 pad = numbers_width - len(str(i))
288 if pad >= 3:
288 if pad >= 3:
289 marker = '-'*(pad-3) + '-> '
289 marker = '-'*(pad-3) + '-> '
290 elif pad == 2:
290 elif pad == 2:
291 marker = '> '
291 marker = '> '
292 elif pad == 1:
292 elif pad == 1:
293 marker = '>'
293 marker = '>'
294 else:
294 else:
295 marker = ''
295 marker = ''
296 num = marker + str(i)
296 num = marker + str(i)
297 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
297 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
298 Colors.line, line, Colors.Normal)
298 Colors.line, line, Colors.Normal)
299 else:
299 else:
300 num = '%*s' % (numbers_width,i)
300 num = '%*s' % (numbers_width,i)
301 line = '%s%s%s %s' %(Colors.lineno, num,
301 line = '%s%s%s %s' %(Colors.lineno, num,
302 Colors.Normal, line)
302 Colors.Normal, line)
303
303
304 res.append(line)
304 res.append(line)
305 if lvals and i == lnum:
305 if lvals and i == lnum:
306 res.append(lvals + '\n')
306 res.append(lvals + '\n')
307 i = i + 1
307 i = i + 1
308 return res
308 return res
309
309
310
310
311 #---------------------------------------------------------------------------
311 #---------------------------------------------------------------------------
312 # Module classes
312 # Module classes
313 class TBTools(object):
313 class TBTools(object):
314 """Basic tools used by all traceback printer classes."""
314 """Basic tools used by all traceback printer classes."""
315
315
316 # Number of frames to skip when reporting tracebacks
316 # Number of frames to skip when reporting tracebacks
317 tb_offset = 0
317 tb_offset = 0
318
318
319 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
319 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
320 # Whether to call the interactive pdb debugger after printing
320 # Whether to call the interactive pdb debugger after printing
321 # tracebacks or not
321 # tracebacks or not
322 self.call_pdb = call_pdb
322 self.call_pdb = call_pdb
323
323
324 # Output stream to write to. Note that we store the original value in
324 # Output stream to write to. Note that we store the original value in
325 # a private attribute and then make the public ostream a property, so
325 # a private attribute and then make the public ostream a property, so
326 # that we can delay accessing io.Term.cout until runtime. The way
326 # that we can delay accessing io.Term.cout until runtime. The way
327 # things are written now, the Term.cout object is dynamically managed
327 # things are written now, the Term.cout object is dynamically managed
328 # so a reference to it should NEVER be stored statically. This
328 # so a reference to it should NEVER be stored statically. This
329 # property approach confines this detail to a single location, and all
329 # property approach confines this detail to a single location, and all
330 # subclasses can simply access self.ostream for writing.
330 # subclasses can simply access self.ostream for writing.
331 self._ostream = ostream
331 self._ostream = ostream
332
332
333 # Create color table
333 # Create color table
334 self.color_scheme_table = exception_colors()
334 self.color_scheme_table = exception_colors()
335
335
336 self.set_colors(color_scheme)
336 self.set_colors(color_scheme)
337 self.old_scheme = color_scheme # save initial value for toggles
337 self.old_scheme = color_scheme # save initial value for toggles
338
338
339 if call_pdb:
339 if call_pdb:
340 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
340 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
341 else:
341 else:
342 self.pdb = None
342 self.pdb = None
343
343
344 def _get_ostream(self):
344 def _get_ostream(self):
345 """Output stream that exceptions are written to.
345 """Output stream that exceptions are written to.
346
346
347 Valid values are:
347 Valid values are:
348
348
349 - None: the default, which means that IPython will dynamically resolve
349 - None: the default, which means that IPython will dynamically resolve
350 to io.Term.cout. This ensures compatibility with most tools, including
350 to io.Term.cout. This ensures compatibility with most tools, including
351 Windows (where plain stdout doesn't recognize ANSI escapes).
351 Windows (where plain stdout doesn't recognize ANSI escapes).
352
352
353 - Any object with 'write' and 'flush' attributes.
353 - Any object with 'write' and 'flush' attributes.
354 """
354 """
355 return io.Term.cout if self._ostream is None else self._ostream
355 return io.Term.cout if self._ostream is None else self._ostream
356
356
357 def _set_ostream(self, val):
357 def _set_ostream(self, val):
358 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
358 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
359 self._ostream = val
359 self._ostream = val
360
360
361 ostream = property(_get_ostream, _set_ostream)
361 ostream = property(_get_ostream, _set_ostream)
362
362
363 def set_colors(self,*args,**kw):
363 def set_colors(self,*args,**kw):
364 """Shorthand access to the color table scheme selector method."""
364 """Shorthand access to the color table scheme selector method."""
365
365
366 # Set own color table
366 # Set own color table
367 self.color_scheme_table.set_active_scheme(*args,**kw)
367 self.color_scheme_table.set_active_scheme(*args,**kw)
368 # for convenience, set Colors to the active scheme
368 # for convenience, set Colors to the active scheme
369 self.Colors = self.color_scheme_table.active_colors
369 self.Colors = self.color_scheme_table.active_colors
370 # Also set colors of debugger
370 # Also set colors of debugger
371 if hasattr(self,'pdb') and self.pdb is not None:
371 if hasattr(self,'pdb') and self.pdb is not None:
372 self.pdb.set_colors(*args,**kw)
372 self.pdb.set_colors(*args,**kw)
373
373
374 def color_toggle(self):
374 def color_toggle(self):
375 """Toggle between the currently active color scheme and NoColor."""
375 """Toggle between the currently active color scheme and NoColor."""
376
376
377 if self.color_scheme_table.active_scheme_name == 'NoColor':
377 if self.color_scheme_table.active_scheme_name == 'NoColor':
378 self.color_scheme_table.set_active_scheme(self.old_scheme)
378 self.color_scheme_table.set_active_scheme(self.old_scheme)
379 self.Colors = self.color_scheme_table.active_colors
379 self.Colors = self.color_scheme_table.active_colors
380 else:
380 else:
381 self.old_scheme = self.color_scheme_table.active_scheme_name
381 self.old_scheme = self.color_scheme_table.active_scheme_name
382 self.color_scheme_table.set_active_scheme('NoColor')
382 self.color_scheme_table.set_active_scheme('NoColor')
383 self.Colors = self.color_scheme_table.active_colors
383 self.Colors = self.color_scheme_table.active_colors
384
384
385 def stb2text(self, stb):
385 def stb2text(self, stb):
386 """Convert a structured traceback (a list) to a string."""
386 """Convert a structured traceback (a list) to a string."""
387 return '\n'.join(stb)
387 return '\n'.join(stb)
388
388
389 def text(self, etype, value, tb, tb_offset=None, context=5):
389 def text(self, etype, value, tb, tb_offset=None, context=5):
390 """Return formatted traceback.
390 """Return formatted traceback.
391
391
392 Subclasses may override this if they add extra arguments.
392 Subclasses may override this if they add extra arguments.
393 """
393 """
394 tb_list = self.structured_traceback(etype, value, tb,
394 tb_list = self.structured_traceback(etype, value, tb,
395 tb_offset, context)
395 tb_offset, context)
396 return self.stb2text(tb_list)
396 return self.stb2text(tb_list)
397
397
398 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
398 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
399 context=5, mode=None):
399 context=5, mode=None):
400 """Return a list of traceback frames.
400 """Return a list of traceback frames.
401
401
402 Must be implemented by each class.
402 Must be implemented by each class.
403 """
403 """
404 raise NotImplementedError()
404 raise NotImplementedError()
405
405
406
406
407 #---------------------------------------------------------------------------
407 #---------------------------------------------------------------------------
408 class ListTB(TBTools):
408 class ListTB(TBTools):
409 """Print traceback information from a traceback list, with optional color.
409 """Print traceback information from a traceback list, with optional color.
410
410
411 Calling: requires 3 arguments:
411 Calling: requires 3 arguments:
412 (etype, evalue, elist)
412 (etype, evalue, elist)
413 as would be obtained by:
413 as would be obtained by:
414 etype, evalue, tb = sys.exc_info()
414 etype, evalue, tb = sys.exc_info()
415 if tb:
415 if tb:
416 elist = traceback.extract_tb(tb)
416 elist = traceback.extract_tb(tb)
417 else:
417 else:
418 elist = None
418 elist = None
419
419
420 It can thus be used by programs which need to process the traceback before
420 It can thus be used by programs which need to process the traceback before
421 printing (such as console replacements based on the code module from the
421 printing (such as console replacements based on the code module from the
422 standard library).
422 standard library).
423
423
424 Because they are meant to be called without a full traceback (only a
424 Because they are meant to be called without a full traceback (only a
425 list), instances of this class can't call the interactive pdb debugger."""
425 list), instances of this class can't call the interactive pdb debugger."""
426
426
427 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
427 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
428 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
428 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
429 ostream=ostream)
429 ostream=ostream)
430
430
431 def __call__(self, etype, value, elist):
431 def __call__(self, etype, value, elist):
432 self.ostream.flush()
432 self.ostream.flush()
433 self.ostream.write(self.text(etype, value, elist))
433 self.ostream.write(self.text(etype, value, elist))
434 self.ostream.write('\n')
434 self.ostream.write('\n')
435
435
436 def structured_traceback(self, etype, value, elist, tb_offset=None,
436 def structured_traceback(self, etype, value, elist, tb_offset=None,
437 context=5):
437 context=5):
438 """Return a color formatted string with the traceback info.
438 """Return a color formatted string with the traceback info.
439
439
440 Parameters
440 Parameters
441 ----------
441 ----------
442 etype : exception type
442 etype : exception type
443 Type of the exception raised.
443 Type of the exception raised.
444
444
445 value : object
445 value : object
446 Data stored in the exception
446 Data stored in the exception
447
447
448 elist : list
448 elist : list
449 List of frames, see class docstring for details.
449 List of frames, see class docstring for details.
450
450
451 tb_offset : int, optional
451 tb_offset : int, optional
452 Number of frames in the traceback to skip. If not given, the
452 Number of frames in the traceback to skip. If not given, the
453 instance value is used (set in constructor).
453 instance value is used (set in constructor).
454
454
455 context : int, optional
455 context : int, optional
456 Number of lines of context information to print.
456 Number of lines of context information to print.
457
457
458 Returns
458 Returns
459 -------
459 -------
460 String with formatted exception.
460 String with formatted exception.
461 """
461 """
462 tb_offset = self.tb_offset if tb_offset is None else tb_offset
462 tb_offset = self.tb_offset if tb_offset is None else tb_offset
463 Colors = self.Colors
463 Colors = self.Colors
464 out_list = []
464 out_list = []
465 if elist:
465 if elist:
466
466
467 if tb_offset and len(elist) > tb_offset:
467 if tb_offset and len(elist) > tb_offset:
468 elist = elist[tb_offset:]
468 elist = elist[tb_offset:]
469
469
470 out_list.append('Traceback %s(most recent call last)%s:' %
470 out_list.append('Traceback %s(most recent call last)%s:' %
471 (Colors.normalEm, Colors.Normal) + '\n')
471 (Colors.normalEm, Colors.Normal) + '\n')
472 out_list.extend(self._format_list(elist))
472 out_list.extend(self._format_list(elist))
473 # The exception info should be a single entry in the list.
473 # The exception info should be a single entry in the list.
474 lines = ''.join(self._format_exception_only(etype, value))
474 lines = ''.join(self._format_exception_only(etype, value))
475 out_list.append(lines)
475 out_list.append(lines)
476
476
477 # Note: this code originally read:
477 # Note: this code originally read:
478
478
479 ## for line in lines[:-1]:
479 ## for line in lines[:-1]:
480 ## out_list.append(" "+line)
480 ## out_list.append(" "+line)
481 ## out_list.append(lines[-1])
481 ## out_list.append(lines[-1])
482
482
483 # This means it was indenting everything but the last line by a little
483 # This means it was indenting everything but the last line by a little
484 # bit. I've disabled this for now, but if we see ugliness somewhre we
484 # bit. I've disabled this for now, but if we see ugliness somewhre we
485 # can restore it.
485 # can restore it.
486
486
487 return out_list
487 return out_list
488
488
489 def _format_list(self, extracted_list):
489 def _format_list(self, extracted_list):
490 """Format a list of traceback entry tuples for printing.
490 """Format a list of traceback entry tuples for printing.
491
491
492 Given a list of tuples as returned by extract_tb() or
492 Given a list of tuples as returned by extract_tb() or
493 extract_stack(), return a list of strings ready for printing.
493 extract_stack(), return a list of strings ready for printing.
494 Each string in the resulting list corresponds to the item with the
494 Each string in the resulting list corresponds to the item with the
495 same index in the argument list. Each string ends in a newline;
495 same index in the argument list. Each string ends in a newline;
496 the strings may contain internal newlines as well, for those items
496 the strings may contain internal newlines as well, for those items
497 whose source text line is not None.
497 whose source text line is not None.
498
498
499 Lifted almost verbatim from traceback.py
499 Lifted almost verbatim from traceback.py
500 """
500 """
501
501
502 Colors = self.Colors
502 Colors = self.Colors
503 list = []
503 list = []
504 for filename, lineno, name, line in extracted_list[:-1]:
504 for filename, lineno, name, line in extracted_list[:-1]:
505 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
505 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
506 (Colors.filename, filename, Colors.Normal,
506 (Colors.filename, filename, Colors.Normal,
507 Colors.lineno, lineno, Colors.Normal,
507 Colors.lineno, lineno, Colors.Normal,
508 Colors.name, name, Colors.Normal)
508 Colors.name, name, Colors.Normal)
509 if line:
509 if line:
510 item = item + ' %s\n' % line.strip()
510 item = item + ' %s\n' % line.strip()
511 list.append(item)
511 list.append(item)
512 # Emphasize the last entry
512 # Emphasize the last entry
513 filename, lineno, name, line = extracted_list[-1]
513 filename, lineno, name, line = extracted_list[-1]
514 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
514 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
515 (Colors.normalEm,
515 (Colors.normalEm,
516 Colors.filenameEm, filename, Colors.normalEm,
516 Colors.filenameEm, filename, Colors.normalEm,
517 Colors.linenoEm, lineno, Colors.normalEm,
517 Colors.linenoEm, lineno, Colors.normalEm,
518 Colors.nameEm, name, Colors.normalEm,
518 Colors.nameEm, name, Colors.normalEm,
519 Colors.Normal)
519 Colors.Normal)
520 if line:
520 if line:
521 item = item + '%s %s%s\n' % (Colors.line, line.strip(),
521 item = item + '%s %s%s\n' % (Colors.line, line.strip(),
522 Colors.Normal)
522 Colors.Normal)
523 list.append(item)
523 list.append(item)
524 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
524 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
525 return list
525 return list
526
526
527 def _format_exception_only(self, etype, value):
527 def _format_exception_only(self, etype, value):
528 """Format the exception part of a traceback.
528 """Format the exception part of a traceback.
529
529
530 The arguments are the exception type and value such as given by
530 The arguments are the exception type and value such as given by
531 sys.exc_info()[:2]. The return value is a list of strings, each ending
531 sys.exc_info()[:2]. The return value is a list of strings, each ending
532 in a newline. Normally, the list contains a single string; however,
532 in a newline. Normally, the list contains a single string; however,
533 for SyntaxError exceptions, it contains several lines that (when
533 for SyntaxError exceptions, it contains several lines that (when
534 printed) display detailed information about where the syntax error
534 printed) display detailed information about where the syntax error
535 occurred. The message indicating which exception occurred is the
535 occurred. The message indicating which exception occurred is the
536 always last string in the list.
536 always last string in the list.
537
537
538 Also lifted nearly verbatim from traceback.py
538 Also lifted nearly verbatim from traceback.py
539 """
539 """
540
540
541 have_filedata = False
541 have_filedata = False
542 Colors = self.Colors
542 Colors = self.Colors
543 list = []
543 list = []
544 try:
544 try:
545 stype = Colors.excName + etype.__name__ + Colors.Normal
545 stype = Colors.excName + etype.__name__ + Colors.Normal
546 except AttributeError:
546 except AttributeError:
547 stype = etype # String exceptions don't get special coloring
547 stype = etype # String exceptions don't get special coloring
548 if value is None:
548 if value is None:
549 list.append( str(stype) + '\n')
549 list.append( str(stype) + '\n')
550 else:
550 else:
551 if etype is SyntaxError:
551 if etype is SyntaxError:
552 try:
552 try:
553 msg, (filename, lineno, offset, line) = value
553 msg, (filename, lineno, offset, line) = value
554 except:
554 except:
555 have_filedata = False
555 have_filedata = False
556 else:
556 else:
557 have_filedata = True
557 have_filedata = True
558 #print 'filename is',filename # dbg
558 #print 'filename is',filename # dbg
559 if not filename: filename = "<string>"
559 if not filename: filename = "<string>"
560 list.append('%s File %s"%s"%s, line %s%d%s\n' % \
560 list.append('%s File %s"%s"%s, line %s%d%s\n' % \
561 (Colors.normalEm,
561 (Colors.normalEm,
562 Colors.filenameEm, filename, Colors.normalEm,
562 Colors.filenameEm, filename, Colors.normalEm,
563 Colors.linenoEm, lineno, Colors.Normal ))
563 Colors.linenoEm, lineno, Colors.Normal ))
564 if line is not None:
564 if line is not None:
565 i = 0
565 i = 0
566 while i < len(line) and line[i].isspace():
566 while i < len(line) and line[i].isspace():
567 i = i+1
567 i = i+1
568 list.append('%s %s%s\n' % (Colors.line,
568 list.append('%s %s%s\n' % (Colors.line,
569 line.strip(),
569 line.strip(),
570 Colors.Normal))
570 Colors.Normal))
571 if offset is not None:
571 if offset is not None:
572 s = ' '
572 s = ' '
573 for c in line[i:offset-1]:
573 for c in line[i:offset-1]:
574 if c.isspace():
574 if c.isspace():
575 s = s + c
575 s = s + c
576 else:
576 else:
577 s = s + ' '
577 s = s + ' '
578 list.append('%s%s^%s\n' % (Colors.caret, s,
578 list.append('%s%s^%s\n' % (Colors.caret, s,
579 Colors.Normal) )
579 Colors.Normal) )
580 value = msg
580 value = msg
581 s = self._some_str(value)
581 s = self._some_str(value)
582 if s:
582 if s:
583 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
583 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
584 Colors.Normal, s))
584 Colors.Normal, s))
585 else:
585 else:
586 list.append('%s\n' % str(stype))
586 list.append('%s\n' % str(stype))
587
587
588 # sync with user hooks
588 # sync with user hooks
589 if have_filedata:
589 if have_filedata:
590 ipinst = ipapi.get()
590 ipinst = ipapi.get()
591 if ipinst is not None:
591 if ipinst is not None:
592 ipinst.hooks.synchronize_with_editor(filename, lineno, 0)
592 ipinst.hooks.synchronize_with_editor(filename, lineno, 0)
593
593
594 return list
594 return list
595
595
596 def get_exception_only(self, etype, value):
596 def get_exception_only(self, etype, value):
597 """Only print the exception type and message, without a traceback.
597 """Only print the exception type and message, without a traceback.
598
598
599 Parameters
599 Parameters
600 ----------
600 ----------
601 etype : exception type
601 etype : exception type
602 value : exception value
602 value : exception value
603 """
603 """
604 return ListTB.structured_traceback(self, etype, value, [])
604 return ListTB.structured_traceback(self, etype, value, [])
605
605
606
606
607 def show_exception_only(self, etype, value):
607 def show_exception_only(self, etype, evalue):
608 """Only print the exception type and message, without a traceback.
608 """Only print the exception type and message, without a traceback.
609
609
610 Parameters
610 Parameters
611 ----------
611 ----------
612 etype : exception type
612 etype : exception type
613 value : exception value
613 value : exception value
614 """
614 """
615 # This method needs to use __call__ from *this* class, not the one from
615 # This method needs to use __call__ from *this* class, not the one from
616 # a subclass whose signature or behavior may be different
616 # a subclass whose signature or behavior may be different
617 ostream = self.ostream
617 ostream = self.ostream
618 ostream.flush()
618 ostream.flush()
619 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
619 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
620 ostream.flush()
620 ostream.flush()
621
621
622 def _some_str(self, value):
622 def _some_str(self, value):
623 # Lifted from traceback.py
623 # Lifted from traceback.py
624 try:
624 try:
625 return str(value)
625 return str(value)
626 except:
626 except:
627 return '<unprintable %s object>' % type(value).__name__
627 return '<unprintable %s object>' % type(value).__name__
628
628
629 #----------------------------------------------------------------------------
629 #----------------------------------------------------------------------------
630 class VerboseTB(TBTools):
630 class VerboseTB(TBTools):
631 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
631 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
632 of HTML. Requires inspect and pydoc. Crazy, man.
632 of HTML. Requires inspect and pydoc. Crazy, man.
633
633
634 Modified version which optionally strips the topmost entries from the
634 Modified version which optionally strips the topmost entries from the
635 traceback, to be used with alternate interpreters (because their own code
635 traceback, to be used with alternate interpreters (because their own code
636 would appear in the traceback)."""
636 would appear in the traceback)."""
637
637
638 def __init__(self,color_scheme = 'Linux', call_pdb=False, ostream=None,
638 def __init__(self,color_scheme = 'Linux', call_pdb=False, ostream=None,
639 tb_offset=0, long_header=False, include_vars=True):
639 tb_offset=0, long_header=False, include_vars=True):
640 """Specify traceback offset, headers and color scheme.
640 """Specify traceback offset, headers and color scheme.
641
641
642 Define how many frames to drop from the tracebacks. Calling it with
642 Define how many frames to drop from the tracebacks. Calling it with
643 tb_offset=1 allows use of this handler in interpreters which will have
643 tb_offset=1 allows use of this handler in interpreters which will have
644 their own code at the top of the traceback (VerboseTB will first
644 their own code at the top of the traceback (VerboseTB will first
645 remove that frame before printing the traceback info)."""
645 remove that frame before printing the traceback info)."""
646 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
646 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
647 ostream=ostream)
647 ostream=ostream)
648 self.tb_offset = tb_offset
648 self.tb_offset = tb_offset
649 self.long_header = long_header
649 self.long_header = long_header
650 self.include_vars = include_vars
650 self.include_vars = include_vars
651
651
652 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
652 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
653 context=5):
653 context=5):
654 """Return a nice text document describing the traceback."""
654 """Return a nice text document describing the traceback."""
655
655
656 tb_offset = self.tb_offset if tb_offset is None else tb_offset
656 tb_offset = self.tb_offset if tb_offset is None else tb_offset
657
657
658 # some locals
658 # some locals
659 try:
659 try:
660 etype = etype.__name__
660 etype = etype.__name__
661 except AttributeError:
661 except AttributeError:
662 pass
662 pass
663 Colors = self.Colors # just a shorthand + quicker name lookup
663 Colors = self.Colors # just a shorthand + quicker name lookup
664 ColorsNormal = Colors.Normal # used a lot
664 ColorsNormal = Colors.Normal # used a lot
665 col_scheme = self.color_scheme_table.active_scheme_name
665 col_scheme = self.color_scheme_table.active_scheme_name
666 indent = ' '*INDENT_SIZE
666 indent = ' '*INDENT_SIZE
667 em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
667 em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
668 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
668 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
669 exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal)
669 exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal)
670
670
671 # some internal-use functions
671 # some internal-use functions
672 def text_repr(value):
672 def text_repr(value):
673 """Hopefully pretty robust repr equivalent."""
673 """Hopefully pretty robust repr equivalent."""
674 # this is pretty horrible but should always return *something*
674 # this is pretty horrible but should always return *something*
675 try:
675 try:
676 return pydoc.text.repr(value)
676 return pydoc.text.repr(value)
677 except KeyboardInterrupt:
677 except KeyboardInterrupt:
678 raise
678 raise
679 except:
679 except:
680 try:
680 try:
681 return repr(value)
681 return repr(value)
682 except KeyboardInterrupt:
682 except KeyboardInterrupt:
683 raise
683 raise
684 except:
684 except:
685 try:
685 try:
686 # all still in an except block so we catch
686 # all still in an except block so we catch
687 # getattr raising
687 # getattr raising
688 name = getattr(value, '__name__', None)
688 name = getattr(value, '__name__', None)
689 if name:
689 if name:
690 # ick, recursion
690 # ick, recursion
691 return text_repr(name)
691 return text_repr(name)
692 klass = getattr(value, '__class__', None)
692 klass = getattr(value, '__class__', None)
693 if klass:
693 if klass:
694 return '%s instance' % text_repr(klass)
694 return '%s instance' % text_repr(klass)
695 except KeyboardInterrupt:
695 except KeyboardInterrupt:
696 raise
696 raise
697 except:
697 except:
698 return 'UNRECOVERABLE REPR FAILURE'
698 return 'UNRECOVERABLE REPR FAILURE'
699 def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
699 def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
700 def nullrepr(value, repr=text_repr): return ''
700 def nullrepr(value, repr=text_repr): return ''
701
701
702 # meat of the code begins
702 # meat of the code begins
703 try:
703 try:
704 etype = etype.__name__
704 etype = etype.__name__
705 except AttributeError:
705 except AttributeError:
706 pass
706 pass
707
707
708 if self.long_header:
708 if self.long_header:
709 # Header with the exception type, python version, and date
709 # Header with the exception type, python version, and date
710 pyver = 'Python ' + string.split(sys.version)[0] + ': ' + sys.executable
710 pyver = 'Python ' + string.split(sys.version)[0] + ': ' + sys.executable
711 date = time.ctime(time.time())
711 date = time.ctime(time.time())
712
712
713 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
713 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
714 exc, ' '*(75-len(str(etype))-len(pyver)),
714 exc, ' '*(75-len(str(etype))-len(pyver)),
715 pyver, string.rjust(date, 75) )
715 pyver, string.rjust(date, 75) )
716 head += "\nA problem occured executing Python code. Here is the sequence of function"\
716 head += "\nA problem occured executing Python code. Here is the sequence of function"\
717 "\ncalls leading up to the error, with the most recent (innermost) call last."
717 "\ncalls leading up to the error, with the most recent (innermost) call last."
718 else:
718 else:
719 # Simplified header
719 # Simplified header
720 head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
720 head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
721 string.rjust('Traceback (most recent call last)',
721 string.rjust('Traceback (most recent call last)',
722 75 - len(str(etype)) ) )
722 75 - len(str(etype)) ) )
723 frames = []
723 frames = []
724 # Flush cache before calling inspect. This helps alleviate some of the
724 # Flush cache before calling inspect. This helps alleviate some of the
725 # problems with python 2.3's inspect.py.
725 # problems with python 2.3's inspect.py.
726 linecache.checkcache()
726 linecache.checkcache()
727 # Drop topmost frames if requested
727 # Drop topmost frames if requested
728 try:
728 try:
729 # Try the default getinnerframes and Alex's: Alex's fixes some
729 # Try the default getinnerframes and Alex's: Alex's fixes some
730 # problems, but it generates empty tracebacks for console errors
730 # problems, but it generates empty tracebacks for console errors
731 # (5 blanks lines) where none should be returned.
731 # (5 blanks lines) where none should be returned.
732 #records = inspect.getinnerframes(etb, context)[tb_offset:]
732 #records = inspect.getinnerframes(etb, context)[tb_offset:]
733 #print 'python records:', records # dbg
733 #print 'python records:', records # dbg
734 records = _fixed_getinnerframes(etb, context, tb_offset)
734 records = _fixed_getinnerframes(etb, context, tb_offset)
735 #print 'alex records:', records # dbg
735 #print 'alex records:', records # dbg
736 except:
736 except:
737
737
738 # FIXME: I've been getting many crash reports from python 2.3
738 # FIXME: I've been getting many crash reports from python 2.3
739 # users, traceable to inspect.py. If I can find a small test-case
739 # users, traceable to inspect.py. If I can find a small test-case
740 # to reproduce this, I should either write a better workaround or
740 # to reproduce this, I should either write a better workaround or
741 # file a bug report against inspect (if that's the real problem).
741 # file a bug report against inspect (if that's the real problem).
742 # So far, I haven't been able to find an isolated example to
742 # So far, I haven't been able to find an isolated example to
743 # reproduce the problem.
743 # reproduce the problem.
744 inspect_error()
744 inspect_error()
745 traceback.print_exc(file=self.ostream)
745 traceback.print_exc(file=self.ostream)
746 info('\nUnfortunately, your original traceback can not be constructed.\n')
746 info('\nUnfortunately, your original traceback can not be constructed.\n')
747 return ''
747 return ''
748
748
749 # build some color string templates outside these nested loops
749 # build some color string templates outside these nested loops
750 tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
750 tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
751 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
751 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
752 ColorsNormal)
752 ColorsNormal)
753 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
753 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
754 (Colors.vName, Colors.valEm, ColorsNormal)
754 (Colors.vName, Colors.valEm, ColorsNormal)
755 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
755 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
756 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
756 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
757 Colors.vName, ColorsNormal)
757 Colors.vName, ColorsNormal)
758 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
758 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
759 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
759 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
760 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
760 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
761 ColorsNormal)
761 ColorsNormal)
762
762
763 # now, loop over all records printing context and info
763 # now, loop over all records printing context and info
764 abspath = os.path.abspath
764 abspath = os.path.abspath
765 for frame, file, lnum, func, lines, index in records:
765 for frame, file, lnum, func, lines, index in records:
766 #print '*** record:',file,lnum,func,lines,index # dbg
766 #print '*** record:',file,lnum,func,lines,index # dbg
767 try:
767 try:
768 file = file and abspath(file) or '?'
768 file = file and abspath(file) or '?'
769 except OSError:
769 except OSError:
770 # if file is '<console>' or something not in the filesystem,
770 # if file is '<console>' or something not in the filesystem,
771 # the abspath call will throw an OSError. Just ignore it and
771 # the abspath call will throw an OSError. Just ignore it and
772 # keep the original file string.
772 # keep the original file string.
773 pass
773 pass
774 link = tpl_link % file
774 link = tpl_link % file
775 try:
775 try:
776 args, varargs, varkw, locals = inspect.getargvalues(frame)
776 args, varargs, varkw, locals = inspect.getargvalues(frame)
777 except:
777 except:
778 # This can happen due to a bug in python2.3. We should be
778 # This can happen due to a bug in python2.3. We should be
779 # able to remove this try/except when 2.4 becomes a
779 # able to remove this try/except when 2.4 becomes a
780 # requirement. Bug details at http://python.org/sf/1005466
780 # requirement. Bug details at http://python.org/sf/1005466
781 inspect_error()
781 inspect_error()
782 traceback.print_exc(file=self.ostream)
782 traceback.print_exc(file=self.ostream)
783 info("\nIPython's exception reporting continues...\n")
783 info("\nIPython's exception reporting continues...\n")
784
784
785 if func == '?':
785 if func == '?':
786 call = ''
786 call = ''
787 else:
787 else:
788 # Decide whether to include variable details or not
788 # Decide whether to include variable details or not
789 var_repr = self.include_vars and eqrepr or nullrepr
789 var_repr = self.include_vars and eqrepr or nullrepr
790 try:
790 try:
791 call = tpl_call % (func,inspect.formatargvalues(args,
791 call = tpl_call % (func,inspect.formatargvalues(args,
792 varargs, varkw,
792 varargs, varkw,
793 locals,formatvalue=var_repr))
793 locals,formatvalue=var_repr))
794 except KeyError:
794 except KeyError:
795 # Very odd crash from inspect.formatargvalues(). The
795 # Very odd crash from inspect.formatargvalues(). The
796 # scenario under which it appeared was a call to
796 # scenario under which it appeared was a call to
797 # view(array,scale) in NumTut.view.view(), where scale had
797 # view(array,scale) in NumTut.view.view(), where scale had
798 # been defined as a scalar (it should be a tuple). Somehow
798 # been defined as a scalar (it should be a tuple). Somehow
799 # inspect messes up resolving the argument list of view()
799 # inspect messes up resolving the argument list of view()
800 # and barfs out. At some point I should dig into this one
800 # and barfs out. At some point I should dig into this one
801 # and file a bug report about it.
801 # and file a bug report about it.
802 inspect_error()
802 inspect_error()
803 traceback.print_exc(file=self.ostream)
803 traceback.print_exc(file=self.ostream)
804 info("\nIPython's exception reporting continues...\n")
804 info("\nIPython's exception reporting continues...\n")
805 call = tpl_call_fail % func
805 call = tpl_call_fail % func
806
806
807 # Initialize a list of names on the current line, which the
807 # Initialize a list of names on the current line, which the
808 # tokenizer below will populate.
808 # tokenizer below will populate.
809 names = []
809 names = []
810
810
811 def tokeneater(token_type, token, start, end, line):
811 def tokeneater(token_type, token, start, end, line):
812 """Stateful tokeneater which builds dotted names.
812 """Stateful tokeneater which builds dotted names.
813
813
814 The list of names it appends to (from the enclosing scope) can
814 The list of names it appends to (from the enclosing scope) can
815 contain repeated composite names. This is unavoidable, since
815 contain repeated composite names. This is unavoidable, since
816 there is no way to disambguate partial dotted structures until
816 there is no way to disambguate partial dotted structures until
817 the full list is known. The caller is responsible for pruning
817 the full list is known. The caller is responsible for pruning
818 the final list of duplicates before using it."""
818 the final list of duplicates before using it."""
819
819
820 # build composite names
820 # build composite names
821 if token == '.':
821 if token == '.':
822 try:
822 try:
823 names[-1] += '.'
823 names[-1] += '.'
824 # store state so the next token is added for x.y.z names
824 # store state so the next token is added for x.y.z names
825 tokeneater.name_cont = True
825 tokeneater.name_cont = True
826 return
826 return
827 except IndexError:
827 except IndexError:
828 pass
828 pass
829 if token_type == tokenize.NAME and token not in keyword.kwlist:
829 if token_type == tokenize.NAME and token not in keyword.kwlist:
830 if tokeneater.name_cont:
830 if tokeneater.name_cont:
831 # Dotted names
831 # Dotted names
832 names[-1] += token
832 names[-1] += token
833 tokeneater.name_cont = False
833 tokeneater.name_cont = False
834 else:
834 else:
835 # Regular new names. We append everything, the caller
835 # Regular new names. We append everything, the caller
836 # will be responsible for pruning the list later. It's
836 # will be responsible for pruning the list later. It's
837 # very tricky to try to prune as we go, b/c composite
837 # very tricky to try to prune as we go, b/c composite
838 # names can fool us. The pruning at the end is easy
838 # names can fool us. The pruning at the end is easy
839 # to do (or the caller can print a list with repeated
839 # to do (or the caller can print a list with repeated
840 # names if so desired.
840 # names if so desired.
841 names.append(token)
841 names.append(token)
842 elif token_type == tokenize.NEWLINE:
842 elif token_type == tokenize.NEWLINE:
843 raise IndexError
843 raise IndexError
844 # we need to store a bit of state in the tokenizer to build
844 # we need to store a bit of state in the tokenizer to build
845 # dotted names
845 # dotted names
846 tokeneater.name_cont = False
846 tokeneater.name_cont = False
847
847
848 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
848 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
849 line = getline(file, lnum[0])
849 line = getline(file, lnum[0])
850 lnum[0] += 1
850 lnum[0] += 1
851 return line
851 return line
852
852
853 # Build the list of names on this line of code where the exception
853 # Build the list of names on this line of code where the exception
854 # occurred.
854 # occurred.
855 try:
855 try:
856 # This builds the names list in-place by capturing it from the
856 # This builds the names list in-place by capturing it from the
857 # enclosing scope.
857 # enclosing scope.
858 tokenize.tokenize(linereader, tokeneater)
858 tokenize.tokenize(linereader, tokeneater)
859 except IndexError:
859 except IndexError:
860 # signals exit of tokenizer
860 # signals exit of tokenizer
861 pass
861 pass
862 except tokenize.TokenError,msg:
862 except tokenize.TokenError,msg:
863 _m = ("An unexpected error occurred while tokenizing input\n"
863 _m = ("An unexpected error occurred while tokenizing input\n"
864 "The following traceback may be corrupted or invalid\n"
864 "The following traceback may be corrupted or invalid\n"
865 "The error message is: %s\n" % msg)
865 "The error message is: %s\n" % msg)
866 error(_m)
866 error(_m)
867
867
868 # prune names list of duplicates, but keep the right order
868 # prune names list of duplicates, but keep the right order
869 unique_names = uniq_stable(names)
869 unique_names = uniq_stable(names)
870
870
871 # Start loop over vars
871 # Start loop over vars
872 lvals = []
872 lvals = []
873 if self.include_vars:
873 if self.include_vars:
874 for name_full in unique_names:
874 for name_full in unique_names:
875 name_base = name_full.split('.',1)[0]
875 name_base = name_full.split('.',1)[0]
876 if name_base in frame.f_code.co_varnames:
876 if name_base in frame.f_code.co_varnames:
877 if locals.has_key(name_base):
877 if locals.has_key(name_base):
878 try:
878 try:
879 value = repr(eval(name_full,locals))
879 value = repr(eval(name_full,locals))
880 except:
880 except:
881 value = undefined
881 value = undefined
882 else:
882 else:
883 value = undefined
883 value = undefined
884 name = tpl_local_var % name_full
884 name = tpl_local_var % name_full
885 else:
885 else:
886 if frame.f_globals.has_key(name_base):
886 if frame.f_globals.has_key(name_base):
887 try:
887 try:
888 value = repr(eval(name_full,frame.f_globals))
888 value = repr(eval(name_full,frame.f_globals))
889 except:
889 except:
890 value = undefined
890 value = undefined
891 else:
891 else:
892 value = undefined
892 value = undefined
893 name = tpl_global_var % name_full
893 name = tpl_global_var % name_full
894 lvals.append(tpl_name_val % (name,value))
894 lvals.append(tpl_name_val % (name,value))
895 if lvals:
895 if lvals:
896 lvals = '%s%s' % (indent,em_normal.join(lvals))
896 lvals = '%s%s' % (indent,em_normal.join(lvals))
897 else:
897 else:
898 lvals = ''
898 lvals = ''
899
899
900 level = '%s %s\n' % (link,call)
900 level = '%s %s\n' % (link,call)
901
901
902 if index is None:
902 if index is None:
903 frames.append(level)
903 frames.append(level)
904 else:
904 else:
905 frames.append('%s%s' % (level,''.join(
905 frames.append('%s%s' % (level,''.join(
906 _format_traceback_lines(lnum,index,lines,Colors,lvals,
906 _format_traceback_lines(lnum,index,lines,Colors,lvals,
907 col_scheme))))
907 col_scheme))))
908
908
909 # Get (safely) a string form of the exception info
909 # Get (safely) a string form of the exception info
910 try:
910 try:
911 etype_str,evalue_str = map(str,(etype,evalue))
911 etype_str,evalue_str = map(str,(etype,evalue))
912 except:
912 except:
913 # User exception is improperly defined.
913 # User exception is improperly defined.
914 etype,evalue = str,sys.exc_info()[:2]
914 etype,evalue = str,sys.exc_info()[:2]
915 etype_str,evalue_str = map(str,(etype,evalue))
915 etype_str,evalue_str = map(str,(etype,evalue))
916 # ... and format it
916 # ... and format it
917 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
917 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
918 ColorsNormal, evalue_str)]
918 ColorsNormal, evalue_str)]
919 if type(evalue) is types.InstanceType:
919 if type(evalue) is types.InstanceType:
920 try:
920 try:
921 names = [w for w in dir(evalue) if isinstance(w, basestring)]
921 names = [w for w in dir(evalue) if isinstance(w, basestring)]
922 except:
922 except:
923 # Every now and then, an object with funny inernals blows up
923 # Every now and then, an object with funny inernals blows up
924 # when dir() is called on it. We do the best we can to report
924 # when dir() is called on it. We do the best we can to report
925 # the problem and continue
925 # the problem and continue
926 _m = '%sException reporting error (object with broken dir())%s:'
926 _m = '%sException reporting error (object with broken dir())%s:'
927 exception.append(_m % (Colors.excName,ColorsNormal))
927 exception.append(_m % (Colors.excName,ColorsNormal))
928 etype_str,evalue_str = map(str,sys.exc_info()[:2])
928 etype_str,evalue_str = map(str,sys.exc_info()[:2])
929 exception.append('%s%s%s: %s' % (Colors.excName,etype_str,
929 exception.append('%s%s%s: %s' % (Colors.excName,etype_str,
930 ColorsNormal, evalue_str))
930 ColorsNormal, evalue_str))
931 names = []
931 names = []
932 for name in names:
932 for name in names:
933 value = text_repr(getattr(evalue, name))
933 value = text_repr(getattr(evalue, name))
934 exception.append('\n%s%s = %s' % (indent, name, value))
934 exception.append('\n%s%s = %s' % (indent, name, value))
935
935
936 # vds: >>
936 # vds: >>
937 if records:
937 if records:
938 filepath, lnum = records[-1][1:3]
938 filepath, lnum = records[-1][1:3]
939 #print "file:", str(file), "linenb", str(lnum) # dbg
939 #print "file:", str(file), "linenb", str(lnum) # dbg
940 filepath = os.path.abspath(filepath)
940 filepath = os.path.abspath(filepath)
941 ipinst = ipapi.get()
941 ipinst = ipapi.get()
942 if ipinst is not None:
942 if ipinst is not None:
943 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
943 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
944 # vds: <<
944 # vds: <<
945
945
946 # return all our info assembled as a single string
946 # return all our info assembled as a single string
947 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
947 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
948 return [head] + frames + [''.join(exception[0])]
948 return [head] + frames + [''.join(exception[0])]
949
949
950 def debugger(self,force=False):
950 def debugger(self,force=False):
951 """Call up the pdb debugger if desired, always clean up the tb
951 """Call up the pdb debugger if desired, always clean up the tb
952 reference.
952 reference.
953
953
954 Keywords:
954 Keywords:
955
955
956 - force(False): by default, this routine checks the instance call_pdb
956 - force(False): by default, this routine checks the instance call_pdb
957 flag and does not actually invoke the debugger if the flag is false.
957 flag and does not actually invoke the debugger if the flag is false.
958 The 'force' option forces the debugger to activate even if the flag
958 The 'force' option forces the debugger to activate even if the flag
959 is false.
959 is false.
960
960
961 If the call_pdb flag is set, the pdb interactive debugger is
961 If the call_pdb flag is set, the pdb interactive debugger is
962 invoked. In all cases, the self.tb reference to the current traceback
962 invoked. In all cases, the self.tb reference to the current traceback
963 is deleted to prevent lingering references which hamper memory
963 is deleted to prevent lingering references which hamper memory
964 management.
964 management.
965
965
966 Note that each call to pdb() does an 'import readline', so if your app
966 Note that each call to pdb() does an 'import readline', so if your app
967 requires a special setup for the readline completers, you'll have to
967 requires a special setup for the readline completers, you'll have to
968 fix that by hand after invoking the exception handler."""
968 fix that by hand after invoking the exception handler."""
969
969
970 if force or self.call_pdb:
970 if force or self.call_pdb:
971 if self.pdb is None:
971 if self.pdb is None:
972 self.pdb = debugger.Pdb(
972 self.pdb = debugger.Pdb(
973 self.color_scheme_table.active_scheme_name)
973 self.color_scheme_table.active_scheme_name)
974 # the system displayhook may have changed, restore the original
974 # the system displayhook may have changed, restore the original
975 # for pdb
975 # for pdb
976 display_trap = DisplayTrap(hook=sys.__displayhook__)
976 display_trap = DisplayTrap(hook=sys.__displayhook__)
977 with display_trap:
977 with display_trap:
978 self.pdb.reset()
978 self.pdb.reset()
979 # Find the right frame so we don't pop up inside ipython itself
979 # Find the right frame so we don't pop up inside ipython itself
980 if hasattr(self,'tb') and self.tb is not None:
980 if hasattr(self,'tb') and self.tb is not None:
981 etb = self.tb
981 etb = self.tb
982 else:
982 else:
983 etb = self.tb = sys.last_traceback
983 etb = self.tb = sys.last_traceback
984 while self.tb is not None and self.tb.tb_next is not None:
984 while self.tb is not None and self.tb.tb_next is not None:
985 self.tb = self.tb.tb_next
985 self.tb = self.tb.tb_next
986 if etb and etb.tb_next:
986 if etb and etb.tb_next:
987 etb = etb.tb_next
987 etb = etb.tb_next
988 self.pdb.botframe = etb.tb_frame
988 self.pdb.botframe = etb.tb_frame
989 self.pdb.interaction(self.tb.tb_frame, self.tb)
989 self.pdb.interaction(self.tb.tb_frame, self.tb)
990
990
991 if hasattr(self,'tb'):
991 if hasattr(self,'tb'):
992 del self.tb
992 del self.tb
993
993
994 def handler(self, info=None):
994 def handler(self, info=None):
995 (etype, evalue, etb) = info or sys.exc_info()
995 (etype, evalue, etb) = info or sys.exc_info()
996 self.tb = etb
996 self.tb = etb
997 ostream = self.ostream
997 ostream = self.ostream
998 ostream.flush()
998 ostream.flush()
999 ostream.write(self.text(etype, evalue, etb))
999 ostream.write(self.text(etype, evalue, etb))
1000 ostream.write('\n')
1000 ostream.write('\n')
1001 ostream.flush()
1001 ostream.flush()
1002
1002
1003 # Changed so an instance can just be called as VerboseTB_inst() and print
1003 # Changed so an instance can just be called as VerboseTB_inst() and print
1004 # out the right info on its own.
1004 # out the right info on its own.
1005 def __call__(self, etype=None, evalue=None, etb=None):
1005 def __call__(self, etype=None, evalue=None, etb=None):
1006 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1006 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1007 if etb is None:
1007 if etb is None:
1008 self.handler()
1008 self.handler()
1009 else:
1009 else:
1010 self.handler((etype, evalue, etb))
1010 self.handler((etype, evalue, etb))
1011 try:
1011 try:
1012 self.debugger()
1012 self.debugger()
1013 except KeyboardInterrupt:
1013 except KeyboardInterrupt:
1014 print "\nKeyboardInterrupt"
1014 print "\nKeyboardInterrupt"
1015
1015
1016 #----------------------------------------------------------------------------
1016 #----------------------------------------------------------------------------
1017 class FormattedTB(VerboseTB, ListTB):
1017 class FormattedTB(VerboseTB, ListTB):
1018 """Subclass ListTB but allow calling with a traceback.
1018 """Subclass ListTB but allow calling with a traceback.
1019
1019
1020 It can thus be used as a sys.excepthook for Python > 2.1.
1020 It can thus be used as a sys.excepthook for Python > 2.1.
1021
1021
1022 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1022 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1023
1023
1024 Allows a tb_offset to be specified. This is useful for situations where
1024 Allows a tb_offset to be specified. This is useful for situations where
1025 one needs to remove a number of topmost frames from the traceback (such as
1025 one needs to remove a number of topmost frames from the traceback (such as
1026 occurs with python programs that themselves execute other python code,
1026 occurs with python programs that themselves execute other python code,
1027 like Python shells). """
1027 like Python shells). """
1028
1028
1029 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1029 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1030 ostream=None,
1030 ostream=None,
1031 tb_offset=0, long_header=False, include_vars=False):
1031 tb_offset=0, long_header=False, include_vars=False):
1032
1032
1033 # NEVER change the order of this list. Put new modes at the end:
1033 # NEVER change the order of this list. Put new modes at the end:
1034 self.valid_modes = ['Plain','Context','Verbose']
1034 self.valid_modes = ['Plain','Context','Verbose']
1035 self.verbose_modes = self.valid_modes[1:3]
1035 self.verbose_modes = self.valid_modes[1:3]
1036
1036
1037 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1037 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1038 ostream=ostream, tb_offset=tb_offset,
1038 ostream=ostream, tb_offset=tb_offset,
1039 long_header=long_header, include_vars=include_vars)
1039 long_header=long_header, include_vars=include_vars)
1040
1040
1041 # Different types of tracebacks are joined with different separators to
1041 # Different types of tracebacks are joined with different separators to
1042 # form a single string. They are taken from this dict
1042 # form a single string. They are taken from this dict
1043 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1043 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1044 # set_mode also sets the tb_join_char attribute
1044 # set_mode also sets the tb_join_char attribute
1045 self.set_mode(mode)
1045 self.set_mode(mode)
1046
1046
1047 def _extract_tb(self,tb):
1047 def _extract_tb(self,tb):
1048 if tb:
1048 if tb:
1049 return traceback.extract_tb(tb)
1049 return traceback.extract_tb(tb)
1050 else:
1050 else:
1051 return None
1051 return None
1052
1052
1053 def structured_traceback(self, etype, value, tb, tb_offset=None, context=5):
1053 def structured_traceback(self, etype, value, tb, tb_offset=None, context=5):
1054 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1054 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1055 mode = self.mode
1055 mode = self.mode
1056 if mode in self.verbose_modes:
1056 if mode in self.verbose_modes:
1057 # Verbose modes need a full traceback
1057 # Verbose modes need a full traceback
1058 return VerboseTB.structured_traceback(
1058 return VerboseTB.structured_traceback(
1059 self, etype, value, tb, tb_offset, context
1059 self, etype, value, tb, tb_offset, context
1060 )
1060 )
1061 else:
1061 else:
1062 # We must check the source cache because otherwise we can print
1062 # We must check the source cache because otherwise we can print
1063 # out-of-date source code.
1063 # out-of-date source code.
1064 linecache.checkcache()
1064 linecache.checkcache()
1065 # Now we can extract and format the exception
1065 # Now we can extract and format the exception
1066 elist = self._extract_tb(tb)
1066 elist = self._extract_tb(tb)
1067 return ListTB.structured_traceback(
1067 return ListTB.structured_traceback(
1068 self, etype, value, elist, tb_offset, context
1068 self, etype, value, elist, tb_offset, context
1069 )
1069 )
1070
1070
1071 def stb2text(self, stb):
1071 def stb2text(self, stb):
1072 """Convert a structured traceback (a list) to a string."""
1072 """Convert a structured traceback (a list) to a string."""
1073 return self.tb_join_char.join(stb)
1073 return self.tb_join_char.join(stb)
1074
1074
1075
1075
1076 def set_mode(self,mode=None):
1076 def set_mode(self,mode=None):
1077 """Switch to the desired mode.
1077 """Switch to the desired mode.
1078
1078
1079 If mode is not specified, cycles through the available modes."""
1079 If mode is not specified, cycles through the available modes."""
1080
1080
1081 if not mode:
1081 if not mode:
1082 new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
1082 new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
1083 len(self.valid_modes)
1083 len(self.valid_modes)
1084 self.mode = self.valid_modes[new_idx]
1084 self.mode = self.valid_modes[new_idx]
1085 elif mode not in self.valid_modes:
1085 elif mode not in self.valid_modes:
1086 raise ValueError, 'Unrecognized mode in FormattedTB: <'+mode+'>\n'\
1086 raise ValueError, 'Unrecognized mode in FormattedTB: <'+mode+'>\n'\
1087 'Valid modes: '+str(self.valid_modes)
1087 'Valid modes: '+str(self.valid_modes)
1088 else:
1088 else:
1089 self.mode = mode
1089 self.mode = mode
1090 # include variable details only in 'Verbose' mode
1090 # include variable details only in 'Verbose' mode
1091 self.include_vars = (self.mode == self.valid_modes[2])
1091 self.include_vars = (self.mode == self.valid_modes[2])
1092 # Set the join character for generating text tracebacks
1092 # Set the join character for generating text tracebacks
1093 self.tb_join_char = self._join_chars[mode]
1093 self.tb_join_char = self._join_chars[mode]
1094
1094
1095 # some convenient shorcuts
1095 # some convenient shorcuts
1096 def plain(self):
1096 def plain(self):
1097 self.set_mode(self.valid_modes[0])
1097 self.set_mode(self.valid_modes[0])
1098
1098
1099 def context(self):
1099 def context(self):
1100 self.set_mode(self.valid_modes[1])
1100 self.set_mode(self.valid_modes[1])
1101
1101
1102 def verbose(self):
1102 def verbose(self):
1103 self.set_mode(self.valid_modes[2])
1103 self.set_mode(self.valid_modes[2])
1104
1104
1105 #----------------------------------------------------------------------------
1105 #----------------------------------------------------------------------------
1106 class AutoFormattedTB(FormattedTB):
1106 class AutoFormattedTB(FormattedTB):
1107 """A traceback printer which can be called on the fly.
1107 """A traceback printer which can be called on the fly.
1108
1108
1109 It will find out about exceptions by itself.
1109 It will find out about exceptions by itself.
1110
1110
1111 A brief example:
1111 A brief example:
1112
1112
1113 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1113 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1114 try:
1114 try:
1115 ...
1115 ...
1116 except:
1116 except:
1117 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1117 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1118 """
1118 """
1119
1119
1120 def __call__(self,etype=None,evalue=None,etb=None,
1120 def __call__(self,etype=None,evalue=None,etb=None,
1121 out=None,tb_offset=None):
1121 out=None,tb_offset=None):
1122 """Print out a formatted exception traceback.
1122 """Print out a formatted exception traceback.
1123
1123
1124 Optional arguments:
1124 Optional arguments:
1125 - out: an open file-like object to direct output to.
1125 - out: an open file-like object to direct output to.
1126
1126
1127 - tb_offset: the number of frames to skip over in the stack, on a
1127 - tb_offset: the number of frames to skip over in the stack, on a
1128 per-call basis (this overrides temporarily the instance's tb_offset
1128 per-call basis (this overrides temporarily the instance's tb_offset
1129 given at initialization time. """
1129 given at initialization time. """
1130
1130
1131
1131
1132 if out is None:
1132 if out is None:
1133 out = self.ostream
1133 out = self.ostream
1134 out.flush()
1134 out.flush()
1135 out.write(self.text(etype, evalue, etb, tb_offset))
1135 out.write(self.text(etype, evalue, etb, tb_offset))
1136 out.write('\n')
1136 out.write('\n')
1137 out.flush()
1137 out.flush()
1138 # FIXME: we should remove the auto pdb behavior from here and leave
1138 # FIXME: we should remove the auto pdb behavior from here and leave
1139 # that to the clients.
1139 # that to the clients.
1140 try:
1140 try:
1141 self.debugger()
1141 self.debugger()
1142 except KeyboardInterrupt:
1142 except KeyboardInterrupt:
1143 print "\nKeyboardInterrupt"
1143 print "\nKeyboardInterrupt"
1144
1144
1145 def structured_traceback(self, etype=None, value=None, tb=None,
1145 def structured_traceback(self, etype=None, value=None, tb=None,
1146 tb_offset=None, context=5):
1146 tb_offset=None, context=5):
1147 if etype is None:
1147 if etype is None:
1148 etype,value,tb = sys.exc_info()
1148 etype,value,tb = sys.exc_info()
1149 self.tb = tb
1149 self.tb = tb
1150 return FormattedTB.structured_traceback(
1150 return FormattedTB.structured_traceback(
1151 self, etype, value, tb, tb_offset, context)
1151 self, etype, value, tb, tb_offset, context)
1152
1152
1153 #---------------------------------------------------------------------------
1153 #---------------------------------------------------------------------------
1154
1154
1155 # A simple class to preserve Nathan's original functionality.
1155 # A simple class to preserve Nathan's original functionality.
1156 class ColorTB(FormattedTB):
1156 class ColorTB(FormattedTB):
1157 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1157 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1158 def __init__(self,color_scheme='Linux',call_pdb=0):
1158 def __init__(self,color_scheme='Linux',call_pdb=0):
1159 FormattedTB.__init__(self,color_scheme=color_scheme,
1159 FormattedTB.__init__(self,color_scheme=color_scheme,
1160 call_pdb=call_pdb)
1160 call_pdb=call_pdb)
1161
1161
1162
1162
1163 class SyntaxTB(ListTB):
1163 class SyntaxTB(ListTB):
1164 """Extension which holds some state: the last exception value"""
1164 """Extension which holds some state: the last exception value"""
1165
1165
1166 def __init__(self,color_scheme = 'NoColor'):
1166 def __init__(self,color_scheme = 'NoColor'):
1167 ListTB.__init__(self,color_scheme)
1167 ListTB.__init__(self,color_scheme)
1168 self.last_syntax_error = None
1168 self.last_syntax_error = None
1169
1169
1170 def __call__(self, etype, value, elist):
1170 def __call__(self, etype, value, elist):
1171 self.last_syntax_error = value
1171 self.last_syntax_error = value
1172 ListTB.__call__(self,etype,value,elist)
1172 ListTB.__call__(self,etype,value,elist)
1173
1173
1174 def clear_err_state(self):
1174 def clear_err_state(self):
1175 """Return the current error state and clear it"""
1175 """Return the current error state and clear it"""
1176 e = self.last_syntax_error
1176 e = self.last_syntax_error
1177 self.last_syntax_error = None
1177 self.last_syntax_error = None
1178 return e
1178 return e
1179
1179
1180 def stb2text(self, stb):
1180 def stb2text(self, stb):
1181 """Convert a structured traceback (a list) to a string."""
1181 """Convert a structured traceback (a list) to a string."""
1182 return ''.join(stb)
1182 return ''.join(stb)
1183
1183
1184
1184
1185 #----------------------------------------------------------------------------
1185 #----------------------------------------------------------------------------
1186 # module testing (minimal)
1186 # module testing (minimal)
1187 if __name__ == "__main__":
1187 if __name__ == "__main__":
1188 def spam(c, (d, e)):
1188 def spam(c, (d, e)):
1189 x = c + d
1189 x = c + d
1190 y = c * d
1190 y = c * d
1191 foo(x, y)
1191 foo(x, y)
1192
1192
1193 def foo(a, b, bar=1):
1193 def foo(a, b, bar=1):
1194 eggs(a, b + bar)
1194 eggs(a, b + bar)
1195
1195
1196 def eggs(f, g, z=globals()):
1196 def eggs(f, g, z=globals()):
1197 h = f + g
1197 h = f + g
1198 i = f - g
1198 i = f - g
1199 return h / i
1199 return h / i
1200
1200
1201 print ''
1201 print ''
1202 print '*** Before ***'
1202 print '*** Before ***'
1203 try:
1203 try:
1204 print spam(1, (2, 3))
1204 print spam(1, (2, 3))
1205 except:
1205 except:
1206 traceback.print_exc()
1206 traceback.print_exc()
1207 print ''
1207 print ''
1208
1208
1209 handler = ColorTB()
1209 handler = ColorTB()
1210 print '*** ColorTB ***'
1210 print '*** ColorTB ***'
1211 try:
1211 try:
1212 print spam(1, (2, 3))
1212 print spam(1, (2, 3))
1213 except:
1213 except:
1214 apply(handler, sys.exc_info() )
1214 apply(handler, sys.exc_info() )
1215 print ''
1215 print ''
1216
1216
1217 handler = VerboseTB()
1217 handler = VerboseTB()
1218 print '*** VerboseTB ***'
1218 print '*** VerboseTB ***'
1219 try:
1219 try:
1220 print spam(1, (2, 3))
1220 print spam(1, (2, 3))
1221 except:
1221 except:
1222 apply(handler, sys.exc_info() )
1222 apply(handler, sys.exc_info() )
1223 print ''
1223 print ''
1224
1224
@@ -1,419 +1,418 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 import zmq
9
8
10 # Local imports
9 # Local imports
11 from IPython.core.inputsplitter import InputSplitter
10 from IPython.core.inputsplitter import InputSplitter
12 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
11 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
13 from call_tip_widget import CallTipWidget
12 from call_tip_widget import CallTipWidget
14 from completion_lexer import CompletionLexer
13 from completion_lexer import CompletionLexer
15 from console_widget import HistoryConsoleWidget
14 from console_widget import HistoryConsoleWidget
16 from pygments_highlighter import PygmentsHighlighter
15 from pygments_highlighter import PygmentsHighlighter
17
16
18
17
19 class FrontendHighlighter(PygmentsHighlighter):
18 class FrontendHighlighter(PygmentsHighlighter):
20 """ A PygmentsHighlighter that can be turned on and off and that ignores
19 """ A PygmentsHighlighter that can be turned on and off and that ignores
21 prompts.
20 prompts.
22 """
21 """
23
22
24 def __init__(self, frontend):
23 def __init__(self, frontend):
25 super(FrontendHighlighter, self).__init__(frontend._control.document())
24 super(FrontendHighlighter, self).__init__(frontend._control.document())
26 self._current_offset = 0
25 self._current_offset = 0
27 self._frontend = frontend
26 self._frontend = frontend
28 self.highlighting_on = False
27 self.highlighting_on = False
29
28
30 def highlightBlock(self, qstring):
29 def highlightBlock(self, qstring):
31 """ Highlight a block of text. Reimplemented to highlight selectively.
30 """ Highlight a block of text. Reimplemented to highlight selectively.
32 """
31 """
33 if not self.highlighting_on:
32 if not self.highlighting_on:
34 return
33 return
35
34
36 # The input to this function is unicode string that may contain
35 # The input to this function is unicode string that may contain
37 # paragraph break characters, non-breaking spaces, etc. Here we acquire
36 # paragraph break characters, non-breaking spaces, etc. Here we acquire
38 # the string as plain text so we can compare it.
37 # the string as plain text so we can compare it.
39 current_block = self.currentBlock()
38 current_block = self.currentBlock()
40 string = self._frontend._get_block_plain_text(current_block)
39 string = self._frontend._get_block_plain_text(current_block)
41
40
42 # Decide whether to check for the regular or continuation prompt.
41 # Decide whether to check for the regular or continuation prompt.
43 if current_block.contains(self._frontend._prompt_pos):
42 if current_block.contains(self._frontend._prompt_pos):
44 prompt = self._frontend._prompt
43 prompt = self._frontend._prompt
45 else:
44 else:
46 prompt = self._frontend._continuation_prompt
45 prompt = self._frontend._continuation_prompt
47
46
48 # Don't highlight the part of the string that contains the prompt.
47 # Don't highlight the part of the string that contains the prompt.
49 if string.startswith(prompt):
48 if string.startswith(prompt):
50 self._current_offset = len(prompt)
49 self._current_offset = len(prompt)
51 qstring.remove(0, len(prompt))
50 qstring.remove(0, len(prompt))
52 else:
51 else:
53 self._current_offset = 0
52 self._current_offset = 0
54
53
55 PygmentsHighlighter.highlightBlock(self, qstring)
54 PygmentsHighlighter.highlightBlock(self, qstring)
56
55
57 def rehighlightBlock(self, block):
56 def rehighlightBlock(self, block):
58 """ Reimplemented to temporarily enable highlighting if disabled.
57 """ Reimplemented to temporarily enable highlighting if disabled.
59 """
58 """
60 old = self.highlighting_on
59 old = self.highlighting_on
61 self.highlighting_on = True
60 self.highlighting_on = True
62 super(FrontendHighlighter, self).rehighlightBlock(block)
61 super(FrontendHighlighter, self).rehighlightBlock(block)
63 self.highlighting_on = old
62 self.highlighting_on = old
64
63
65 def setFormat(self, start, count, format):
64 def setFormat(self, start, count, format):
66 """ Reimplemented to highlight selectively.
65 """ Reimplemented to highlight selectively.
67 """
66 """
68 start += self._current_offset
67 start += self._current_offset
69 PygmentsHighlighter.setFormat(self, start, count, format)
68 PygmentsHighlighter.setFormat(self, start, count, format)
70
69
71
70
72 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
71 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
73 """ A Qt frontend for a generic Python kernel.
72 """ A Qt frontend for a generic Python kernel.
74 """
73 """
75
74
76 # An option and corresponding signal for overriding the default kernel
75 # An option and corresponding signal for overriding the default kernel
77 # interrupt behavior.
76 # interrupt behavior.
78 custom_interrupt = False
77 custom_interrupt = False
79 custom_interrupt_requested = QtCore.pyqtSignal()
78 custom_interrupt_requested = QtCore.pyqtSignal()
80
79
81 # An option and corresponding signal for overriding the default kernel
80 # An option and corresponding signal for overriding the default kernel
82 # restart behavior.
81 # restart behavior.
83 custom_restart = False
82 custom_restart = False
84 custom_restart_requested = QtCore.pyqtSignal()
83 custom_restart_requested = QtCore.pyqtSignal()
85
84
86 # Emitted when an 'execute_reply' has been received from the kernel and
85 # Emitted when an 'execute_reply' has been received from the kernel and
87 # processed by the FrontendWidget.
86 # processed by the FrontendWidget.
88 executed = QtCore.pyqtSignal(object)
87 executed = QtCore.pyqtSignal(object)
89
88
90 # Protected class variables.
89 # Protected class variables.
91 _highlighter_class = FrontendHighlighter
90 _highlighter_class = FrontendHighlighter
92 _input_splitter_class = InputSplitter
91 _input_splitter_class = InputSplitter
93
92
94 #---------------------------------------------------------------------------
93 #---------------------------------------------------------------------------
95 # 'object' interface
94 # 'object' interface
96 #---------------------------------------------------------------------------
95 #---------------------------------------------------------------------------
97
96
98 def __init__(self, *args, **kw):
97 def __init__(self, *args, **kw):
99 super(FrontendWidget, self).__init__(*args, **kw)
98 super(FrontendWidget, self).__init__(*args, **kw)
100
99
101 # FrontendWidget protected variables.
100 # FrontendWidget protected variables.
102 self._call_tip_widget = CallTipWidget(self._control)
101 self._call_tip_widget = CallTipWidget(self._control)
103 self._completion_lexer = CompletionLexer(PythonLexer())
102 self._completion_lexer = CompletionLexer(PythonLexer())
104 self._hidden = False
103 self._hidden = False
105 self._highlighter = self._highlighter_class(self)
104 self._highlighter = self._highlighter_class(self)
106 self._input_splitter = self._input_splitter_class(input_mode='block')
105 self._input_splitter = self._input_splitter_class(input_mode='block')
107 self._kernel_manager = None
106 self._kernel_manager = None
108
107
109 # Configure the ConsoleWidget.
108 # Configure the ConsoleWidget.
110 self.tab_width = 4
109 self.tab_width = 4
111 self._set_continuation_prompt('... ')
110 self._set_continuation_prompt('... ')
112
111
113 # Connect signal handlers.
112 # Connect signal handlers.
114 document = self._control.document()
113 document = self._control.document()
115 document.contentsChange.connect(self._document_contents_change)
114 document.contentsChange.connect(self._document_contents_change)
116
115
117 #---------------------------------------------------------------------------
116 #---------------------------------------------------------------------------
118 # 'ConsoleWidget' abstract interface
117 # 'ConsoleWidget' abstract interface
119 #---------------------------------------------------------------------------
118 #---------------------------------------------------------------------------
120
119
121 def _is_complete(self, source, interactive):
120 def _is_complete(self, source, interactive):
122 """ Returns whether 'source' can be completely processed and a new
121 """ Returns whether 'source' can be completely processed and a new
123 prompt created. When triggered by an Enter/Return key press,
122 prompt created. When triggered by an Enter/Return key press,
124 'interactive' is True; otherwise, it is False.
123 'interactive' is True; otherwise, it is False.
125 """
124 """
126 complete = self._input_splitter.push(source.expandtabs(4))
125 complete = self._input_splitter.push(source.expandtabs(4))
127 if interactive:
126 if interactive:
128 complete = not self._input_splitter.push_accepts_more()
127 complete = not self._input_splitter.push_accepts_more()
129 return complete
128 return complete
130
129
131 def _execute(self, source, hidden):
130 def _execute(self, source, hidden):
132 """ Execute 'source'. If 'hidden', do not show any output.
131 """ Execute 'source'. If 'hidden', do not show any output.
133 """
132 """
134 self.kernel_manager.xreq_channel.execute(source, hidden)
133 self.kernel_manager.xreq_channel.execute(source, hidden)
135 self._hidden = hidden
134 self._hidden = hidden
136
135
137 def _prompt_started_hook(self):
136 def _prompt_started_hook(self):
138 """ Called immediately after a new prompt is displayed.
137 """ Called immediately after a new prompt is displayed.
139 """
138 """
140 if not self._reading:
139 if not self._reading:
141 self._highlighter.highlighting_on = True
140 self._highlighter.highlighting_on = True
142
141
143 def _prompt_finished_hook(self):
142 def _prompt_finished_hook(self):
144 """ Called immediately after a prompt is finished, i.e. when some input
143 """ Called immediately after a prompt is finished, i.e. when some input
145 will be processed and a new prompt displayed.
144 will be processed and a new prompt displayed.
146 """
145 """
147 if not self._reading:
146 if not self._reading:
148 self._highlighter.highlighting_on = False
147 self._highlighter.highlighting_on = False
149
148
150 def _tab_pressed(self):
149 def _tab_pressed(self):
151 """ Called when the tab key is pressed. Returns whether to continue
150 """ Called when the tab key is pressed. Returns whether to continue
152 processing the event.
151 processing the event.
153 """
152 """
154 # Perform tab completion if:
153 # Perform tab completion if:
155 # 1) The cursor is in the input buffer.
154 # 1) The cursor is in the input buffer.
156 # 2) There is a non-whitespace character before the cursor.
155 # 2) There is a non-whitespace character before the cursor.
157 text = self._get_input_buffer_cursor_line()
156 text = self._get_input_buffer_cursor_line()
158 if text is None:
157 if text is None:
159 return False
158 return False
160 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
159 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
161 if complete:
160 if complete:
162 self._complete()
161 self._complete()
163 return not complete
162 return not complete
164
163
165 #---------------------------------------------------------------------------
164 #---------------------------------------------------------------------------
166 # 'ConsoleWidget' protected interface
165 # 'ConsoleWidget' protected interface
167 #---------------------------------------------------------------------------
166 #---------------------------------------------------------------------------
168
167
169 def _event_filter_console_keypress(self, event):
168 def _event_filter_console_keypress(self, event):
170 """ Reimplemented to allow execution interruption.
169 """ Reimplemented to allow execution interruption.
171 """
170 """
172 key = event.key()
171 key = event.key()
173 if self._executing and self._control_key_down(event.modifiers()):
172 if self._executing and self._control_key_down(event.modifiers()):
174 if key == QtCore.Qt.Key_C:
173 if key == QtCore.Qt.Key_C:
175 self._kernel_interrupt()
174 self._kernel_interrupt()
176 return True
175 return True
177 elif key == QtCore.Qt.Key_Period:
176 elif key == QtCore.Qt.Key_Period:
178 self._kernel_restart()
177 self._kernel_restart()
179 return True
178 return True
180 return super(FrontendWidget, self)._event_filter_console_keypress(event)
179 return super(FrontendWidget, self)._event_filter_console_keypress(event)
181
180
182 def _show_continuation_prompt(self):
181 def _show_continuation_prompt(self):
183 """ Reimplemented for auto-indentation.
182 """ Reimplemented for auto-indentation.
184 """
183 """
185 super(FrontendWidget, self)._show_continuation_prompt()
184 super(FrontendWidget, self)._show_continuation_prompt()
186 spaces = self._input_splitter.indent_spaces
185 spaces = self._input_splitter.indent_spaces
187 self._append_plain_text('\t' * (spaces / self.tab_width))
186 self._append_plain_text('\t' * (spaces / self.tab_width))
188 self._append_plain_text(' ' * (spaces % self.tab_width))
187 self._append_plain_text(' ' * (spaces % self.tab_width))
189
188
190 #---------------------------------------------------------------------------
189 #---------------------------------------------------------------------------
191 # 'BaseFrontendMixin' abstract interface
190 # 'BaseFrontendMixin' abstract interface
192 #---------------------------------------------------------------------------
191 #---------------------------------------------------------------------------
193
192
194 def _handle_complete_reply(self, rep):
193 def _handle_complete_reply(self, rep):
195 """ Handle replies for tab completion.
194 """ Handle replies for tab completion.
196 """
195 """
197 cursor = self._get_cursor()
196 cursor = self._get_cursor()
198 if rep['parent_header']['msg_id'] == self._complete_id and \
197 if rep['parent_header']['msg_id'] == self._complete_id and \
199 cursor.position() == self._complete_pos:
198 cursor.position() == self._complete_pos:
200 text = '.'.join(self._get_context())
199 text = '.'.join(self._get_context())
201 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
200 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
202 self._complete_with_items(cursor, rep['content']['matches'])
201 self._complete_with_items(cursor, rep['content']['matches'])
203
202
204 def _handle_execute_reply(self, msg):
203 def _handle_execute_reply(self, msg):
205 """ Handles replies for code execution.
204 """ Handles replies for code execution.
206 """
205 """
207 if not self._hidden:
206 if not self._hidden:
208 # Make sure that all output from the SUB channel has been processed
207 # Make sure that all output from the SUB channel has been processed
209 # before writing a new prompt.
208 # before writing a new prompt.
210 self.kernel_manager.sub_channel.flush()
209 self.kernel_manager.sub_channel.flush()
211
210
212 content = msg['content']
211 content = msg['content']
213 status = content['status']
212 status = content['status']
214 if status == 'ok':
213 if status == 'ok':
215 self._process_execute_ok(msg)
214 self._process_execute_ok(msg)
216 elif status == 'error':
215 elif status == 'error':
217 self._process_execute_error(msg)
216 self._process_execute_error(msg)
218 elif status == 'abort':
217 elif status == 'abort':
219 self._process_execute_abort(msg)
218 self._process_execute_abort(msg)
220
219
221 self._show_interpreter_prompt_for_reply(msg)
220 self._show_interpreter_prompt_for_reply(msg)
222 self.executed.emit(msg)
221 self.executed.emit(msg)
223
222
224 def _handle_input_request(self, msg):
223 def _handle_input_request(self, msg):
225 """ Handle requests for raw_input.
224 """ Handle requests for raw_input.
226 """
225 """
227 if self._hidden:
226 if self._hidden:
228 raise RuntimeError('Request for raw input during hidden execution.')
227 raise RuntimeError('Request for raw input during hidden execution.')
229
228
230 # 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
231 # before entering readline mode.
230 # before entering readline mode.
232 self.kernel_manager.sub_channel.flush()
231 self.kernel_manager.sub_channel.flush()
233
232
234 def callback(line):
233 def callback(line):
235 self.kernel_manager.rep_channel.input(line)
234 self.kernel_manager.rep_channel.input(line)
236 self._readline(msg['content']['prompt'], callback=callback)
235 self._readline(msg['content']['prompt'], callback=callback)
237
236
238 def _handle_object_info_reply(self, rep):
237 def _handle_object_info_reply(self, rep):
239 """ Handle replies for call tips.
238 """ Handle replies for call tips.
240 """
239 """
241 cursor = self._get_cursor()
240 cursor = self._get_cursor()
242 if rep['parent_header']['msg_id'] == self._call_tip_id and \
241 if rep['parent_header']['msg_id'] == self._call_tip_id and \
243 cursor.position() == self._call_tip_pos:
242 cursor.position() == self._call_tip_pos:
244 doc = rep['content']['docstring']
243 doc = rep['content']['docstring']
245 if doc:
244 if doc:
246 self._call_tip_widget.show_docstring(doc)
245 self._call_tip_widget.show_docstring(doc)
247
246
248 def _handle_pyout(self, msg):
247 def _handle_pyout(self, msg):
249 """ Handle display hook output.
248 """ Handle display hook output.
250 """
249 """
251 if not self._hidden and self._is_from_this_session(msg):
250 if not self._hidden and self._is_from_this_session(msg):
252 self._append_plain_text(msg['content']['data'] + '\n')
251 self._append_plain_text(msg['content']['data'] + '\n')
253
252
254 def _handle_stream(self, msg):
253 def _handle_stream(self, msg):
255 """ Handle stdout, stderr, and stdin.
254 """ Handle stdout, stderr, and stdin.
256 """
255 """
257 if not self._hidden and self._is_from_this_session(msg):
256 if not self._hidden and self._is_from_this_session(msg):
258 self._append_plain_text(msg['content']['data'])
257 self._append_plain_text(msg['content']['data'])
259 self._control.moveCursor(QtGui.QTextCursor.End)
258 self._control.moveCursor(QtGui.QTextCursor.End)
260
259
261 def _started_channels(self):
260 def _started_channels(self):
262 """ Called when the KernelManager channels have started listening or
261 """ Called when the KernelManager channels have started listening or
263 when the frontend is assigned an already listening KernelManager.
262 when the frontend is assigned an already listening KernelManager.
264 """
263 """
265 self._control.clear()
264 self._control.clear()
266 self._append_plain_text(self._get_banner())
265 self._append_plain_text(self._get_banner())
267 self._show_interpreter_prompt()
266 self._show_interpreter_prompt()
268
267
269 def _stopped_channels(self):
268 def _stopped_channels(self):
270 """ Called when the KernelManager channels have stopped listening or
269 """ Called when the KernelManager channels have stopped listening or
271 when a listening KernelManager is removed from the frontend.
270 when a listening KernelManager is removed from the frontend.
272 """
271 """
273 self._executing = self._reading = False
272 self._executing = self._reading = False
274 self._highlighter.highlighting_on = False
273 self._highlighter.highlighting_on = False
275
274
276 #---------------------------------------------------------------------------
275 #---------------------------------------------------------------------------
277 # 'FrontendWidget' interface
276 # 'FrontendWidget' interface
278 #---------------------------------------------------------------------------
277 #---------------------------------------------------------------------------
279
278
280 def execute_file(self, path, hidden=False):
279 def execute_file(self, path, hidden=False):
281 """ Attempts to execute file with 'path'. If 'hidden', no output is
280 """ Attempts to execute file with 'path'. If 'hidden', no output is
282 shown.
281 shown.
283 """
282 """
284 self.execute('execfile("%s")' % path, hidden=hidden)
283 self.execute('execfile("%s")' % path, hidden=hidden)
285
284
286 #---------------------------------------------------------------------------
285 #---------------------------------------------------------------------------
287 # 'FrontendWidget' protected interface
286 # 'FrontendWidget' protected interface
288 #---------------------------------------------------------------------------
287 #---------------------------------------------------------------------------
289
288
290 def _call_tip(self):
289 def _call_tip(self):
291 """ Shows a call tip, if appropriate, at the current cursor location.
290 """ Shows a call tip, if appropriate, at the current cursor location.
292 """
291 """
293 # Decide if it makes sense to show a call tip
292 # Decide if it makes sense to show a call tip
294 cursor = self._get_cursor()
293 cursor = self._get_cursor()
295 cursor.movePosition(QtGui.QTextCursor.Left)
294 cursor.movePosition(QtGui.QTextCursor.Left)
296 if cursor.document().characterAt(cursor.position()).toAscii() != '(':
295 if cursor.document().characterAt(cursor.position()).toAscii() != '(':
297 return False
296 return False
298 context = self._get_context(cursor)
297 context = self._get_context(cursor)
299 if not context:
298 if not context:
300 return False
299 return False
301
300
302 # Send the metadata request to the kernel
301 # Send the metadata request to the kernel
303 name = '.'.join(context)
302 name = '.'.join(context)
304 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
303 self._call_tip_id = self.kernel_manager.xreq_channel.object_info(name)
305 self._call_tip_pos = self._get_cursor().position()
304 self._call_tip_pos = self._get_cursor().position()
306 return True
305 return True
307
306
308 def _complete(self):
307 def _complete(self):
309 """ Performs completion at the current cursor location.
308 """ Performs completion at the current cursor location.
310 """
309 """
311 context = self._get_context()
310 context = self._get_context()
312 if context:
311 if context:
313 # Send the completion request to the kernel
312 # Send the completion request to the kernel
314 self._complete_id = self.kernel_manager.xreq_channel.complete(
313 self._complete_id = self.kernel_manager.xreq_channel.complete(
315 '.'.join(context), # text
314 '.'.join(context), # text
316 self._get_input_buffer_cursor_line(), # line
315 self._get_input_buffer_cursor_line(), # line
317 self._get_input_buffer_cursor_column(), # cursor_pos
316 self._get_input_buffer_cursor_column(), # cursor_pos
318 self.input_buffer) # block
317 self.input_buffer) # block
319 self._complete_pos = self._get_cursor().position()
318 self._complete_pos = self._get_cursor().position()
320
319
321 def _get_banner(self):
320 def _get_banner(self):
322 """ Gets a banner to display at the beginning of a session.
321 """ Gets a banner to display at the beginning of a session.
323 """
322 """
324 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
323 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
325 '"license" for more information.'
324 '"license" for more information.'
326 return banner % (sys.version, sys.platform)
325 return banner % (sys.version, sys.platform)
327
326
328 def _get_context(self, cursor=None):
327 def _get_context(self, cursor=None):
329 """ Gets the context for the specified cursor (or the current cursor
328 """ Gets the context for the specified cursor (or the current cursor
330 if none is specified).
329 if none is specified).
331 """
330 """
332 if cursor is None:
331 if cursor is None:
333 cursor = self._get_cursor()
332 cursor = self._get_cursor()
334 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
333 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
335 QtGui.QTextCursor.KeepAnchor)
334 QtGui.QTextCursor.KeepAnchor)
336 text = str(cursor.selection().toPlainText())
335 text = str(cursor.selection().toPlainText())
337 return self._completion_lexer.get_context(text)
336 return self._completion_lexer.get_context(text)
338
337
339 def _kernel_interrupt(self):
338 def _kernel_interrupt(self):
340 """ Attempts to interrupt the running kernel.
339 """ Attempts to interrupt the running kernel.
341 """
340 """
342 if self.custom_interrupt:
341 if self.custom_interrupt:
343 self.custom_interrupt_requested.emit()
342 self.custom_interrupt_requested.emit()
344 elif self.kernel_manager.has_kernel:
343 elif self.kernel_manager.has_kernel:
345 self.kernel_manager.signal_kernel(signal.SIGINT)
344 self.kernel_manager.signal_kernel(signal.SIGINT)
346 else:
345 else:
347 self._append_plain_text('Kernel process is either remote or '
346 self._append_plain_text('Kernel process is either remote or '
348 'unspecified. Cannot interrupt.\n')
347 'unspecified. Cannot interrupt.\n')
349
348
350 def _kernel_restart(self):
349 def _kernel_restart(self):
351 """ Attempts to restart the running kernel.
350 """ Attempts to restart the running kernel.
352 """
351 """
353 if self.custom_restart:
352 if self.custom_restart:
354 self.custom_restart_requested.emit()
353 self.custom_restart_requested.emit()
355 elif self.kernel_manager.has_kernel:
354 elif self.kernel_manager.has_kernel:
356 try:
355 try:
357 self.kernel_manager.restart_kernel()
356 self.kernel_manager.restart_kernel()
358 except RuntimeError:
357 except RuntimeError:
359 message = 'Kernel started externally. Cannot restart.\n'
358 message = 'Kernel started externally. Cannot restart.\n'
360 self._append_plain_text(message)
359 self._append_plain_text(message)
361 else:
360 else:
362 self._stopped_channels()
361 self._stopped_channels()
363 self._append_plain_text('Kernel restarting...\n')
362 self._append_plain_text('Kernel restarting...\n')
364 self._show_interpreter_prompt()
363 self._show_interpreter_prompt()
365 else:
364 else:
366 self._append_plain_text('Kernel process is either remote or '
365 self._append_plain_text('Kernel process is either remote or '
367 'unspecified. Cannot restart.\n')
366 'unspecified. Cannot restart.\n')
368
367
369 def _process_execute_abort(self, msg):
368 def _process_execute_abort(self, msg):
370 """ Process a reply for an aborted execution request.
369 """ Process a reply for an aborted execution request.
371 """
370 """
372 self._append_plain_text("ERROR: execution aborted\n")
371 self._append_plain_text("ERROR: execution aborted\n")
373
372
374 def _process_execute_error(self, msg):
373 def _process_execute_error(self, msg):
375 """ Process a reply for an execution request that resulted in an error.
374 """ Process a reply for an execution request that resulted in an error.
376 """
375 """
377 content = msg['content']
376 content = msg['content']
378 traceback = ''.join(content['traceback'])
377 traceback = ''.join(content['traceback'])
379 self._append_plain_text(traceback)
378 self._append_plain_text(traceback)
380
379
381 def _process_execute_ok(self, msg):
380 def _process_execute_ok(self, msg):
382 """ Process a reply for a successful execution equest.
381 """ Process a reply for a successful execution equest.
383 """
382 """
384 payload = msg['content']['payload']
383 payload = msg['content']['payload']
385 for item in payload:
384 for item in payload:
386 if not self._process_execute_payload(item):
385 if not self._process_execute_payload(item):
387 warning = 'Received unknown payload of type %s\n'
386 warning = 'Received unknown payload of type %s\n'
388 self._append_plain_text(warning % repr(item['source']))
387 self._append_plain_text(warning % repr(item['source']))
389
388
390 def _process_execute_payload(self, item):
389 def _process_execute_payload(self, item):
391 """ Process a single payload item from the list of payload items in an
390 """ Process a single payload item from the list of payload items in an
392 execution reply. Returns whether the payload was handled.
391 execution reply. Returns whether the payload was handled.
393 """
392 """
394 # The basic FrontendWidget doesn't handle payloads, as they are a
393 # The basic FrontendWidget doesn't handle payloads, as they are a
395 # mechanism for going beyond the standard Python interpreter model.
394 # mechanism for going beyond the standard Python interpreter model.
396 return False
395 return False
397
396
398 def _show_interpreter_prompt(self):
397 def _show_interpreter_prompt(self):
399 """ Shows a prompt for the interpreter.
398 """ Shows a prompt for the interpreter.
400 """
399 """
401 self._show_prompt('>>> ')
400 self._show_prompt('>>> ')
402
401
403 def _show_interpreter_prompt_for_reply(self, msg):
402 def _show_interpreter_prompt_for_reply(self, msg):
404 """ Shows a prompt for the interpreter given an 'execute_reply' message.
403 """ Shows a prompt for the interpreter given an 'execute_reply' message.
405 """
404 """
406 self._show_interpreter_prompt()
405 self._show_interpreter_prompt()
407
406
408 #------ Signal handlers ----------------------------------------------------
407 #------ Signal handlers ----------------------------------------------------
409
408
410 def _document_contents_change(self, position, removed, added):
409 def _document_contents_change(self, position, removed, added):
411 """ Called whenever the document's content changes. Display a call tip
410 """ Called whenever the document's content changes. Display a call tip
412 if appropriate.
411 if appropriate.
413 """
412 """
414 # Calculate where the cursor should be *after* the change:
413 # Calculate where the cursor should be *after* the change:
415 position += added
414 position += added
416
415
417 document = self._control.document()
416 document = self._control.document()
418 if position == self._get_cursor().position():
417 if position == self._get_cursor().position():
419 self._call_tip()
418 self._call_tip()
@@ -1,93 +1,99 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 """ A minimal application using the Qt console-style IPython frontend.
3 """ A minimal application using the Qt console-style IPython frontend.
4 """
4 """
5
5
6 # Systemm library imports
6 # Systemm library imports
7 from PyQt4 import QtCore, QtGui
7 from PyQt4 import QtGui
8
8
9 # Local imports
9 # Local imports
10 from IPython.external.argparse import ArgumentParser
10 from IPython.external.argparse import ArgumentParser
11 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
11 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
12 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
12 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
13 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
13 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
14 from IPython.frontend.qt.kernelmanager import QtKernelManager
14 from IPython.frontend.qt.kernelmanager import QtKernelManager
15
15
16 # Constants
16 # Constants
17 LOCALHOST = '127.0.0.1'
17 LOCALHOST = '127.0.0.1'
18
18
19
19
20 def main():
20 def main():
21 """ Entry point for application.
21 """ Entry point for application.
22 """
22 """
23 # Parse command line arguments.
23 # Parse command line arguments.
24 parser = ArgumentParser()
24 parser = ArgumentParser()
25 kgroup = parser.add_argument_group('kernel options')
25 kgroup = parser.add_argument_group('kernel options')
26 kgroup.add_argument('-e', '--existing', action='store_true',
26 kgroup.add_argument('-e', '--existing', action='store_true',
27 help='connect to an existing kernel')
27 help='connect to an existing kernel')
28 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
28 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
29 help='set the kernel\'s IP address [default localhost]')
29 help='set the kernel\'s IP address [default localhost]')
30 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
30 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
31 help='set the XREQ channel port [default random]')
31 help='set the XREQ channel port [default random]')
32 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
32 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
33 help='set the SUB channel port [default random]')
33 help='set the SUB channel port [default random]')
34 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
34 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
35 help='set the REP channel port [default random]')
35 help='set the REP channel port [default random]')
36
36
37 egroup = kgroup.add_mutually_exclusive_group()
37 egroup = kgroup.add_mutually_exclusive_group()
38 egroup.add_argument('--pure', action='store_true', help = \
38 egroup.add_argument('--pure', action='store_true', help = \
39 'use a pure Python kernel instead of an IPython kernel')
39 'use a pure Python kernel instead of an IPython kernel')
40 egroup.add_argument('--pylab', action='store_true',
40 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
41 help='use a kernel with PyLab enabled')
41 const='auto', help = \
42 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
43 given, the GUI backend is matplotlib's, otherwise use one of: \
44 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
42
45
43 wgroup = parser.add_argument_group('widget options')
46 wgroup = parser.add_argument_group('widget options')
44 wgroup.add_argument('--paging', type=str, default='inside',
47 wgroup.add_argument('--paging', type=str, default='inside',
45 choices = ['inside', 'hsplit', 'vsplit', 'none'],
48 choices = ['inside', 'hsplit', 'vsplit', 'none'],
46 help='set the paging style [default inside]')
49 help='set the paging style [default inside]')
47 wgroup.add_argument('--rich', action='store_true',
50 wgroup.add_argument('--rich', action='store_true',
48 help='enable rich text support')
51 help='enable rich text support')
49 wgroup.add_argument('--tab-simple', action='store_true',
52 wgroup.add_argument('--tab-simple', action='store_true',
50 help='do tab completion ala a Unix terminal')
53 help='do tab completion ala a Unix terminal')
51
54
52 args = parser.parse_args()
55 args = parser.parse_args()
53
56
54 # Don't let Qt or ZMQ swallow KeyboardInterupts.
57 # Don't let Qt or ZMQ swallow KeyboardInterupts.
55 import signal
58 import signal
56 signal.signal(signal.SIGINT, signal.SIG_DFL)
59 signal.signal(signal.SIGINT, signal.SIG_DFL)
57
60
58 # Create a KernelManager and start a kernel.
61 # Create a KernelManager and start a kernel.
59 kernel_manager = QtKernelManager(xreq_address=(args.ip, args.xreq),
62 kernel_manager = QtKernelManager(xreq_address=(args.ip, args.xreq),
60 sub_address=(args.ip, args.sub),
63 sub_address=(args.ip, args.sub),
61 rep_address=(args.ip, args.rep))
64 rep_address=(args.ip, args.rep))
62 if args.ip == LOCALHOST and not args.existing:
65 if args.ip == LOCALHOST and not args.existing:
63 if args.pure:
66 if args.pure:
64 kernel_manager.start_kernel(ipython=False)
67 kernel_manager.start_kernel(ipython=False)
65 elif args.pylab:
68 elif args.pylab:
66 if args.rich:
69 if args.rich:
67 kernel_manager.start_kernel(pylab='payload-svg')
70 kernel_manager.start_kernel(pylab='payload-svg')
68 else:
71 else:
69 kernel_manager.start_kernel(pylab='qt4')
72 if args.pylab == 'auto':
73 kernel_manager.start_kernel(pylab='qt4')
74 else:
75 kernel_manager.start_kernel(pylab=args.pylab)
70 else:
76 else:
71 kernel_manager.start_kernel()
77 kernel_manager.start_kernel()
72 kernel_manager.start_channels()
78 kernel_manager.start_channels()
73
79
74 # Create the widget.
80 # Create the widget.
75 app = QtGui.QApplication([])
81 app = QtGui.QApplication([])
76 if args.pure:
82 if args.pure:
77 kind = 'rich' if args.rich else 'plain'
83 kind = 'rich' if args.rich else 'plain'
78 widget = FrontendWidget(kind=kind, paging=args.paging)
84 widget = FrontendWidget(kind=kind, paging=args.paging)
79 elif args.rich:
85 elif args.rich:
80 widget = RichIPythonWidget(paging=args.paging)
86 widget = RichIPythonWidget(paging=args.paging)
81 else:
87 else:
82 widget = IPythonWidget(paging=args.paging)
88 widget = IPythonWidget(paging=args.paging)
83 widget.gui_completion = not args.tab_simple
89 widget.gui_completion = not args.tab_simple
84 widget.kernel_manager = kernel_manager
90 widget.kernel_manager = kernel_manager
85 widget.setWindowTitle('Python' if args.pure else 'IPython')
91 widget.setWindowTitle('Python' if args.pure else 'IPython')
86 widget.show()
92 widget.show()
87
93
88 # Start the application main loop.
94 # Start the application main loop.
89 app.exec_()
95 app.exec_()
90
96
91
97
92 if __name__ == '__main__':
98 if __name__ == '__main__':
93 main()
99 main()
@@ -1,571 +1,572 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # coding: utf-8
2 # coding: utf-8
3 """
3 """
4 Inputhook management for GUI event loop integration.
4 Inputhook management for GUI event loop integration.
5 """
5 """
6
6
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008-2009 The IPython Development Team
8 # Copyright (C) 2008-2009 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
17
18 import ctypes
18 import ctypes
19 import sys
19 import sys
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Constants
22 # Constants
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 # Constants for identifying the GUI toolkits.
25 # Constants for identifying the GUI toolkits.
26 GUI_WX = 'wx'
26 GUI_WX = 'wx'
27 GUI_QT = 'qt'
27 GUI_QT = 'qt'
28 GUI_QT4 = 'qt4'
28 GUI_QT4 = 'qt4'
29 GUI_GTK = 'gtk'
29 GUI_GTK = 'gtk'
30 GUI_TK = 'tk'
30 GUI_TK = 'tk'
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # Utility classes
33 # Utility classes
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36
36
37 class _DummyMainloop(object):
37 class _DummyMainloop(object):
38 """A special manager to hijack GUI mainloops that is mostly a no-op.
38 """A special manager to hijack GUI mainloops that is mostly a no-op.
39
39
40 We are not using this class currently as it breaks GUI code that calls
40 We are not using this class currently as it breaks GUI code that calls
41 a mainloop function after the app has started to process pending events.
41 a mainloop function after the app has started to process pending events.
42 """
42 """
43 def __init__(self, ml, ihm, gui_type):
43 def __init__(self, ml, ihm, gui_type):
44 self.ml = ml
44 self.ml = ml
45 self.ihm = ihm
45 self.ihm = ihm
46 self.gui_type = gui_type
46 self.gui_type = gui_type
47
47
48 def __call__(self, *args, **kw):
48 def __call__(self, *args, **kw):
49 if self.ihm.current_gui() == self.gui_type:
49 if self.ihm.current_gui() == self.gui_type:
50 pass
50 pass
51 else:
51 else:
52 self.ml(*args, **kw)
52 self.ml(*args, **kw)
53
53
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Appstart and spin functions
56 # Appstart and spin functions
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59
59
60 def appstart_qt4(app):
60 def appstart_qt4(app):
61 """Start the qt4 event loop in a way that plays with IPython.
61 """Start the qt4 event loop in a way that plays with IPython.
62
62
63 When a qt4 app is run interactively in IPython, the event loop should
63 When a qt4 app is run interactively in IPython, the event loop should
64 not be started. This function checks to see if IPython's qt4 integration
64 not be started. This function checks to see if IPython's qt4 integration
65 is activated and if so, it passes. If not, it will call the :meth:`exec_`
65 is activated and if so, it passes. If not, it will call the :meth:`exec_`
66 method of the main qt4 app.
66 method of the main qt4 app.
67
67
68 This function should be used by users who want their qt4 scripts to work
68 This function should be used by users who want their qt4 scripts to work
69 both at the command line and in IPython. These users should put the
69 both at the command line and in IPython. These users should put the
70 following logic at the bottom on their script, after they create a
70 following logic at the bottom on their script, after they create a
71 :class:`QApplication` instance (called ``app`` here)::
71 :class:`QApplication` instance (called ``app`` here)::
72
72
73 try:
73 try:
74 from IPython.lib.inputhook import appstart_qt4
74 from IPython.lib.inputhook import appstart_qt4
75 appstart_qt4(app)
75 appstart_qt4(app)
76 except ImportError:
76 except ImportError:
77 app.exec_()
77 app.exec_()
78 """
78 """
79 from PyQt4 import QtCore, QtGui
79 from PyQt4 import QtCore
80
80
81 assert isinstance(app, QtCore.QCoreApplication)
81 assert isinstance(app, QtCore.QCoreApplication)
82 if app is not None:
82 if app is not None:
83 if current_gui() == GUI_QT4:
83 if current_gui() == GUI_QT4:
84 pass
84 pass
85 else:
85 else:
86 app.exec_()
86 app.exec_()
87
87
88
88
89 def appstart_wx(app):
89 def appstart_wx(app):
90 """Start the wx event loop in a way that plays with IPython.
90 """Start the wx event loop in a way that plays with IPython.
91
91
92 When a wx app is run interactively in IPython, the event loop should
92 When a wx app is run interactively in IPython, the event loop should
93 not be started. This function checks to see if IPython's wx integration
93 not be started. This function checks to see if IPython's wx integration
94 is activated and if so, it passes. If not, it will call the
94 is activated and if so, it passes. If not, it will call the
95 :meth:`MainLoop` method of the main qt4 app.
95 :meth:`MainLoop` method of the main qt4 app.
96
96
97 This function should be used by users who want their wx scripts to work
97 This function should be used by users who want their wx scripts to work
98 both at the command line and in IPython. These users should put the
98 both at the command line and in IPython. These users should put the
99 following logic at the bottom on their script, after they create a
99 following logic at the bottom on their script, after they create a
100 :class:`App` instance (called ``app`` here)::
100 :class:`App` instance (called ``app`` here)::
101
101
102 try:
102 try:
103 from IPython.lib.inputhook import appstart_wx
103 from IPython.lib.inputhook import appstart_wx
104 appstart_wx(app)
104 appstart_wx(app)
105 except ImportError:
105 except ImportError:
106 app.MainLoop()
106 app.MainLoop()
107 """
107 """
108 import wx
108 import wx
109
109
110 assert isinstance(app, wx.App)
110 assert isinstance(app, wx.App)
111 if app is not None:
111 if app is not None:
112 if current_gui() == GUI_WX:
112 if current_gui() == GUI_WX:
113 pass
113 pass
114 else:
114 else:
115 app.MainLoop()
115 app.MainLoop()
116
116
117
117
118 def appstart_tk(app):
118 def appstart_tk(app):
119 """Start the tk event loop in a way that plays with IPython.
119 """Start the tk event loop in a way that plays with IPython.
120
120
121 When a tk app is run interactively in IPython, the event loop should
121 When a tk app is run interactively in IPython, the event loop should
122 not be started. This function checks to see if IPython's tk integration
122 not be started. This function checks to see if IPython's tk integration
123 is activated and if so, it passes. If not, it will call the
123 is activated and if so, it passes. If not, it will call the
124 :meth:`mainloop` method of the tk object passed to this method.
124 :meth:`mainloop` method of the tk object passed to this method.
125
125
126 This function should be used by users who want their tk scripts to work
126 This function should be used by users who want their tk scripts to work
127 both at the command line and in IPython. These users should put the
127 both at the command line and in IPython. These users should put the
128 following logic at the bottom on their script, after they create a
128 following logic at the bottom on their script, after they create a
129 :class:`Tk` instance (called ``app`` here)::
129 :class:`Tk` instance (called ``app`` here)::
130
130
131 try:
131 try:
132 from IPython.lib.inputhook import appstart_tk
132 from IPython.lib.inputhook import appstart_tk
133 appstart_tk(app)
133 appstart_tk(app)
134 except ImportError:
134 except ImportError:
135 app.mainloop()
135 app.mainloop()
136 """
136 """
137 if app is not None:
137 if app is not None:
138 if current_gui() == GUI_TK:
138 if current_gui() == GUI_TK:
139 pass
139 pass
140 else:
140 else:
141 app.mainloop()
141 app.mainloop()
142
142
143 def appstart_gtk():
143 def appstart_gtk():
144 """Start the gtk event loop in a way that plays with IPython.
144 """Start the gtk event loop in a way that plays with IPython.
145
145
146 When a gtk app is run interactively in IPython, the event loop should
146 When a gtk app is run interactively in IPython, the event loop should
147 not be started. This function checks to see if IPython's gtk integration
147 not be started. This function checks to see if IPython's gtk integration
148 is activated and if so, it passes. If not, it will call
148 is activated and if so, it passes. If not, it will call
149 :func:`gtk.main`. Unlike the other appstart implementations, this does
149 :func:`gtk.main`. Unlike the other appstart implementations, this does
150 not take an ``app`` argument.
150 not take an ``app`` argument.
151
151
152 This function should be used by users who want their gtk scripts to work
152 This function should be used by users who want their gtk scripts to work
153 both at the command line and in IPython. These users should put the
153 both at the command line and in IPython. These users should put the
154 following logic at the bottom on their script::
154 following logic at the bottom on their script::
155
155
156 try:
156 try:
157 from IPython.lib.inputhook import appstart_gtk
157 from IPython.lib.inputhook import appstart_gtk
158 appstart_gtk()
158 appstart_gtk()
159 except ImportError:
159 except ImportError:
160 gtk.main()
160 gtk.main()
161 """
161 """
162 import gtk
162 import gtk
163 if current_gui() == GUI_GTK:
163 if current_gui() == GUI_GTK:
164 pass
164 pass
165 else:
165 else:
166 gtk.main()
166 gtk.main()
167
167
168 #-----------------------------------------------------------------------------
168 #-----------------------------------------------------------------------------
169 # Main InputHookManager class
169 # Main InputHookManager class
170 #-----------------------------------------------------------------------------
170 #-----------------------------------------------------------------------------
171
171
172
172
173 class InputHookManager(object):
173 class InputHookManager(object):
174 """Manage PyOS_InputHook for different GUI toolkits.
174 """Manage PyOS_InputHook for different GUI toolkits.
175
175
176 This class installs various hooks under ``PyOSInputHook`` to handle
176 This class installs various hooks under ``PyOSInputHook`` to handle
177 GUI event loop integration.
177 GUI event loop integration.
178 """
178 """
179
179
180 def __init__(self):
180 def __init__(self):
181 self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int)
181 self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int)
182 self._apps = {}
182 self._apps = {}
183 self._spinner_dict = {
183 self._spinner_dict = {
184 GUI_QT4 : self._spin_qt4,
184 GUI_QT4 : self._spin_qt4,
185 GUI_WX : self._spin_wx,
185 GUI_WX : self._spin_wx,
186 GUI_GTK : self._spin_gtk,
186 GUI_GTK : self._spin_gtk,
187 GUI_TK : self._spin_tk}
187 GUI_TK : self._spin_tk}
188 self._reset()
188 self._reset()
189
189
190 def _reset(self):
190 def _reset(self):
191 self._callback_pyfunctype = None
191 self._callback_pyfunctype = None
192 self._callback = None
192 self._callback = None
193 self._installed = False
193 self._installed = False
194 self._current_gui = None
194 self._current_gui = None
195
195
196 def _hijack_wx(self):
196 def _hijack_wx(self):
197 """Hijack the wx mainloop so a user calling it won't cause badness.
197 """Hijack the wx mainloop so a user calling it won't cause badness.
198
198
199 We are not currently using this as it breaks GUI code that calls a
199 We are not currently using this as it breaks GUI code that calls a
200 mainloop at anytime but startup.
200 mainloop at anytime but startup.
201 """
201 """
202 import wx
202 import wx
203 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
203 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
204 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
204 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
205 else: raise AttributeError('Could not find wx core module')
205 else: raise AttributeError('Could not find wx core module')
206 orig_mainloop = core.PyApp_MainLoop
206 orig_mainloop = core.PyApp_MainLoop
207 core.PyApp_MainLoop = _DummyMainloop
207 core.PyApp_MainLoop = _DummyMainloop
208 return orig_mainloop
208 return orig_mainloop
209
209
210 def _hijack_qt4(self):
210 def _hijack_qt4(self):
211 """Hijack the qt4 mainloop so a user calling it won't cause badness.
211 """Hijack the qt4 mainloop so a user calling it won't cause badness.
212
212
213 We are not currently using this as it breaks GUI code that calls a
213 We are not currently using this as it breaks GUI code that calls a
214 mainloop at anytime but startup.
214 mainloop at anytime but startup.
215 """
215 """
216 from PyQt4 import QtGui, QtCore
216 from PyQt4 import QtGui, QtCore
217 orig_mainloop = QtGui.qApp.exec_
217 orig_mainloop = QtGui.qApp.exec_
218 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_QT4)
218 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_QT4)
219 QtGui.qApp.exec_ = dumb_ml
219 QtGui.qApp.exec_ = dumb_ml
220 QtGui.QApplication.exec_ = dumb_ml
220 QtGui.QApplication.exec_ = dumb_ml
221 QtCore.QCoreApplication.exec_ = dumb_ml
221 QtCore.QCoreApplication.exec_ = dumb_ml
222 return orig_mainloop
222 return orig_mainloop
223
223
224 def _hijack_gtk(self):
224 def _hijack_gtk(self):
225 """Hijack the gtk mainloop so a user calling it won't cause badness.
225 """Hijack the gtk mainloop so a user calling it won't cause badness.
226
226
227 We are not currently using this as it breaks GUI code that calls a
227 We are not currently using this as it breaks GUI code that calls a
228 mainloop at anytime but startup.
228 mainloop at anytime but startup.
229 """
229 """
230 import gtk
230 import gtk
231 orig_mainloop = gtk.main
231 orig_mainloop = gtk.main
232 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_GTK)
232 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_GTK)
233 gtk.mainloop = dumb_ml
233 gtk.mainloop = dumb_ml
234 gtk.main = dumb_ml
234 gtk.main = dumb_ml
235 return orig_mainloop
235 return orig_mainloop
236
236
237 def _hijack_tk(self):
237 def _hijack_tk(self):
238 """Hijack the tk mainloop so a user calling it won't cause badness.
238 """Hijack the tk mainloop so a user calling it won't cause badness.
239
239
240 We are not currently using this as it breaks GUI code that calls a
240 We are not currently using this as it breaks GUI code that calls a
241 mainloop at anytime but startup.
241 mainloop at anytime but startup.
242 """
242 """
243 import Tkinter
243 import Tkinter
244 # FIXME: gtk is not imported here and we shouldn't be using gtk.main!
244 orig_mainloop = gtk.main
245 orig_mainloop = gtk.main
245 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK)
246 dumb_ml = _DummyMainloop(orig_mainloop, self, GUI_TK)
246 Tkinter.Misc.mainloop = dumb_ml
247 Tkinter.Misc.mainloop = dumb_ml
247 Tkinter.mainloop = dumb_ml
248 Tkinter.mainloop = dumb_ml
248
249
249 def _spin_qt4(self):
250 def _spin_qt4(self):
250 """Process all pending events in the qt4 event loop.
251 """Process all pending events in the qt4 event loop.
251
252
252 This is for internal IPython use only and user code should not call this.
253 This is for internal IPython use only and user code should not call this.
253 Instead, they should issue the raw GUI calls themselves.
254 Instead, they should issue the raw GUI calls themselves.
254 """
255 """
255 from PyQt4 import QtCore, QtGui
256 from PyQt4 import QtCore
256
257
257 app = QtCore.QCoreApplication.instance()
258 app = QtCore.QCoreApplication.instance()
258 if app is not None:
259 if app is not None:
259 QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents)
260 QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents)
260
261
261 def _spin_wx(self):
262 def _spin_wx(self):
262 """Process all pending events in the wx event loop.
263 """Process all pending events in the wx event loop.
263
264
264 This is for internal IPython use only and user code should not call this.
265 This is for internal IPython use only and user code should not call this.
265 Instead, they should issue the raw GUI calls themselves.
266 Instead, they should issue the raw GUI calls themselves.
266 """
267 """
267 import wx
268 import wx
268 app = wx.GetApp()
269 app = wx.GetApp()
269 if app is not None and wx.Thread_IsMain():
270 if app is not None and wx.Thread_IsMain():
270 evtloop = wx.EventLoop()
271 evtloop = wx.EventLoop()
271 ea = wx.EventLoopActivator(evtloop)
272 ea = wx.EventLoopActivator(evtloop)
272 while evtloop.Pending():
273 while evtloop.Pending():
273 evtloop.Dispatch()
274 evtloop.Dispatch()
274 app.ProcessIdle()
275 app.ProcessIdle()
275 del ea
276 del ea
276
277
277 def _spin_gtk(self):
278 def _spin_gtk(self):
278 """Process all pending events in the gtk event loop.
279 """Process all pending events in the gtk event loop.
279
280
280 This is for internal IPython use only and user code should not call this.
281 This is for internal IPython use only and user code should not call this.
281 Instead, they should issue the raw GUI calls themselves.
282 Instead, they should issue the raw GUI calls themselves.
282 """
283 """
283 import gtk
284 import gtk
284 gtk.gdk.threads_enter()
285 gtk.gdk.threads_enter()
285 while gtk.events_pending():
286 while gtk.events_pending():
286 gtk.main_iteration(False)
287 gtk.main_iteration(False)
287 gtk.gdk.flush()
288 gtk.gdk.flush()
288 gtk.gdk.threads_leave()
289 gtk.gdk.threads_leave()
289
290
290 def _spin_tk(self):
291 def _spin_tk(self):
291 """Process all pending events in the tk event loop.
292 """Process all pending events in the tk event loop.
292
293
293 This is for internal IPython use only and user code should not call this.
294 This is for internal IPython use only and user code should not call this.
294 Instead, they should issue the raw GUI calls themselves.
295 Instead, they should issue the raw GUI calls themselves.
295 """
296 """
296 app = self._apps.get(GUI_TK)
297 app = self._apps.get(GUI_TK)
297 if app is not None:
298 if app is not None:
298 app.update()
299 app.update()
299
300
300 def spin(self):
301 def spin(self):
301 """Process pending events in the current gui.
302 """Process pending events in the current gui.
302
303
303 This method is just provided for IPython to use internally if needed
304 This method is just provided for IPython to use internally if needed
304 for things like testing. Third party projects should not call this
305 for things like testing. Third party projects should not call this
305 method, but instead should call the underlying GUI toolkit methods
306 method, but instead should call the underlying GUI toolkit methods
306 that we are calling.
307 that we are calling.
307 """
308 """
308 spinner = self._spinner_dict.get(self._current_gui, lambda: None)
309 spinner = self._spinner_dict.get(self._current_gui, lambda: None)
309 spinner()
310 spinner()
310
311
311 def get_pyos_inputhook(self):
312 def get_pyos_inputhook(self):
312 """Return the current PyOS_InputHook as a ctypes.c_void_p."""
313 """Return the current PyOS_InputHook as a ctypes.c_void_p."""
313 return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook")
314 return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook")
314
315
315 def get_pyos_inputhook_as_func(self):
316 def get_pyos_inputhook_as_func(self):
316 """Return the current PyOS_InputHook as a ctypes.PYFUNCYPE."""
317 """Return the current PyOS_InputHook as a ctypes.PYFUNCYPE."""
317 return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook")
318 return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook")
318
319
319 def set_inputhook(self, callback):
320 def set_inputhook(self, callback):
320 """Set PyOS_InputHook to callback and return the previous one."""
321 """Set PyOS_InputHook to callback and return the previous one."""
321 self._callback = callback
322 self._callback = callback
322 self._callback_pyfunctype = self.PYFUNC(callback)
323 self._callback_pyfunctype = self.PYFUNC(callback)
323 pyos_inputhook_ptr = self.get_pyos_inputhook()
324 pyos_inputhook_ptr = self.get_pyos_inputhook()
324 original = self.get_pyos_inputhook_as_func()
325 original = self.get_pyos_inputhook_as_func()
325 pyos_inputhook_ptr.value = \
326 pyos_inputhook_ptr.value = \
326 ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value
327 ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value
327 self._installed = True
328 self._installed = True
328 return original
329 return original
329
330
330 def clear_inputhook(self, app=None):
331 def clear_inputhook(self, app=None):
331 """Set PyOS_InputHook to NULL and return the previous one.
332 """Set PyOS_InputHook to NULL and return the previous one.
332
333
333 Parameters
334 Parameters
334 ----------
335 ----------
335 app : optional, ignored
336 app : optional, ignored
336 This parameter is allowed only so that clear_inputhook() can be
337 This parameter is allowed only so that clear_inputhook() can be
337 called with a similar interface as all the ``enable_*`` methods. But
338 called with a similar interface as all the ``enable_*`` methods. But
338 the actual value of the parameter is ignored. This uniform interface
339 the actual value of the parameter is ignored. This uniform interface
339 makes it easier to have user-level entry points in the main IPython
340 makes it easier to have user-level entry points in the main IPython
340 app like :meth:`enable_gui`."""
341 app like :meth:`enable_gui`."""
341 pyos_inputhook_ptr = self.get_pyos_inputhook()
342 pyos_inputhook_ptr = self.get_pyos_inputhook()
342 original = self.get_pyos_inputhook_as_func()
343 original = self.get_pyos_inputhook_as_func()
343 pyos_inputhook_ptr.value = ctypes.c_void_p(None).value
344 pyos_inputhook_ptr.value = ctypes.c_void_p(None).value
344 self._reset()
345 self._reset()
345 return original
346 return original
346
347
347 def clear_app_refs(self, gui=None):
348 def clear_app_refs(self, gui=None):
348 """Clear IPython's internal reference to an application instance.
349 """Clear IPython's internal reference to an application instance.
349
350
350 Whenever we create an app for a user on qt4 or wx, we hold a
351 Whenever we create an app for a user on qt4 or wx, we hold a
351 reference to the app. This is needed because in some cases bad things
352 reference to the app. This is needed because in some cases bad things
352 can happen if a user doesn't hold a reference themselves. This
353 can happen if a user doesn't hold a reference themselves. This
353 method is provided to clear the references we are holding.
354 method is provided to clear the references we are holding.
354
355
355 Parameters
356 Parameters
356 ----------
357 ----------
357 gui : None or str
358 gui : None or str
358 If None, clear all app references. If ('wx', 'qt4') clear
359 If None, clear all app references. If ('wx', 'qt4') clear
359 the app for that toolkit. References are not held for gtk or tk
360 the app for that toolkit. References are not held for gtk or tk
360 as those toolkits don't have the notion of an app.
361 as those toolkits don't have the notion of an app.
361 """
362 """
362 if gui is None:
363 if gui is None:
363 self._apps = {}
364 self._apps = {}
364 elif self._apps.has_key(gui):
365 elif self._apps.has_key(gui):
365 del self._apps[gui]
366 del self._apps[gui]
366
367
367 def enable_wx(self, app=False):
368 def enable_wx(self, app=False):
368 """Enable event loop integration with wxPython.
369 """Enable event loop integration with wxPython.
369
370
370 Parameters
371 Parameters
371 ----------
372 ----------
372 app : bool
373 app : bool
373 Create a running application object or not.
374 Create a running application object or not.
374
375
375 Notes
376 Notes
376 -----
377 -----
377 This methods sets the ``PyOS_InputHook`` for wxPython, which allows
378 This methods sets the ``PyOS_InputHook`` for wxPython, which allows
378 the wxPython to integrate with terminal based applications like
379 the wxPython to integrate with terminal based applications like
379 IPython.
380 IPython.
380
381
381 If ``app`` is True, we create an :class:`wx.App` as follows::
382 If ``app`` is True, we create an :class:`wx.App` as follows::
382
383
383 import wx
384 import wx
384 app = wx.App(redirect=False, clearSigInt=False)
385 app = wx.App(redirect=False, clearSigInt=False)
385
386
386 Both options this constructor are important for things to work
387 Both options this constructor are important for things to work
387 properly in an interactive context.
388 properly in an interactive context.
388
389
389 But, we first check to see if an application has already been
390 But, we first check to see if an application has already been
390 created. If so, we simply return that instance.
391 created. If so, we simply return that instance.
391 """
392 """
392 from IPython.lib.inputhookwx import inputhook_wx
393 from IPython.lib.inputhookwx import inputhook_wx
393 self.set_inputhook(inputhook_wx)
394 self.set_inputhook(inputhook_wx)
394 self._current_gui = GUI_WX
395 self._current_gui = GUI_WX
395 if app:
396 if app:
396 import wx
397 import wx
397 app = wx.GetApp()
398 app = wx.GetApp()
398 if app is None:
399 if app is None:
399 app = wx.App(redirect=False, clearSigInt=False)
400 app = wx.App(redirect=False, clearSigInt=False)
400 self._apps[GUI_WX] = app
401 self._apps[GUI_WX] = app
401 return app
402 return app
402
403
403 def disable_wx(self):
404 def disable_wx(self):
404 """Disable event loop integration with wxPython.
405 """Disable event loop integration with wxPython.
405
406
406 This merely sets PyOS_InputHook to NULL.
407 This merely sets PyOS_InputHook to NULL.
407 """
408 """
408 self.clear_inputhook()
409 self.clear_inputhook()
409
410
410 def enable_qt4(self, app=False):
411 def enable_qt4(self, app=False):
411 """Enable event loop integration with PyQt4.
412 """Enable event loop integration with PyQt4.
412
413
413 Parameters
414 Parameters
414 ----------
415 ----------
415 app : bool
416 app : bool
416 Create a running application object or not.
417 Create a running application object or not.
417
418
418 Notes
419 Notes
419 -----
420 -----
420 This methods sets the PyOS_InputHook for PyQt4, which allows
421 This methods sets the PyOS_InputHook for PyQt4, which allows
421 the PyQt4 to integrate with terminal based applications like
422 the PyQt4 to integrate with terminal based applications like
422 IPython.
423 IPython.
423
424
424 If ``app`` is True, we create an :class:`QApplication` as follows::
425 If ``app`` is True, we create an :class:`QApplication` as follows::
425
426
426 from PyQt4 import QtCore
427 from PyQt4 import QtCore
427 app = QtGui.QApplication(sys.argv)
428 app = QtGui.QApplication(sys.argv)
428
429
429 But, we first check to see if an application has already been
430 But, we first check to see if an application has already been
430 created. If so, we simply return that instance.
431 created. If so, we simply return that instance.
431 """
432 """
432 from PyQt4 import QtCore
433 from PyQt4 import QtCore
433 # PyQt4 has had this since 4.3.1. In version 4.2, PyOS_InputHook
434 # PyQt4 has had this since 4.3.1. In version 4.2, PyOS_InputHook
434 # was set when QtCore was imported, but if it ever got removed,
435 # was set when QtCore was imported, but if it ever got removed,
435 # you couldn't reset it. For earlier versions we can
436 # you couldn't reset it. For earlier versions we can
436 # probably implement a ctypes version.
437 # probably implement a ctypes version.
437 try:
438 try:
438 QtCore.pyqtRestoreInputHook()
439 QtCore.pyqtRestoreInputHook()
439 except AttributeError:
440 except AttributeError:
440 pass
441 pass
441 self._current_gui = GUI_QT4
442 self._current_gui = GUI_QT4
442 if app:
443 if app:
443 from PyQt4 import QtGui
444 from PyQt4 import QtGui
444 app = QtCore.QCoreApplication.instance()
445 app = QtCore.QCoreApplication.instance()
445 if app is None:
446 if app is None:
446 app = QtGui.QApplication(sys.argv)
447 app = QtGui.QApplication(sys.argv)
447 self._apps[GUI_QT4] = app
448 self._apps[GUI_QT4] = app
448 return app
449 return app
449
450
450 def disable_qt4(self):
451 def disable_qt4(self):
451 """Disable event loop integration with PyQt4.
452 """Disable event loop integration with PyQt4.
452
453
453 This merely sets PyOS_InputHook to NULL.
454 This merely sets PyOS_InputHook to NULL.
454 """
455 """
455 self.clear_inputhook()
456 self.clear_inputhook()
456
457
457 def enable_gtk(self, app=False):
458 def enable_gtk(self, app=False):
458 """Enable event loop integration with PyGTK.
459 """Enable event loop integration with PyGTK.
459
460
460 Parameters
461 Parameters
461 ----------
462 ----------
462 app : bool
463 app : bool
463 Create a running application object or not. Because gtk does't
464 Create a running application object or not. Because gtk does't
464 have an app class, this does nothing.
465 have an app class, this does nothing.
465
466
466 Notes
467 Notes
467 -----
468 -----
468 This methods sets the PyOS_InputHook for PyGTK, which allows
469 This methods sets the PyOS_InputHook for PyGTK, which allows
469 the PyGTK to integrate with terminal based applications like
470 the PyGTK to integrate with terminal based applications like
470 IPython.
471 IPython.
471 """
472 """
472 import gtk
473 import gtk
473 try:
474 try:
474 gtk.set_interactive(True)
475 gtk.set_interactive(True)
475 self._current_gui = GUI_GTK
476 self._current_gui = GUI_GTK
476 except AttributeError:
477 except AttributeError:
477 # For older versions of gtk, use our own ctypes version
478 # For older versions of gtk, use our own ctypes version
478 from IPython.lib.inputhookgtk import inputhook_gtk
479 from IPython.lib.inputhookgtk import inputhook_gtk
479 self.set_inputhook(inputhook_gtk)
480 self.set_inputhook(inputhook_gtk)
480 self._current_gui = GUI_GTK
481 self._current_gui = GUI_GTK
481
482
482 def disable_gtk(self):
483 def disable_gtk(self):
483 """Disable event loop integration with PyGTK.
484 """Disable event loop integration with PyGTK.
484
485
485 This merely sets PyOS_InputHook to NULL.
486 This merely sets PyOS_InputHook to NULL.
486 """
487 """
487 self.clear_inputhook()
488 self.clear_inputhook()
488
489
489 def enable_tk(self, app=False):
490 def enable_tk(self, app=False):
490 """Enable event loop integration with Tk.
491 """Enable event loop integration with Tk.
491
492
492 Parameters
493 Parameters
493 ----------
494 ----------
494 app : bool
495 app : bool
495 Create a running application object or not.
496 Create a running application object or not.
496
497
497 Notes
498 Notes
498 -----
499 -----
499 Currently this is a no-op as creating a :class:`Tkinter.Tk` object
500 Currently this is a no-op as creating a :class:`Tkinter.Tk` object
500 sets ``PyOS_InputHook``.
501 sets ``PyOS_InputHook``.
501 """
502 """
502 self._current_gui = GUI_TK
503 self._current_gui = GUI_TK
503 if app:
504 if app:
504 import Tkinter
505 import Tkinter
505 app = Tkinter.Tk()
506 app = Tkinter.Tk()
506 app.withdraw()
507 app.withdraw()
507 self._apps[GUI_TK] = app
508 self._apps[GUI_TK] = app
508 return app
509 return app
509
510
510 def disable_tk(self):
511 def disable_tk(self):
511 """Disable event loop integration with Tkinter.
512 """Disable event loop integration with Tkinter.
512
513
513 This merely sets PyOS_InputHook to NULL.
514 This merely sets PyOS_InputHook to NULL.
514 """
515 """
515 self.clear_inputhook()
516 self.clear_inputhook()
516
517
517 def current_gui(self):
518 def current_gui(self):
518 """Return a string indicating the currently active GUI or None."""
519 """Return a string indicating the currently active GUI or None."""
519 return self._current_gui
520 return self._current_gui
520
521
521 inputhook_manager = InputHookManager()
522 inputhook_manager = InputHookManager()
522
523
523 enable_wx = inputhook_manager.enable_wx
524 enable_wx = inputhook_manager.enable_wx
524 disable_wx = inputhook_manager.disable_wx
525 disable_wx = inputhook_manager.disable_wx
525 enable_qt4 = inputhook_manager.enable_qt4
526 enable_qt4 = inputhook_manager.enable_qt4
526 disable_qt4 = inputhook_manager.disable_qt4
527 disable_qt4 = inputhook_manager.disable_qt4
527 enable_gtk = inputhook_manager.enable_gtk
528 enable_gtk = inputhook_manager.enable_gtk
528 disable_gtk = inputhook_manager.disable_gtk
529 disable_gtk = inputhook_manager.disable_gtk
529 enable_tk = inputhook_manager.enable_tk
530 enable_tk = inputhook_manager.enable_tk
530 disable_tk = inputhook_manager.disable_tk
531 disable_tk = inputhook_manager.disable_tk
531 clear_inputhook = inputhook_manager.clear_inputhook
532 clear_inputhook = inputhook_manager.clear_inputhook
532 set_inputhook = inputhook_manager.set_inputhook
533 set_inputhook = inputhook_manager.set_inputhook
533 current_gui = inputhook_manager.current_gui
534 current_gui = inputhook_manager.current_gui
534 clear_app_refs = inputhook_manager.clear_app_refs
535 clear_app_refs = inputhook_manager.clear_app_refs
535 spin = inputhook_manager.spin
536 spin = inputhook_manager.spin
536
537
537
538
538 # Convenience function to switch amongst them
539 # Convenience function to switch amongst them
539 def enable_gui(gui=None, app=True):
540 def enable_gui(gui=None, app=True):
540 """Switch amongst GUI input hooks by name.
541 """Switch amongst GUI input hooks by name.
541
542
542 This is just a utility wrapper around the methods of the InputHookManager
543 This is just a utility wrapper around the methods of the InputHookManager
543 object.
544 object.
544
545
545 Parameters
546 Parameters
546 ----------
547 ----------
547 gui : optional, string or None
548 gui : optional, string or None
548 If None, clears input hook, otherwise it must be one of the recognized
549 If None, clears input hook, otherwise it must be one of the recognized
549 GUI names (see ``GUI_*`` constants in module).
550 GUI names (see ``GUI_*`` constants in module).
550
551
551 app : optional, bool
552 app : optional, bool
552 If true, create an app object and return it.
553 If true, create an app object and return it.
553
554
554 Returns
555 Returns
555 -------
556 -------
556 The output of the underlying gui switch routine, typically the actual
557 The output of the underlying gui switch routine, typically the actual
557 PyOS_InputHook wrapper object or the GUI toolkit app created, if there was
558 PyOS_InputHook wrapper object or the GUI toolkit app created, if there was
558 one.
559 one.
559 """
560 """
560 guis = {None: clear_inputhook,
561 guis = {None: clear_inputhook,
561 GUI_TK: enable_tk,
562 GUI_TK: enable_tk,
562 GUI_GTK: enable_gtk,
563 GUI_GTK: enable_gtk,
563 GUI_WX: enable_wx,
564 GUI_WX: enable_wx,
564 GUI_QT: enable_qt4, # qt3 not supported
565 GUI_QT: enable_qt4, # qt3 not supported
565 GUI_QT4: enable_qt4 }
566 GUI_QT4: enable_qt4 }
566 try:
567 try:
567 gui_hook = guis[gui]
568 gui_hook = guis[gui]
568 except KeyError:
569 except KeyError:
569 e="Invalid GUI request %r, valid ones are:%s" % (gui, guis.keys())
570 e="Invalid GUI request %r, valid ones are:%s" % (gui, guis.keys())
570 raise ValueError(e)
571 raise ValueError(e)
571 return gui_hook(app)
572 return gui_hook(app)
@@ -1,147 +1,179 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities.
2 """Pylab (matplotlib) support utilities.
3
3
4 Authors
4 Authors
5 -------
5 -------
6 Fernando Perez.
6 Fernando Perez.
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2009 The IPython Development Team
10 # Copyright (C) 2009 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 from IPython.utils.decorators import flag_calls
20 from IPython.utils.decorators import flag_calls
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Main classes and functions
23 # Main classes and functions
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 def pylab_activate(user_ns, gui=None, import_all=True):
27 """Activate pylab mode in the user's namespace.
28
26
29 Loads and initializes numpy, matplotlib and friends for interactive use.
27 def find_gui_and_backend(gui=None):
28 """Given a gui string return the gui and mpl backend.
30
29
31 Parameters
30 Parameters
32 ----------
31 ----------
33 user_ns : dict
32 gui : str
34 Namespace where the imports will occur.
33 Can be one of ('tk','gtk','wx','qt','qt4','payload-svg').
35
36 gui : optional, string
37 A valid gui name following the conventions of the %gui magic.
38
39 import_all : optional, boolean
40 If true, an 'import *' is done from numpy and pylab.
41
34
42 Returns
35 Returns
43 -------
36 -------
44 The actual gui used (if not given as input, it was obtained from matplotlib
37 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
45 itself, and will be needed next to configure IPython's gui integration.
38 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_payload_svg').
46 """
39 """
47
40
48 # Initialize matplotlib to interactive mode always
49 import matplotlib
41 import matplotlib
50
42
51 # If user specifies a GUI, that dictates the backend, otherwise we read the
43 # If user specifies a GUI, that dictates the backend, otherwise we read the
52 # user's mpl default from the mpl rc structure
44 # user's mpl default from the mpl rc structure
53 g2b = {'tk': 'TkAgg',
45 g2b = {'tk': 'TkAgg',
54 'gtk': 'GTKAgg',
46 'gtk': 'GTKAgg',
55 'wx': 'WXAgg',
47 'wx': 'WXAgg',
56 'qt': 'Qt4Agg', # qt3 not supported
48 'qt': 'Qt4Agg', # qt3 not supported
57 'qt4': 'Qt4Agg' }
49 'qt4': 'Qt4Agg',
50 'payload-svg' : \
51 'module://IPython.zmq.pylab.backend_payload_svg'}
58
52
59 if gui:
53 if gui:
60 # select backend based on requested gui
54 # select backend based on requested gui
61 backend = g2b[gui]
55 backend = g2b[gui]
62 else:
56 else:
63 backend = matplotlib.rcParams['backend']
57 backend = matplotlib.rcParams['backend']
64 # In this case, we need to find what the appropriate gui selection call
58 # In this case, we need to find what the appropriate gui selection call
65 # should be for IPython, so we can activate inputhook accordingly
59 # should be for IPython, so we can activate inputhook accordingly
66 b2g = dict(zip(g2b.values(),g2b.keys()))
60 b2g = dict(zip(g2b.values(),g2b.keys()))
67 gui = b2g.get(backend, None)
61 gui = b2g.get(backend, None)
62 return gui, backend
63
64
65 def activate_matplotlib(backend):
66 """Activate the given backend and set interactive to True."""
67
68 import matplotlib
69 if backend.startswith('module://'):
70 # Work around bug in matplotlib: matplotlib.use converts the
71 # backend_id to lowercase even if a module name is specified!
72 matplotlib.rcParams['backend'] = backend
73 else:
74 matplotlib.use(backend)
75 matplotlib.interactive(True)
68
76
69 # We must set the desired backend before importing pylab
70 matplotlib.use(backend)
71
72 # This must be imported last in the matplotlib series, after
77 # This must be imported last in the matplotlib series, after
73 # backend/interactivity choices have been made
78 # backend/interactivity choices have been made
74 import matplotlib.pylab as pylab
79 import matplotlib.pylab as pylab
75
80
76 # XXX For now leave this commented out, but depending on discussions with
81 # XXX For now leave this commented out, but depending on discussions with
77 # mpl-dev, we may be able to allow interactive switching...
82 # mpl-dev, we may be able to allow interactive switching...
78 #import matplotlib.pyplot
83 #import matplotlib.pyplot
79 #matplotlib.pyplot.switch_backend(backend)
84 #matplotlib.pyplot.switch_backend(backend)
80
85
81 pylab.show._needmain = False
86 pylab.show._needmain = False
82 # We need to detect at runtime whether show() is called by the user.
87 # We need to detect at runtime whether show() is called by the user.
83 # For this, we wrap it into a decorator which adds a 'called' flag.
88 # For this, we wrap it into a decorator which adds a 'called' flag.
84 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
89 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
85
90
91 def import_pylab(user_ns, import_all=True):
92 """Import the standard pylab symbols into user_ns."""
93
86 # Import numpy as np/pyplot as plt are conventions we're trying to
94 # Import numpy as np/pyplot as plt are conventions we're trying to
87 # somewhat standardize on. Making them available to users by default
95 # somewhat standardize on. Making them available to users by default
88 # will greatly help this.
96 # will greatly help this.
89 exec ("import numpy\n"
97 exec ("import numpy\n"
90 "import matplotlib\n"
98 "import matplotlib\n"
91 "from matplotlib import pylab, mlab, pyplot\n"
99 "from matplotlib import pylab, mlab, pyplot\n"
92 "np = numpy\n"
100 "np = numpy\n"
93 "plt = pyplot\n"
101 "plt = pyplot\n"
94 ) in user_ns
102 ) in user_ns
95
103
96 if import_all:
104 if import_all:
97 exec("from matplotlib.pylab import *\n"
105 exec("from matplotlib.pylab import *\n"
98 "from numpy import *\n") in user_ns
106 "from numpy import *\n") in user_ns
99
107
100 matplotlib.interactive(True)
108
109 def pylab_activate(user_ns, gui=None, import_all=True):
110 """Activate pylab mode in the user's namespace.
111
112 Loads and initializes numpy, matplotlib and friends for interactive use.
113
114 Parameters
115 ----------
116 user_ns : dict
117 Namespace where the imports will occur.
118
119 gui : optional, string
120 A valid gui name following the conventions of the %gui magic.
121
122 import_all : optional, boolean
123 If true, an 'import *' is done from numpy and pylab.
124
125 Returns
126 -------
127 The actual gui used (if not given as input, it was obtained from matplotlib
128 itself, and will be needed next to configure IPython's gui integration.
129 """
130 gui, backend = find_gui_and_backend(gui)
131 activate_matplotlib(backend)
132 import_pylab(user_ns)
101
133
102 print """
134 print """
103 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
135 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
104 For more information, type 'help(pylab)'.""" % backend
136 For more information, type 'help(pylab)'.""" % backend
105
137
106 return gui
138 return gui
107
139
108 # We need a little factory function here to create the closure where
140 # We need a little factory function here to create the closure where
109 # safe_execfile can live.
141 # safe_execfile can live.
110 def mpl_runner(safe_execfile):
142 def mpl_runner(safe_execfile):
111 """Factory to return a matplotlib-enabled runner for %run.
143 """Factory to return a matplotlib-enabled runner for %run.
112
144
113 Parameters
145 Parameters
114 ----------
146 ----------
115 safe_execfile : function
147 safe_execfile : function
116 This must be a function with the same interface as the
148 This must be a function with the same interface as the
117 :meth:`safe_execfile` method of IPython.
149 :meth:`safe_execfile` method of IPython.
118
150
119 Returns
151 Returns
120 -------
152 -------
121 A function suitable for use as the ``runner`` argument of the %run magic
153 A function suitable for use as the ``runner`` argument of the %run magic
122 function.
154 function.
123 """
155 """
124
156
125 def mpl_execfile(fname,*where,**kw):
157 def mpl_execfile(fname,*where,**kw):
126 """matplotlib-aware wrapper around safe_execfile.
158 """matplotlib-aware wrapper around safe_execfile.
127
159
128 Its interface is identical to that of the :func:`execfile` builtin.
160 Its interface is identical to that of the :func:`execfile` builtin.
129
161
130 This is ultimately a call to execfile(), but wrapped in safeties to
162 This is ultimately a call to execfile(), but wrapped in safeties to
131 properly handle interactive rendering."""
163 properly handle interactive rendering."""
132
164
133 import matplotlib
165 import matplotlib
134 import matplotlib.pylab as pylab
166 import matplotlib.pylab as pylab
135
167
136 #print '*** Matplotlib runner ***' # dbg
168 #print '*** Matplotlib runner ***' # dbg
137 # turn off rendering until end of script
169 # turn off rendering until end of script
138 is_interactive = matplotlib.rcParams['interactive']
170 is_interactive = matplotlib.rcParams['interactive']
139 matplotlib.interactive(False)
171 matplotlib.interactive(False)
140 safe_execfile(fname,*where,**kw)
172 safe_execfile(fname,*where,**kw)
141 matplotlib.interactive(is_interactive)
173 matplotlib.interactive(is_interactive)
142 # make rendering call now, if the user tried to do it
174 # make rendering call now, if the user tried to do it
143 if pylab.draw_if_interactive.called:
175 if pylab.draw_if_interactive.called:
144 pylab.draw()
176 pylab.draw()
145 pylab.draw_if_interactive.called = False
177 pylab.draw_if_interactive.called = False
146
178
147 return mpl_execfile
179 return mpl_execfile
@@ -1,196 +1,201 b''
1 """ Defines helper functions for creating kernel entry points and process
1 """ Defines helper functions for creating kernel entry points and process
2 launchers.
2 launchers.
3 """
3 """
4
4
5 # Standard library imports.
5 # Standard library imports.
6 import os
6 import socket
7 import socket
7 from subprocess import Popen
8 from subprocess import Popen
8 import sys
9 import sys
9
10
10 # System library imports.
11 # System library imports.
11 import zmq
12 import zmq
12
13
13 # Local imports.
14 # Local imports.
14 from IPython.core.ultratb import FormattedTB
15 from IPython.core.ultratb import FormattedTB
15 from IPython.external.argparse import ArgumentParser
16 from IPython.external.argparse import ArgumentParser
16 from IPython.utils import io
17 from IPython.utils import io
17 from exitpoller import ExitPollerUnix, ExitPollerWindows
18 from exitpoller import ExitPollerUnix, ExitPollerWindows
18 from displayhook import DisplayHook
19 from displayhook import DisplayHook
19 from iostream import OutStream
20 from iostream import OutStream
20 from session import Session
21 from session import Session
21
22
22
23
23 def bind_port(socket, ip, port):
24 def bind_port(socket, ip, port):
24 """ Binds the specified ZMQ socket. If the port is zero, a random port is
25 """ Binds the specified ZMQ socket. If the port is zero, a random port is
25 chosen. Returns the port that was bound.
26 chosen. Returns the port that was bound.
26 """
27 """
27 connection = 'tcp://%s' % ip
28 connection = 'tcp://%s' % ip
28 if port <= 0:
29 if port <= 0:
29 port = socket.bind_to_random_port(connection)
30 port = socket.bind_to_random_port(connection)
30 else:
31 else:
31 connection += ':%i' % port
32 connection += ':%i' % port
32 socket.bind(connection)
33 socket.bind(connection)
33 return port
34 return port
34
35
35
36
36 def make_argument_parser():
37 def make_argument_parser():
37 """ Creates an ArgumentParser for the generic arguments supported by all
38 """ Creates an ArgumentParser for the generic arguments supported by all
38 kernel entry points.
39 kernel entry points.
39 """
40 """
40 parser = ArgumentParser()
41 parser = ArgumentParser()
41 parser.add_argument('--ip', type=str, default='127.0.0.1',
42 parser.add_argument('--ip', type=str, default='127.0.0.1',
42 help='set the kernel\'s IP address [default: local]')
43 help='set the kernel\'s IP address [default: local]')
43 parser.add_argument('--xrep', type=int, metavar='PORT', default=0,
44 parser.add_argument('--xrep', type=int, metavar='PORT', default=0,
44 help='set the XREP channel port [default: random]')
45 help='set the XREP channel port [default: random]')
45 parser.add_argument('--pub', type=int, metavar='PORT', default=0,
46 parser.add_argument('--pub', type=int, metavar='PORT', default=0,
46 help='set the PUB channel port [default: random]')
47 help='set the PUB channel port [default: random]')
47 parser.add_argument('--req', type=int, metavar='PORT', default=0,
48 parser.add_argument('--req', type=int, metavar='PORT', default=0,
48 help='set the REQ channel port [default: random]')
49 help='set the REQ channel port [default: random]')
49
50
50 if sys.platform == 'win32':
51 if sys.platform == 'win32':
51 parser.add_argument('--parent', type=int, metavar='HANDLE',
52 parser.add_argument('--parent', type=int, metavar='HANDLE',
52 default=0, help='kill this process if the process '
53 default=0, help='kill this process if the process '
53 'with HANDLE dies')
54 'with HANDLE dies')
54 else:
55 else:
55 parser.add_argument('--parent', action='store_true',
56 parser.add_argument('--parent', action='store_true',
56 help='kill this process if its parent dies')
57 help='kill this process if its parent dies')
57
58
58 return parser
59 return parser
59
60
60
61
61 def make_kernel(namespace, kernel_factory,
62 def make_kernel(namespace, kernel_factory,
62 out_stream_factory=None, display_hook_factory=None):
63 out_stream_factory=None, display_hook_factory=None):
63 """ Creates a kernel.
64 """ Creates a kernel.
64 """
65 """
65 # Install minimal exception handling
66 # Install minimal exception handling
66 sys.excepthook = FormattedTB(mode='Verbose', ostream=sys.__stdout__)
67 color_scheme = 'LightBG' if sys.platform == 'darwin' else 'Linux'
68 sys.excepthook = FormattedTB(
69 mode='Verbose', color_scheme=color_scheme, ostream=sys.__stdout__
70 )
67
71
68 # Create a context, a session, and the kernel sockets.
72 # Create a context, a session, and the kernel sockets.
69 io.rprint("Starting the kernel...")
73 io.rprint("Starting the kernel...")
70 context = zmq.Context()
74 context = zmq.Context()
71 session = Session(username=u'kernel')
75 session = Session(username=u'kernel')
72
76
73 reply_socket = context.socket(zmq.XREP)
77 reply_socket = context.socket(zmq.XREP)
74 xrep_port = bind_port(reply_socket, namespace.ip, namespace.xrep)
78 xrep_port = bind_port(reply_socket, namespace.ip, namespace.xrep)
75 io.rprint("XREP Channel on port", xrep_port)
79 io.rprint("XREP Channel on port", xrep_port)
76
80
77 pub_socket = context.socket(zmq.PUB)
81 pub_socket = context.socket(zmq.PUB)
78 pub_port = bind_port(pub_socket, namespace.ip, namespace.pub)
82 pub_port = bind_port(pub_socket, namespace.ip, namespace.pub)
79 io.rprint("PUB Channel on port", pub_port)
83 io.rprint("PUB Channel on port", pub_port)
80
84
81 req_socket = context.socket(zmq.XREQ)
85 req_socket = context.socket(zmq.XREQ)
82 req_port = bind_port(req_socket, namespace.ip, namespace.req)
86 req_port = bind_port(req_socket, namespace.ip, namespace.req)
83 io.rprint("REQ Channel on port", req_port)
87 io.rprint("REQ Channel on port", req_port)
84
88
85 # Redirect input streams and set a display hook.
89 # Redirect input streams and set a display hook.
86 if out_stream_factory:
90 if out_stream_factory:
91 pass
87 sys.stdout = out_stream_factory(session, pub_socket, u'stdout')
92 sys.stdout = out_stream_factory(session, pub_socket, u'stdout')
88 sys.stderr = out_stream_factory(session, pub_socket, u'stderr')
93 sys.stderr = out_stream_factory(session, pub_socket, u'stderr')
89 if display_hook_factory:
94 if display_hook_factory:
90 sys.displayhook = display_hook_factory(session, pub_socket)
95 sys.displayhook = display_hook_factory(session, pub_socket)
91
96
92 # Create the kernel.
97 # Create the kernel.
93 return kernel_factory(session=session, reply_socket=reply_socket,
98 return kernel_factory(session=session, reply_socket=reply_socket,
94 pub_socket=pub_socket, req_socket=req_socket)
99 pub_socket=pub_socket, req_socket=req_socket)
95
100
96
101
97 def start_kernel(namespace, kernel):
102 def start_kernel(namespace, kernel):
98 """ Starts a kernel.
103 """ Starts a kernel.
99 """
104 """
100 # Configure this kernel/process to die on parent termination, if necessary.
105 # Configure this kernel/process to die on parent termination, if necessary.
101 if namespace.parent:
106 if namespace.parent:
102 if sys.platform == 'win32':
107 if sys.platform == 'win32':
103 poller = ExitPollerWindows(namespace.parent)
108 poller = ExitPollerWindows(namespace.parent)
104 else:
109 else:
105 poller = ExitPollerUnix()
110 poller = ExitPollerUnix()
106 poller.start()
111 poller.start()
107
112
108 # Start the kernel mainloop.
113 # Start the kernel mainloop.
109 kernel.start()
114 kernel.start()
110
115
111
116
112 def make_default_main(kernel_factory):
117 def make_default_main(kernel_factory):
113 """ Creates the simplest possible kernel entry point.
118 """ Creates the simplest possible kernel entry point.
114 """
119 """
115 def main():
120 def main():
116 namespace = make_argument_parser().parse_args()
121 namespace = make_argument_parser().parse_args()
117 kernel = make_kernel(namespace, kernel_factory, OutStream, DisplayHook)
122 kernel = make_kernel(namespace, kernel_factory, OutStream, DisplayHook)
118 start_kernel(namespace, kernel)
123 start_kernel(namespace, kernel)
119 return main
124 return main
120
125
121
126
122 def base_launch_kernel(code, xrep_port=0, pub_port=0, req_port=0,
127 def base_launch_kernel(code, xrep_port=0, pub_port=0, req_port=0,
123 independent=False, extra_arguments=[]):
128 independent=False, extra_arguments=[]):
124 """ Launches a localhost kernel, binding to the specified ports.
129 """ Launches a localhost kernel, binding to the specified ports.
125
130
126 Parameters
131 Parameters
127 ----------
132 ----------
128 code : str,
133 code : str,
129 A string of Python code that imports and executes a kernel entry point.
134 A string of Python code that imports and executes a kernel entry point.
130
135
131 xrep_port : int, optional
136 xrep_port : int, optional
132 The port to use for XREP channel.
137 The port to use for XREP channel.
133
138
134 pub_port : int, optional
139 pub_port : int, optional
135 The port to use for the SUB channel.
140 The port to use for the SUB channel.
136
141
137 req_port : int, optional
142 req_port : int, optional
138 The port to use for the REQ (raw input) channel.
143 The port to use for the REQ (raw input) channel.
139
144
140 independent : bool, optional (default False)
145 independent : bool, optional (default False)
141 If set, the kernel process is guaranteed to survive if this process
146 If set, the kernel process is guaranteed to survive if this process
142 dies. If not set, an effort is made to ensure that the kernel is killed
147 dies. If not set, an effort is made to ensure that the kernel is killed
143 when this process dies. Note that in this case it is still good practice
148 when this process dies. Note that in this case it is still good practice
144 to kill kernels manually before exiting.
149 to kill kernels manually before exiting.
145
150
146 extra_arguments = list, optional
151 extra_arguments = list, optional
147 A list of extra arguments to pass when executing the launch code.
152 A list of extra arguments to pass when executing the launch code.
148
153
149 Returns
154 Returns
150 -------
155 -------
151 A tuple of form:
156 A tuple of form:
152 (kernel_process, xrep_port, pub_port, req_port)
157 (kernel_process, xrep_port, pub_port, req_port)
153 where kernel_process is a Popen object and the ports are integers.
158 where kernel_process is a Popen object and the ports are integers.
154 """
159 """
155 # Find open ports as necessary.
160 # Find open ports as necessary.
156 ports = []
161 ports = []
157 ports_needed = int(xrep_port <= 0) + int(pub_port <= 0) + int(req_port <= 0)
162 ports_needed = int(xrep_port <= 0) + int(pub_port <= 0) + int(req_port <= 0)
158 for i in xrange(ports_needed):
163 for i in xrange(ports_needed):
159 sock = socket.socket()
164 sock = socket.socket()
160 sock.bind(('', 0))
165 sock.bind(('', 0))
161 ports.append(sock)
166 ports.append(sock)
162 for i, sock in enumerate(ports):
167 for i, sock in enumerate(ports):
163 port = sock.getsockname()[1]
168 port = sock.getsockname()[1]
164 sock.close()
169 sock.close()
165 ports[i] = port
170 ports[i] = port
166 if xrep_port <= 0:
171 if xrep_port <= 0:
167 xrep_port = ports.pop(0)
172 xrep_port = ports.pop(0)
168 if pub_port <= 0:
173 if pub_port <= 0:
169 pub_port = ports.pop(0)
174 pub_port = ports.pop(0)
170 if req_port <= 0:
175 if req_port <= 0:
171 req_port = ports.pop(0)
176 req_port = ports.pop(0)
172
177
173 # Build the kernel launch command.
178 # Build the kernel launch command.
174 arguments = [ sys.executable, '-c', code, '--xrep', str(xrep_port),
179 arguments = [ sys.executable, '-c', code, '--xrep', str(xrep_port),
175 '--pub', str(pub_port), '--req', str(req_port) ]
180 '--pub', str(pub_port), '--req', str(req_port) ]
176 arguments.extend(extra_arguments)
181 arguments.extend(extra_arguments)
177
182
178 # Spawn a kernel.
183 # Spawn a kernel.
179 if independent:
184 if independent:
180 if sys.platform == 'win32':
185 if sys.platform == 'win32':
181 proc = Popen(['start', '/b'] + arguments, shell=True)
186 proc = Popen(['start', '/b'] + arguments, shell=True)
182 else:
187 else:
183 proc = Popen(arguments, preexec_fn=lambda: os.setsid())
188 proc = Popen(arguments, preexec_fn=lambda: os.setsid())
184 else:
189 else:
185 if sys.platform == 'win32':
190 if sys.platform == 'win32':
186 from _subprocess import DuplicateHandle, GetCurrentProcess, \
191 from _subprocess import DuplicateHandle, GetCurrentProcess, \
187 DUPLICATE_SAME_ACCESS
192 DUPLICATE_SAME_ACCESS
188 pid = GetCurrentProcess()
193 pid = GetCurrentProcess()
189 handle = DuplicateHandle(pid, pid, pid, 0,
194 handle = DuplicateHandle(pid, pid, pid, 0,
190 True, # Inheritable by new processes.
195 True, # Inheritable by new processes.
191 DUPLICATE_SAME_ACCESS)
196 DUPLICATE_SAME_ACCESS)
192 proc = Popen(arguments + ['--parent', str(int(handle))])
197 proc = Popen(arguments + ['--parent', str(int(handle))])
193 else:
198 else:
194 proc = Popen(arguments + ['--parent'])
199 proc = Popen(arguments + ['--parent'])
195
200
196 return proc, xrep_port, pub_port, req_port
201 return proc, xrep_port, pub_port, req_port
@@ -1,400 +1,456 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.utils.traitlets import Instance
31 from IPython.utils.traitlets import Instance
31 from completer import KernelCompleter
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 # Main kernel class
39 # Main kernel class
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 class Kernel(Configurable):
42 class Kernel(Configurable):
43
43
44 #---------------------------------------------------------------------------
44 #---------------------------------------------------------------------------
45 # Kernel interface
45 # Kernel interface
46 #---------------------------------------------------------------------------
46 #---------------------------------------------------------------------------
47
47
48 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
48 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
49 session = Instance(Session)
49 session = Instance(Session)
50 reply_socket = Instance('zmq.Socket')
50 reply_socket = Instance('zmq.Socket')
51 pub_socket = Instance('zmq.Socket')
51 pub_socket = Instance('zmq.Socket')
52 req_socket = Instance('zmq.Socket')
52 req_socket = Instance('zmq.Socket')
53
53
54 # Maps user-friendly backend names to matplotlib backend identifiers.
55 _pylab_map = { 'tk': 'TkAgg',
56 'gtk': 'GTKAgg',
57 'wx': 'WXAgg',
58 'qt': 'Qt4Agg', # qt3 not supported
59 'qt4': 'Qt4Agg',
60 'payload-svg' : \
61 'module://IPython.zmq.pylab.backend_payload_svg' }
62
63 def __init__(self, **kwargs):
54 def __init__(self, **kwargs):
64 super(Kernel, self).__init__(**kwargs)
55 super(Kernel, self).__init__(**kwargs)
65
56
66 # Initialize the InteractiveShell subclass
57 # Initialize the InteractiveShell subclass
67 self.shell = ZMQInteractiveShell.instance()
58 self.shell = ZMQInteractiveShell.instance()
68 self.shell.displayhook.session = self.session
59 self.shell.displayhook.session = self.session
69 self.shell.displayhook.pub_socket = self.pub_socket
60 self.shell.displayhook.pub_socket = self.pub_socket
70
61
71 # TMP - hack while developing
62 # TMP - hack while developing
72 self.shell._reply_content = None
63 self.shell._reply_content = None
73
64
74 # Build dict of handlers for message types
65 # Build dict of handlers for message types
75 msg_types = [ 'execute_request', 'complete_request',
66 msg_types = [ 'execute_request', 'complete_request',
76 'object_info_request', 'prompt_request',
67 'object_info_request', 'prompt_request',
77 'history_request' ]
68 'history_request' ]
78 self.handlers = {}
69 self.handlers = {}
79 for msg_type in msg_types:
70 for msg_type in msg_types:
80 self.handlers[msg_type] = getattr(self, msg_type)
71 self.handlers[msg_type] = getattr(self, msg_type)
81
72
82 def activate_pylab(self, backend=None, import_all=True):
73 def do_one_iteration(self):
83 """ Activates pylab in this kernel's namespace.
74 try:
84
75 ident = self.reply_socket.recv(zmq.NOBLOCK)
85 Parameters:
76 except zmq.ZMQError, e:
86 -----------
77 if e.errno == zmq.EAGAIN:
87 backend : str, optional
78 return
88 A valid backend name.
89
90 import_all : bool, optional
91 If true, an 'import *' is done from numpy and pylab.
92 """
93 # FIXME: This is adapted from IPython.lib.pylabtools.pylab_activate.
94 # Common functionality should be refactored.
95
96 # We must set the desired backend before importing pylab.
97 import matplotlib
98 if backend:
99 backend_id = self._pylab_map[backend]
100 if backend_id.startswith('module://'):
101 # Work around bug in matplotlib: matplotlib.use converts the
102 # backend_id to lowercase even if a module name is specified!
103 matplotlib.rcParams['backend'] = backend_id
104 else:
79 else:
105 matplotlib.use(backend_id)
80 raise
106
81 # FIXME: Bug in pyzmq/zmq?
107 # Import numpy as np/pyplot as plt are conventions we're trying to
82 # assert self.reply_socket.rcvmore(), "Missing message part."
108 # somewhat standardize on. Making them available to users by default
83 msg = self.reply_socket.recv_json()
109 # will greatly help this.
84 omsg = Message(msg)
110 exec ("import numpy\n"
85 io.rprint('\n')
111 "import matplotlib\n"
86 io.rprint(omsg)
112 "from matplotlib import pylab, mlab, pyplot\n"
87 handler = self.handlers.get(omsg.msg_type, None)
113 "np = numpy\n"
88 if handler is None:
114 "plt = pyplot\n"
89 io.rprinte("UNKNOWN MESSAGE TYPE:", omsg)
115 ) in self.shell.user_ns
90 else:
116
91 handler(ident, omsg)
117 if import_all:
118 exec("from matplotlib.pylab import *\n"
119 "from numpy import *\n") in self.shell.user_ns
120
121 matplotlib.interactive(True)
122
92
123 def start(self):
93 def start(self):
124 """ Start the kernel main loop.
94 """ Start the kernel main loop.
125 """
95 """
126 while True:
96 while True:
127 ident = self.reply_socket.recv()
97 time.sleep(0.05)
128 assert self.reply_socket.rcvmore(), "Missing message part."
98 self.do_one_iteration()
129 msg = self.reply_socket.recv_json()
99
130 omsg = Message(msg)
131 io.rprint('\n', omsg)
132 handler = self.handlers.get(omsg.msg_type, None)
133 if handler is None:
134 io.rprinte("UNKNOWN MESSAGE TYPE:", omsg)
135 else:
136 handler(ident, omsg)
137
100
138 #---------------------------------------------------------------------------
101 #---------------------------------------------------------------------------
139 # Kernel request handlers
102 # Kernel request handlers
140 #---------------------------------------------------------------------------
103 #---------------------------------------------------------------------------
141
104
142 def execute_request(self, ident, parent):
105 def execute_request(self, ident, parent):
143 try:
106 try:
144 code = parent[u'content'][u'code']
107 code = parent[u'content'][u'code']
145 except:
108 except:
146 io.rprinte("Got bad msg: ")
109 io.rprinte("Got bad msg: ")
147 io.rprinte(Message(parent))
110 io.rprinte(Message(parent))
148 return
111 return
149 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
112 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
150 self.pub_socket.send_json(pyin_msg)
113 self.pub_socket.send_json(pyin_msg)
151
114
152 try:
115 try:
153 # Replace raw_input. Note that is not sufficient to replace
116 # Replace raw_input. Note that is not sufficient to replace
154 # raw_input in the user namespace.
117 # raw_input in the user namespace.
155 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
118 raw_input = lambda prompt='': self._raw_input(prompt, ident, parent)
156 __builtin__.raw_input = raw_input
119 __builtin__.raw_input = raw_input
157
120
158 # Set the parent message of the display hook and out streams.
121 # Set the parent message of the display hook and out streams.
159 self.shell.displayhook.set_parent(parent)
122 self.shell.displayhook.set_parent(parent)
160 sys.stdout.set_parent(parent)
123 sys.stdout.set_parent(parent)
161 sys.stderr.set_parent(parent)
124 sys.stderr.set_parent(parent)
162
125
163 # FIXME: runlines calls the exception handler itself. We should
126 # FIXME: runlines calls the exception handler itself. We should
164 # clean this up.
127 # clean this up.
165 self.shell._reply_content = None
128 self.shell._reply_content = None
166 self.shell.runlines(code)
129 self.shell.runlines(code)
167 except:
130 except:
168 # FIXME: this code right now isn't being used yet by default,
131 # FIXME: this code right now isn't being used yet by default,
169 # because the runlines() call above directly fires off exception
132 # because the runlines() call above directly fires off exception
170 # reporting. This code, therefore, is only active in the scenario
133 # reporting. This code, therefore, is only active in the scenario
171 # where runlines itself has an unhandled exception. We need to
134 # where runlines itself has an unhandled exception. We need to
172 # uniformize this, for all exception construction to come from a
135 # uniformize this, for all exception construction to come from a
173 # single location in the codbase.
136 # single location in the codbase.
174 etype, evalue, tb = sys.exc_info()
137 etype, evalue, tb = sys.exc_info()
175 tb_list = traceback.format_exception(etype, evalue, tb)
138 tb_list = traceback.format_exception(etype, evalue, tb)
176 reply_content = self.shell._showtraceback(etype, evalue, tb_list)
139 reply_content = self.shell._showtraceback(etype, evalue, tb_list)
177 else:
140 else:
178 payload = self.shell.payload_manager.read_payload()
141 payload = self.shell.payload_manager.read_payload()
179 # Be agressive about clearing the payload because we don't want
142 # Be agressive about clearing the payload because we don't want
180 # it to sit in memory until the next execute_request comes in.
143 # it to sit in memory until the next execute_request comes in.
181 self.shell.payload_manager.clear_payload()
144 self.shell.payload_manager.clear_payload()
182 reply_content = { 'status' : 'ok', 'payload' : payload }
145 reply_content = { 'status' : 'ok', 'payload' : payload }
183
146
184 # Compute the prompt information
147 # Compute the prompt information
185 prompt_number = self.shell.displayhook.prompt_count
148 prompt_number = self.shell.displayhook.prompt_count
186 reply_content['prompt_number'] = prompt_number
149 reply_content['prompt_number'] = prompt_number
187 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
150 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
188 next_prompt = {'prompt_string' : prompt_string,
151 next_prompt = {'prompt_string' : prompt_string,
189 'prompt_number' : prompt_number+1,
152 'prompt_number' : prompt_number+1,
190 'input_sep' : self.shell.displayhook.input_sep}
153 'input_sep' : self.shell.displayhook.input_sep}
191 reply_content['next_prompt'] = next_prompt
154 reply_content['next_prompt'] = next_prompt
192
155
193 # TMP - fish exception info out of shell, possibly left there by
156 # TMP - fish exception info out of shell, possibly left there by
194 # runlines
157 # runlines
195 if self.shell._reply_content is not None:
158 if self.shell._reply_content is not None:
196 reply_content.update(self.shell._reply_content)
159 reply_content.update(self.shell._reply_content)
197
160
198 # Flush output before sending the reply.
161 # Flush output before sending the reply.
199 sys.stderr.flush()
162 sys.stderr.flush()
200 sys.stdout.flush()
163 sys.stdout.flush()
201
164
202 # Send the reply.
165 # Send the reply.
203 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
166 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
204 io.rprint(Message(reply_msg))
167 io.rprint(Message(reply_msg))
205 self.reply_socket.send(ident, zmq.SNDMORE)
168 self.reply_socket.send(ident, zmq.SNDMORE)
206 self.reply_socket.send_json(reply_msg)
169 self.reply_socket.send_json(reply_msg)
207 if reply_msg['content']['status'] == u'error':
170 if reply_msg['content']['status'] == u'error':
208 self._abort_queue()
171 self._abort_queue()
209
172
210 def complete_request(self, ident, parent):
173 def complete_request(self, ident, parent):
211 txt, matches = self._complete(parent)
174 txt, matches = self._complete(parent)
212 matches = {'matches' : matches,
175 matches = {'matches' : matches,
213 'matched_text' : txt,
176 'matched_text' : txt,
214 'status' : 'ok'}
177 'status' : 'ok'}
215 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
178 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
216 matches, parent, ident)
179 matches, parent, ident)
217 io.rprint(completion_msg)
180 io.rprint(completion_msg)
218
181
219 def object_info_request(self, ident, parent):
182 def object_info_request(self, ident, parent):
220 context = parent['content']['oname'].split('.')
183 context = parent['content']['oname'].split('.')
221 object_info = self._object_info(context)
184 object_info = self._object_info(context)
222 msg = self.session.send(self.reply_socket, 'object_info_reply',
185 msg = self.session.send(self.reply_socket, 'object_info_reply',
223 object_info, parent, ident)
186 object_info, parent, ident)
224 io.rprint(msg)
187 io.rprint(msg)
225
188
226 def prompt_request(self, ident, parent):
189 def prompt_request(self, ident, parent):
227 prompt_number = self.shell.displayhook.prompt_count
190 prompt_number = self.shell.displayhook.prompt_count
228 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
191 prompt_string = self.shell.displayhook.prompt1.peek_next_prompt()
229 content = {'prompt_string' : prompt_string,
192 content = {'prompt_string' : prompt_string,
230 'prompt_number' : prompt_number+1,
193 'prompt_number' : prompt_number+1,
231 'input_sep' : self.shell.displayhook.input_sep}
194 'input_sep' : self.shell.displayhook.input_sep}
232 msg = self.session.send(self.reply_socket, 'prompt_reply',
195 msg = self.session.send(self.reply_socket, 'prompt_reply',
233 content, parent, ident)
196 content, parent, ident)
234 io.rprint(msg)
197 io.rprint(msg)
235
198
236 def history_request(self, ident, parent):
199 def history_request(self, ident, parent):
237 output = parent['content']['output']
200 output = parent['content']['output']
238 index = parent['content']['index']
201 index = parent['content']['index']
239 raw = parent['content']['raw']
202 raw = parent['content']['raw']
240 hist = self.shell.get_history(index=index, raw=raw, output=output)
203 hist = self.shell.get_history(index=index, raw=raw, output=output)
241 content = {'history' : hist}
204 content = {'history' : hist}
242 msg = self.session.send(self.reply_socket, 'history_reply',
205 msg = self.session.send(self.reply_socket, 'history_reply',
243 content, parent, ident)
206 content, parent, ident)
244 io.rprint(msg)
207 io.rprint(msg)
245
208
246 #---------------------------------------------------------------------------
209 #---------------------------------------------------------------------------
247 # Protected interface
210 # Protected interface
248 #---------------------------------------------------------------------------
211 #---------------------------------------------------------------------------
249
212
250 def _abort_queue(self):
213 def _abort_queue(self):
251 while True:
214 while True:
252 try:
215 try:
253 ident = self.reply_socket.recv(zmq.NOBLOCK)
216 ident = self.reply_socket.recv(zmq.NOBLOCK)
254 except zmq.ZMQError, e:
217 except zmq.ZMQError, e:
255 if e.errno == zmq.EAGAIN:
218 if e.errno == zmq.EAGAIN:
256 break
219 break
257 else:
220 else:
258 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
221 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
259 msg = self.reply_socket.recv_json()
222 msg = self.reply_socket.recv_json()
260 io.rprint("Aborting:\n", Message(msg))
223 io.rprint("Aborting:\n", Message(msg))
261 msg_type = msg['msg_type']
224 msg_type = msg['msg_type']
262 reply_type = msg_type.split('_')[0] + '_reply'
225 reply_type = msg_type.split('_')[0] + '_reply'
263 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
226 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
264 io.rprint(Message(reply_msg))
227 io.rprint(Message(reply_msg))
265 self.reply_socket.send(ident,zmq.SNDMORE)
228 self.reply_socket.send(ident,zmq.SNDMORE)
266 self.reply_socket.send_json(reply_msg)
229 self.reply_socket.send_json(reply_msg)
267 # We need to wait a bit for requests to come in. This can probably
230 # We need to wait a bit for requests to come in. This can probably
268 # be set shorter for true asynchronous clients.
231 # be set shorter for true asynchronous clients.
269 time.sleep(0.1)
232 time.sleep(0.1)
270
233
271 def _raw_input(self, prompt, ident, parent):
234 def _raw_input(self, prompt, ident, parent):
272 # Flush output before making the request.
235 # Flush output before making the request.
273 sys.stderr.flush()
236 sys.stderr.flush()
274 sys.stdout.flush()
237 sys.stdout.flush()
275
238
276 # Send the input request.
239 # Send the input request.
277 content = dict(prompt=prompt)
240 content = dict(prompt=prompt)
278 msg = self.session.msg(u'input_request', content, parent)
241 msg = self.session.msg(u'input_request', content, parent)
279 self.req_socket.send_json(msg)
242 self.req_socket.send_json(msg)
280
243
281 # Await a response.
244 # Await a response.
282 reply = self.req_socket.recv_json()
245 reply = self.req_socket.recv_json()
283 try:
246 try:
284 value = reply['content']['value']
247 value = reply['content']['value']
285 except:
248 except:
286 io.rprinte("Got bad raw_input reply: ")
249 io.rprinte("Got bad raw_input reply: ")
287 io.rprinte(Message(parent))
250 io.rprinte(Message(parent))
288 value = ''
251 value = ''
289 return value
252 return value
290
253
291 def _complete(self, msg):
254 def _complete(self, msg):
292 c = msg['content']
255 c = msg['content']
293 try:
256 try:
294 cpos = int(c['cursor_pos'])
257 cpos = int(c['cursor_pos'])
295 except:
258 except:
296 # If we don't get something that we can convert to an integer, at
259 # If we don't get something that we can convert to an integer, at
297 # least attempt the completion guessing the cursor is at the end of
260 # least attempt the completion guessing the cursor is at the end of
298 # the text, if there's any, and otherwise of the line
261 # the text, if there's any, and otherwise of the line
299 cpos = len(c['text'])
262 cpos = len(c['text'])
300 if cpos==0:
263 if cpos==0:
301 cpos = len(c['line'])
264 cpos = len(c['line'])
302 return self.shell.complete(c['text'], c['line'], cpos)
265 return self.shell.complete(c['text'], c['line'], cpos)
303
266
304 def _object_info(self, context):
267 def _object_info(self, context):
305 symbol, leftover = self._symbol_from_context(context)
268 symbol, leftover = self._symbol_from_context(context)
306 if symbol is not None and not leftover:
269 if symbol is not None and not leftover:
307 doc = getattr(symbol, '__doc__', '')
270 doc = getattr(symbol, '__doc__', '')
308 else:
271 else:
309 doc = ''
272 doc = ''
310 object_info = dict(docstring = doc)
273 object_info = dict(docstring = doc)
311 return object_info
274 return object_info
312
275
313 def _symbol_from_context(self, context):
276 def _symbol_from_context(self, context):
314 if not context:
277 if not context:
315 return None, context
278 return None, context
316
279
317 base_symbol_string = context[0]
280 base_symbol_string = context[0]
318 symbol = self.shell.user_ns.get(base_symbol_string, None)
281 symbol = self.shell.user_ns.get(base_symbol_string, None)
319 if symbol is None:
282 if symbol is None:
320 symbol = __builtin__.__dict__.get(base_symbol_string, None)
283 symbol = __builtin__.__dict__.get(base_symbol_string, None)
321 if symbol is None:
284 if symbol is None:
322 return None, context
285 return None, context
323
286
324 context = context[1:]
287 context = context[1:]
325 for i, name in enumerate(context):
288 for i, name in enumerate(context):
326 new_symbol = getattr(symbol, name, None)
289 new_symbol = getattr(symbol, name, None)
327 if new_symbol is None:
290 if new_symbol is None:
328 return symbol, context[i:]
291 return symbol, context[i:]
329 else:
292 else:
330 symbol = new_symbol
293 symbol = new_symbol
331
294
332 return symbol, []
295 return symbol, []
333
296
297
298 class QtKernel(Kernel):
299 """A Kernel subclass with Qt support."""
300
301 def start(self):
302 """Start a kernel with QtPy4 event loop integration."""
303
304 from PyQt4 import QtGui, QtCore
305 self.app = QtGui.QApplication([])
306 self.app.setQuitOnLastWindowClosed (False)
307 self.timer = QtCore.QTimer()
308 self.timer.timeout.connect(self.do_one_iteration)
309 self.timer.start(50)
310 self.app.exec_()
311
312
313 class WxKernel(Kernel):
314 """A Kernel subclass with Wx support."""
315
316 def start(self):
317 """Start a kernel with wx event loop support."""
318
319 import wx
320 doi = self.do_one_iteration
321
322 # We have to put the wx.Timer in a wx.Frame for it to fire properly.
323 # We make the Frame hidden when we create it in the main app below.
324 class TimerFrame(wx.Frame):
325 def __init__(self, func):
326 wx.Frame.__init__(self, None, -1)
327 self.timer = wx.Timer(self)
328 self.timer.Start(50)
329 self.Bind(wx.EVT_TIMER, self.on_timer)
330 self.func = func
331 def on_timer(self, event):
332 self.func()
333
334 # We need a custom wx.App to create our Frame subclass that has the
335 # wx.Timer to drive the ZMQ event loop.
336 class IPWxApp(wx.App):
337 def OnInit(self):
338 self.frame = TimerFrame(doi)
339 self.frame.Show(False)
340 return True
341
342 # The redirect=False here makes sure that wx doesn't replace
343 # sys.stdout/stderr with its own classes.
344 self.app = IPWxApp(redirect=False)
345 self.app.MainLoop()
346
347
348 class TkKernel(Kernel):
349 """A Kernel subclass with Tk support."""
350
351 def start(self):
352 """Start a Tk enabled event loop."""
353
354 import Tkinter
355 doi = self.do_one_iteration
356
357 # For Tkinter, we create a Tk object and call its withdraw method.
358 class Timer(object):
359 def __init__(self, func):
360 self.app = Tkinter.Tk()
361 self.app.withdraw()
362 self.func = func
363 def on_timer(self):
364 self.func()
365 self.app.after(50, self.on_timer)
366 def start(self):
367 self.on_timer() # Call it once to get things going.
368 self.app.mainloop()
369
370 self.timer = Timer(doi)
371 self.timer.start()
372
334 #-----------------------------------------------------------------------------
373 #-----------------------------------------------------------------------------
335 # Kernel main and launch functions
374 # Kernel main and launch functions
336 #-----------------------------------------------------------------------------
375 #-----------------------------------------------------------------------------
337
376
338 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False,
377 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False,
339 pylab=False):
378 pylab=False):
340 """ Launches a localhost kernel, binding to the specified ports.
379 """ Launches a localhost kernel, binding to the specified ports.
341
380
342 Parameters
381 Parameters
343 ----------
382 ----------
344 xrep_port : int, optional
383 xrep_port : int, optional
345 The port to use for XREP channel.
384 The port to use for XREP channel.
346
385
347 pub_port : int, optional
386 pub_port : int, optional
348 The port to use for the SUB channel.
387 The port to use for the SUB channel.
349
388
350 req_port : int, optional
389 req_port : int, optional
351 The port to use for the REQ (raw input) channel.
390 The port to use for the REQ (raw input) channel.
352
391
353 independent : bool, optional (default False)
392 independent : bool, optional (default False)
354 If set, the kernel process is guaranteed to survive if this process
393 If set, the kernel process is guaranteed to survive if this process
355 dies. If not set, an effort is made to ensure that the kernel is killed
394 dies. If not set, an effort is made to ensure that the kernel is killed
356 when this process dies. Note that in this case it is still good practice
395 when this process dies. Note that in this case it is still good practice
357 to kill kernels manually before exiting.
396 to kill kernels manually before exiting.
358
397
359 pylab : bool or string, optional (default False)
398 pylab : bool or string, optional (default False)
360 If not False, the kernel will be launched with pylab enabled. If a
399 If not False, the kernel will be launched with pylab enabled. If a
361 string is passed, matplotlib will use the specified backend. Otherwise,
400 string is passed, matplotlib will use the specified backend. Otherwise,
362 matplotlib's default backend will be used.
401 matplotlib's default backend will be used.
363
402
364 Returns
403 Returns
365 -------
404 -------
366 A tuple of form:
405 A tuple of form:
367 (kernel_process, xrep_port, pub_port, req_port)
406 (kernel_process, xrep_port, pub_port, req_port)
368 where kernel_process is a Popen object and the ports are integers.
407 where kernel_process is a Popen object and the ports are integers.
369 """
408 """
370 extra_arguments = []
409 extra_arguments = []
371 if pylab:
410 if pylab:
372 extra_arguments.append('--pylab')
411 extra_arguments.append('--pylab')
373 if isinstance(pylab, basestring):
412 if isinstance(pylab, basestring):
374 extra_arguments.append(pylab)
413 extra_arguments.append(pylab)
375 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
414 return base_launch_kernel('from IPython.zmq.ipkernel import main; main()',
376 xrep_port, pub_port, req_port, independent,
415 xrep_port, pub_port, req_port, independent,
377 extra_arguments)
416 extra_arguments)
378
417
379 def main():
418 def main():
380 """ The IPython kernel main entry point.
419 """ The IPython kernel main entry point.
381 """
420 """
382 parser = make_argument_parser()
421 parser = make_argument_parser()
383 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
422 parser.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
384 const='auto', help = \
423 const='auto', help = \
385 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
424 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
386 given, the GUI backend is matplotlib's, otherwise use one of: \
425 given, the GUI backend is matplotlib's, otherwise use one of: \
387 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
426 ['tk', 'gtk', 'qt', 'wx', 'payload-svg'].")
388 namespace = parser.parse_args()
427 namespace = parser.parse_args()
389
428
390 kernel = make_kernel(namespace, Kernel, OutStream)
429 kernel_class = Kernel
430
431 _kernel_classes = {
432 'qt' : QtKernel,
433 'qt4' : QtKernel,
434 'payload-svg':Kernel,
435 'wx' : WxKernel,
436 'tk' : TkKernel
437 }
391 if namespace.pylab:
438 if namespace.pylab:
392 if namespace.pylab == 'auto':
439 if namespace.pylab == 'auto':
393 kernel.activate_pylab()
440 gui, backend = pylabtools.find_gui_and_backend()
394 else:
441 else:
395 kernel.activate_pylab(namespace.pylab)
442 gui, backend = pylabtools.find_gui_and_backend(namespace.pylab)
396
443 kernel_class = _kernel_classes.get(gui)
444 if kernel_class is None:
445 raise ValueError('GUI is not supported: %r' % gui)
446 pylabtools.activate_matplotlib(backend)
447
448 kernel = make_kernel(namespace, kernel_class, OutStream)
449
450 if namespace.pylab:
451 pylabtools.import_pylab(kernel.shell.user_ns)
452
397 start_kernel(namespace, kernel)
453 start_kernel(namespace, kernel)
398
454
399 if __name__ == '__main__':
455 if __name__ == '__main__':
400 main()
456 main()
@@ -1,389 +1,389 b''
1 import inspect
1 import inspect
2 import re
2 import re
3 import sys
3 import sys
4 from subprocess import Popen, PIPE
4 from subprocess import Popen, PIPE
5
5
6 from IPython.core.interactiveshell import (
6 from IPython.core.interactiveshell import (
7 InteractiveShell, InteractiveShellABC
7 InteractiveShell, InteractiveShellABC
8 )
8 )
9 from IPython.core.displayhook import DisplayHook
9 from IPython.core.displayhook import DisplayHook
10 from IPython.core.macro import Macro
10 from IPython.core.macro import Macro
11 from IPython.utils.io import rprint
11 from IPython.utils.io import rprint
12 from IPython.utils.path import get_py_filename
12 from IPython.utils.path import get_py_filename
13 from IPython.utils.text import StringTypes
13 from IPython.utils.text import StringTypes
14 from IPython.utils.traitlets import Instance, Type, Dict
14 from IPython.utils.traitlets import Instance, Type, Dict
15 from IPython.utils.warn import warn
15 from IPython.utils.warn import warn
16 from IPython.zmq.session import extract_header
16 from IPython.zmq.session import extract_header
17 from IPython.core.payloadpage import install_payload_page
17 from IPython.core.payloadpage import install_payload_page
18
18 from session import Session
19
19
20 # Install the payload version of page.
20 # Install the payload version of page.
21 install_payload_page()
21 install_payload_page()
22
22
23
23
24 class ZMQDisplayHook(DisplayHook):
24 class ZMQDisplayHook(DisplayHook):
25
25
26 session = Instance('IPython.zmq.session.Session')
26 session = Instance(Session)
27 pub_socket = Instance('zmq.Socket')
27 pub_socket = Instance('zmq.Socket')
28 parent_header = Dict({})
28 parent_header = Dict({})
29
29
30 def set_parent(self, parent):
30 def set_parent(self, parent):
31 """Set the parent for outbound messages."""
31 """Set the parent for outbound messages."""
32 self.parent_header = extract_header(parent)
32 self.parent_header = extract_header(parent)
33
33
34 def start_displayhook(self):
34 def start_displayhook(self):
35 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
35 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
36
36
37 def write_output_prompt(self):
37 def write_output_prompt(self):
38 """Write the output prompt."""
38 """Write the output prompt."""
39 if self.do_full_cache:
39 if self.do_full_cache:
40 self.msg['content']['output_sep'] = self.output_sep
40 self.msg['content']['output_sep'] = self.output_sep
41 self.msg['content']['prompt_string'] = str(self.prompt_out)
41 self.msg['content']['prompt_string'] = str(self.prompt_out)
42 self.msg['content']['prompt_number'] = self.prompt_count
42 self.msg['content']['prompt_number'] = self.prompt_count
43 self.msg['content']['output_sep2'] = self.output_sep2
43 self.msg['content']['output_sep2'] = self.output_sep2
44
44
45 def write_result_repr(self, result_repr):
45 def write_result_repr(self, result_repr):
46 self.msg['content']['data'] = result_repr
46 self.msg['content']['data'] = result_repr
47
47
48 def finish_displayhook(self):
48 def finish_displayhook(self):
49 """Finish up all displayhook activities."""
49 """Finish up all displayhook activities."""
50 self.pub_socket.send_json(self.msg)
50 self.pub_socket.send_json(self.msg)
51 self.msg = None
51 self.msg = None
52
52
53
53
54 class ZMQInteractiveShell(InteractiveShell):
54 class ZMQInteractiveShell(InteractiveShell):
55 """A subclass of InteractiveShell for ZMQ."""
55 """A subclass of InteractiveShell for ZMQ."""
56
56
57 displayhook_class = Type(ZMQDisplayHook)
57 displayhook_class = Type(ZMQDisplayHook)
58
58
59 def system(self, cmd):
59 def system(self, cmd):
60 cmd = self.var_expand(cmd, depth=2)
60 cmd = self.var_expand(cmd, depth=2)
61 sys.stdout.flush()
61 sys.stdout.flush()
62 sys.stderr.flush()
62 sys.stderr.flush()
63 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
63 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
64 for line in p.stdout.read().split('\n'):
64 for line in p.stdout.read().split('\n'):
65 if len(line) > 0:
65 if len(line) > 0:
66 print line
66 print line
67 for line in p.stderr.read().split('\n'):
67 for line in p.stderr.read().split('\n'):
68 if len(line) > 0:
68 if len(line) > 0:
69 print line
69 print line
70 p.wait()
70 p.wait()
71
71
72 def init_io(self):
72 def init_io(self):
73 # This will just use sys.stdout and sys.stderr. If you want to
73 # This will just use sys.stdout and sys.stderr. If you want to
74 # override sys.stdout and sys.stderr themselves, you need to do that
74 # override sys.stdout and sys.stderr themselves, you need to do that
75 # *before* instantiating this class, because Term holds onto
75 # *before* instantiating this class, because Term holds onto
76 # references to the underlying streams.
76 # references to the underlying streams.
77 import IPython.utils.io
77 import IPython.utils.io
78 Term = IPython.utils.io.IOTerm()
78 Term = IPython.utils.io.IOTerm()
79 IPython.utils.io.Term = Term
79 IPython.utils.io.Term = Term
80
80
81 def magic_edit(self,parameter_s='',last_call=['','']):
81 def magic_edit(self,parameter_s='',last_call=['','']):
82 """Bring up an editor and execute the resulting code.
82 """Bring up an editor and execute the resulting code.
83
83
84 Usage:
84 Usage:
85 %edit [options] [args]
85 %edit [options] [args]
86
86
87 %edit runs IPython's editor hook. The default version of this hook is
87 %edit runs IPython's editor hook. The default version of this hook is
88 set to call the __IPYTHON__.rc.editor command. This is read from your
88 set to call the __IPYTHON__.rc.editor command. This is read from your
89 environment variable $EDITOR. If this isn't found, it will default to
89 environment variable $EDITOR. If this isn't found, it will default to
90 vi under Linux/Unix and to notepad under Windows. See the end of this
90 vi under Linux/Unix and to notepad under Windows. See the end of this
91 docstring for how to change the editor hook.
91 docstring for how to change the editor hook.
92
92
93 You can also set the value of this editor via the command line option
93 You can also set the value of this editor via the command line option
94 '-editor' or in your ipythonrc file. This is useful if you wish to use
94 '-editor' or in your ipythonrc file. This is useful if you wish to use
95 specifically for IPython an editor different from your typical default
95 specifically for IPython an editor different from your typical default
96 (and for Windows users who typically don't set environment variables).
96 (and for Windows users who typically don't set environment variables).
97
97
98 This command allows you to conveniently edit multi-line code right in
98 This command allows you to conveniently edit multi-line code right in
99 your IPython session.
99 your IPython session.
100
100
101 If called without arguments, %edit opens up an empty editor with a
101 If called without arguments, %edit opens up an empty editor with a
102 temporary file and will execute the contents of this file when you
102 temporary file and will execute the contents of this file when you
103 close it (don't forget to save it!).
103 close it (don't forget to save it!).
104
104
105
105
106 Options:
106 Options:
107
107
108 -n <number>: open the editor at a specified line number. By default,
108 -n <number>: open the editor at a specified line number. By default,
109 the IPython editor hook uses the unix syntax 'editor +N filename', but
109 the IPython editor hook uses the unix syntax 'editor +N filename', but
110 you can configure this by providing your own modified hook if your
110 you can configure this by providing your own modified hook if your
111 favorite editor supports line-number specifications with a different
111 favorite editor supports line-number specifications with a different
112 syntax.
112 syntax.
113
113
114 -p: this will call the editor with the same data as the previous time
114 -p: this will call the editor with the same data as the previous time
115 it was used, regardless of how long ago (in your current session) it
115 it was used, regardless of how long ago (in your current session) it
116 was.
116 was.
117
117
118 -r: use 'raw' input. This option only applies to input taken from the
118 -r: use 'raw' input. This option only applies to input taken from the
119 user's history. By default, the 'processed' history is used, so that
119 user's history. By default, the 'processed' history is used, so that
120 magics are loaded in their transformed version to valid Python. If
120 magics are loaded in their transformed version to valid Python. If
121 this option is given, the raw input as typed as the command line is
121 this option is given, the raw input as typed as the command line is
122 used instead. When you exit the editor, it will be executed by
122 used instead. When you exit the editor, it will be executed by
123 IPython's own processor.
123 IPython's own processor.
124
124
125 -x: do not execute the edited code immediately upon exit. This is
125 -x: do not execute the edited code immediately upon exit. This is
126 mainly useful if you are editing programs which need to be called with
126 mainly useful if you are editing programs which need to be called with
127 command line arguments, which you can then do using %run.
127 command line arguments, which you can then do using %run.
128
128
129
129
130 Arguments:
130 Arguments:
131
131
132 If arguments are given, the following possibilites exist:
132 If arguments are given, the following possibilites exist:
133
133
134 - The arguments are numbers or pairs of colon-separated numbers (like
134 - The arguments are numbers or pairs of colon-separated numbers (like
135 1 4:8 9). These are interpreted as lines of previous input to be
135 1 4:8 9). These are interpreted as lines of previous input to be
136 loaded into the editor. The syntax is the same of the %macro command.
136 loaded into the editor. The syntax is the same of the %macro command.
137
137
138 - If the argument doesn't start with a number, it is evaluated as a
138 - If the argument doesn't start with a number, it is evaluated as a
139 variable and its contents loaded into the editor. You can thus edit
139 variable and its contents loaded into the editor. You can thus edit
140 any string which contains python code (including the result of
140 any string which contains python code (including the result of
141 previous edits).
141 previous edits).
142
142
143 - If the argument is the name of an object (other than a string),
143 - If the argument is the name of an object (other than a string),
144 IPython will try to locate the file where it was defined and open the
144 IPython will try to locate the file where it was defined and open the
145 editor at the point where it is defined. You can use `%edit function`
145 editor at the point where it is defined. You can use `%edit function`
146 to load an editor exactly at the point where 'function' is defined,
146 to load an editor exactly at the point where 'function' is defined,
147 edit it and have the file be executed automatically.
147 edit it and have the file be executed automatically.
148
148
149 If the object is a macro (see %macro for details), this opens up your
149 If the object is a macro (see %macro for details), this opens up your
150 specified editor with a temporary file containing the macro's data.
150 specified editor with a temporary file containing the macro's data.
151 Upon exit, the macro is reloaded with the contents of the file.
151 Upon exit, the macro is reloaded with the contents of the file.
152
152
153 Note: opening at an exact line is only supported under Unix, and some
153 Note: opening at an exact line is only supported under Unix, and some
154 editors (like kedit and gedit up to Gnome 2.8) do not understand the
154 editors (like kedit and gedit up to Gnome 2.8) do not understand the
155 '+NUMBER' parameter necessary for this feature. Good editors like
155 '+NUMBER' parameter necessary for this feature. Good editors like
156 (X)Emacs, vi, jed, pico and joe all do.
156 (X)Emacs, vi, jed, pico and joe all do.
157
157
158 - If the argument is not found as a variable, IPython will look for a
158 - If the argument is not found as a variable, IPython will look for a
159 file with that name (adding .py if necessary) and load it into the
159 file with that name (adding .py if necessary) and load it into the
160 editor. It will execute its contents with execfile() when you exit,
160 editor. It will execute its contents with execfile() when you exit,
161 loading any code in the file into your interactive namespace.
161 loading any code in the file into your interactive namespace.
162
162
163 After executing your code, %edit will return as output the code you
163 After executing your code, %edit will return as output the code you
164 typed in the editor (except when it was an existing file). This way
164 typed in the editor (except when it was an existing file). This way
165 you can reload the code in further invocations of %edit as a variable,
165 you can reload the code in further invocations of %edit as a variable,
166 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
166 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
167 the output.
167 the output.
168
168
169 Note that %edit is also available through the alias %ed.
169 Note that %edit is also available through the alias %ed.
170
170
171 This is an example of creating a simple function inside the editor and
171 This is an example of creating a simple function inside the editor and
172 then modifying it. First, start up the editor:
172 then modifying it. First, start up the editor:
173
173
174 In [1]: ed
174 In [1]: ed
175 Editing... done. Executing edited code...
175 Editing... done. Executing edited code...
176 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
176 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
177
177
178 We can then call the function foo():
178 We can then call the function foo():
179
179
180 In [2]: foo()
180 In [2]: foo()
181 foo() was defined in an editing session
181 foo() was defined in an editing session
182
182
183 Now we edit foo. IPython automatically loads the editor with the
183 Now we edit foo. IPython automatically loads the editor with the
184 (temporary) file where foo() was previously defined:
184 (temporary) file where foo() was previously defined:
185
185
186 In [3]: ed foo
186 In [3]: ed foo
187 Editing... done. Executing edited code...
187 Editing... done. Executing edited code...
188
188
189 And if we call foo() again we get the modified version:
189 And if we call foo() again we get the modified version:
190
190
191 In [4]: foo()
191 In [4]: foo()
192 foo() has now been changed!
192 foo() has now been changed!
193
193
194 Here is an example of how to edit a code snippet successive
194 Here is an example of how to edit a code snippet successive
195 times. First we call the editor:
195 times. First we call the editor:
196
196
197 In [5]: ed
197 In [5]: ed
198 Editing... done. Executing edited code...
198 Editing... done. Executing edited code...
199 hello
199 hello
200 Out[5]: "print 'hello'n"
200 Out[5]: "print 'hello'n"
201
201
202 Now we call it again with the previous output (stored in _):
202 Now we call it again with the previous output (stored in _):
203
203
204 In [6]: ed _
204 In [6]: ed _
205 Editing... done. Executing edited code...
205 Editing... done. Executing edited code...
206 hello world
206 hello world
207 Out[6]: "print 'hello world'n"
207 Out[6]: "print 'hello world'n"
208
208
209 Now we call it with the output #8 (stored in _8, also as Out[8]):
209 Now we call it with the output #8 (stored in _8, also as Out[8]):
210
210
211 In [7]: ed _8
211 In [7]: ed _8
212 Editing... done. Executing edited code...
212 Editing... done. Executing edited code...
213 hello again
213 hello again
214 Out[7]: "print 'hello again'n"
214 Out[7]: "print 'hello again'n"
215
215
216
216
217 Changing the default editor hook:
217 Changing the default editor hook:
218
218
219 If you wish to write your own editor hook, you can put it in a
219 If you wish to write your own editor hook, you can put it in a
220 configuration file which you load at startup time. The default hook
220 configuration file which you load at startup time. The default hook
221 is defined in the IPython.core.hooks module, and you can use that as a
221 is defined in the IPython.core.hooks module, and you can use that as a
222 starting example for further modifications. That file also has
222 starting example for further modifications. That file also has
223 general instructions on how to set a new hook for use once you've
223 general instructions on how to set a new hook for use once you've
224 defined it."""
224 defined it."""
225
225
226 # FIXME: This function has become a convoluted mess. It needs a
226 # FIXME: This function has become a convoluted mess. It needs a
227 # ground-up rewrite with clean, simple logic.
227 # ground-up rewrite with clean, simple logic.
228
228
229 def make_filename(arg):
229 def make_filename(arg):
230 "Make a filename from the given args"
230 "Make a filename from the given args"
231 try:
231 try:
232 filename = get_py_filename(arg)
232 filename = get_py_filename(arg)
233 except IOError:
233 except IOError:
234 if args.endswith('.py'):
234 if args.endswith('.py'):
235 filename = arg
235 filename = arg
236 else:
236 else:
237 filename = None
237 filename = None
238 return filename
238 return filename
239
239
240 # custom exceptions
240 # custom exceptions
241 class DataIsObject(Exception): pass
241 class DataIsObject(Exception): pass
242
242
243 opts,args = self.parse_options(parameter_s,'prn:')
243 opts,args = self.parse_options(parameter_s,'prn:')
244 # Set a few locals from the options for convenience:
244 # Set a few locals from the options for convenience:
245 opts_p = opts.has_key('p')
245 opts_p = opts.has_key('p')
246 opts_r = opts.has_key('r')
246 opts_r = opts.has_key('r')
247
247
248 # Default line number value
248 # Default line number value
249 lineno = opts.get('n',None)
249 lineno = opts.get('n',None)
250 if lineno is not None:
250 if lineno is not None:
251 try:
251 try:
252 lineno = int(lineno)
252 lineno = int(lineno)
253 except:
253 except:
254 warn("The -n argument must be an integer.")
254 warn("The -n argument must be an integer.")
255 return
255 return
256
256
257 if opts_p:
257 if opts_p:
258 args = '_%s' % last_call[0]
258 args = '_%s' % last_call[0]
259 if not self.shell.user_ns.has_key(args):
259 if not self.shell.user_ns.has_key(args):
260 args = last_call[1]
260 args = last_call[1]
261
261
262 # use last_call to remember the state of the previous call, but don't
262 # use last_call to remember the state of the previous call, but don't
263 # let it be clobbered by successive '-p' calls.
263 # let it be clobbered by successive '-p' calls.
264 try:
264 try:
265 last_call[0] = self.shell.displayhook.prompt_count
265 last_call[0] = self.shell.displayhook.prompt_count
266 if not opts_p:
266 if not opts_p:
267 last_call[1] = parameter_s
267 last_call[1] = parameter_s
268 except:
268 except:
269 pass
269 pass
270
270
271 # by default this is done with temp files, except when the given
271 # by default this is done with temp files, except when the given
272 # arg is a filename
272 # arg is a filename
273 use_temp = 1
273 use_temp = 1
274
274
275 if re.match(r'\d',args):
275 if re.match(r'\d',args):
276 # Mode where user specifies ranges of lines, like in %macro.
276 # Mode where user specifies ranges of lines, like in %macro.
277 # This means that you can't edit files whose names begin with
277 # This means that you can't edit files whose names begin with
278 # numbers this way. Tough.
278 # numbers this way. Tough.
279 ranges = args.split()
279 ranges = args.split()
280 data = ''.join(self.extract_input_slices(ranges,opts_r))
280 data = ''.join(self.extract_input_slices(ranges,opts_r))
281 elif args.endswith('.py'):
281 elif args.endswith('.py'):
282 filename = make_filename(args)
282 filename = make_filename(args)
283 data = ''
283 data = ''
284 use_temp = 0
284 use_temp = 0
285 elif args:
285 elif args:
286 try:
286 try:
287 # Load the parameter given as a variable. If not a string,
287 # Load the parameter given as a variable. If not a string,
288 # process it as an object instead (below)
288 # process it as an object instead (below)
289
289
290 #print '*** args',args,'type',type(args) # dbg
290 #print '*** args',args,'type',type(args) # dbg
291 data = eval(args,self.shell.user_ns)
291 data = eval(args,self.shell.user_ns)
292 if not type(data) in StringTypes:
292 if not type(data) in StringTypes:
293 raise DataIsObject
293 raise DataIsObject
294
294
295 except (NameError,SyntaxError):
295 except (NameError,SyntaxError):
296 # given argument is not a variable, try as a filename
296 # given argument is not a variable, try as a filename
297 filename = make_filename(args)
297 filename = make_filename(args)
298 if filename is None:
298 if filename is None:
299 warn("Argument given (%s) can't be found as a variable "
299 warn("Argument given (%s) can't be found as a variable "
300 "or as a filename." % args)
300 "or as a filename." % args)
301 return
301 return
302
302
303 data = ''
303 data = ''
304 use_temp = 0
304 use_temp = 0
305 except DataIsObject:
305 except DataIsObject:
306
306
307 # macros have a special edit function
307 # macros have a special edit function
308 if isinstance(data,Macro):
308 if isinstance(data,Macro):
309 self._edit_macro(args,data)
309 self._edit_macro(args,data)
310 return
310 return
311
311
312 # For objects, try to edit the file where they are defined
312 # For objects, try to edit the file where they are defined
313 try:
313 try:
314 filename = inspect.getabsfile(data)
314 filename = inspect.getabsfile(data)
315 if 'fakemodule' in filename.lower() and inspect.isclass(data):
315 if 'fakemodule' in filename.lower() and inspect.isclass(data):
316 # class created by %edit? Try to find source
316 # class created by %edit? Try to find source
317 # by looking for method definitions instead, the
317 # by looking for method definitions instead, the
318 # __module__ in those classes is FakeModule.
318 # __module__ in those classes is FakeModule.
319 attrs = [getattr(data, aname) for aname in dir(data)]
319 attrs = [getattr(data, aname) for aname in dir(data)]
320 for attr in attrs:
320 for attr in attrs:
321 if not inspect.ismethod(attr):
321 if not inspect.ismethod(attr):
322 continue
322 continue
323 filename = inspect.getabsfile(attr)
323 filename = inspect.getabsfile(attr)
324 if filename and 'fakemodule' not in filename.lower():
324 if filename and 'fakemodule' not in filename.lower():
325 # change the attribute to be the edit target instead
325 # change the attribute to be the edit target instead
326 data = attr
326 data = attr
327 break
327 break
328
328
329 datafile = 1
329 datafile = 1
330 except TypeError:
330 except TypeError:
331 filename = make_filename(args)
331 filename = make_filename(args)
332 datafile = 1
332 datafile = 1
333 warn('Could not find file where `%s` is defined.\n'
333 warn('Could not find file where `%s` is defined.\n'
334 'Opening a file named `%s`' % (args,filename))
334 'Opening a file named `%s`' % (args,filename))
335 # Now, make sure we can actually read the source (if it was in
335 # Now, make sure we can actually read the source (if it was in
336 # a temp file it's gone by now).
336 # a temp file it's gone by now).
337 if datafile:
337 if datafile:
338 try:
338 try:
339 if lineno is None:
339 if lineno is None:
340 lineno = inspect.getsourcelines(data)[1]
340 lineno = inspect.getsourcelines(data)[1]
341 except IOError:
341 except IOError:
342 filename = make_filename(args)
342 filename = make_filename(args)
343 if filename is None:
343 if filename is None:
344 warn('The file `%s` where `%s` was defined cannot '
344 warn('The file `%s` where `%s` was defined cannot '
345 'be read.' % (filename,data))
345 'be read.' % (filename,data))
346 return
346 return
347 use_temp = 0
347 use_temp = 0
348 else:
348 else:
349 data = ''
349 data = ''
350
350
351 if use_temp:
351 if use_temp:
352 filename = self.shell.mktempfile(data)
352 filename = self.shell.mktempfile(data)
353 print 'IPython will make a temporary file named:',filename
353 print 'IPython will make a temporary file named:',filename
354
354
355 payload = {
355 payload = {
356 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
356 'source' : 'IPython.zmq.zmqshell.ZMQInteractiveShell.edit_magic',
357 'filename' : filename,
357 'filename' : filename,
358 'line_number' : lineno
358 'line_number' : lineno
359 }
359 }
360 self.payload_manager.write_payload(payload)
360 self.payload_manager.write_payload(payload)
361
361
362
362
363 def _showtraceback(self, etype, evalue, stb):
363 def _showtraceback(self, etype, evalue, stb):
364
364
365 exc_content = {
365 exc_content = {
366 u'status' : u'error',
366 u'status' : u'error',
367 u'traceback' : stb,
367 u'traceback' : stb,
368 u'ename' : unicode(etype.__name__),
368 u'ename' : unicode(etype.__name__),
369 u'evalue' : unicode(evalue)
369 u'evalue' : unicode(evalue)
370 }
370 }
371
371
372 dh = self.displayhook
372 dh = self.displayhook
373 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
373 exc_msg = dh.session.msg(u'pyerr', exc_content, dh.parent_header)
374 # Send exception info over pub socket for other clients than the caller
374 # Send exception info over pub socket for other clients than the caller
375 # to pick up
375 # to pick up
376 dh.pub_socket.send_json(exc_msg)
376 dh.pub_socket.send_json(exc_msg)
377
377
378 # FIXME - Hack: store exception info in shell object. Right now, the
378 # FIXME - Hack: store exception info in shell object. Right now, the
379 # caller is reading this info after the fact, we need to fix this logic
379 # caller is reading this info after the fact, we need to fix this logic
380 # to remove this hack.
380 # to remove this hack.
381 self._reply_content = exc_content
381 self._reply_content = exc_content
382 # /FIXME
382 # /FIXME
383
383
384 return exc_content
384 return exc_content
385
385
386 def runlines(self, lines, clean=False):
386 def runlines(self, lines, clean=False):
387 return InteractiveShell.runlines(self, lines, clean)
387 return InteractiveShell.runlines(self, lines, clean)
388
388
389 InteractiveShellABC.register(ZMQInteractiveShell)
389 InteractiveShellABC.register(ZMQInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now