##// END OF EJS Templates
Initial support in ipkernel for proper displayhook handling.
Brian Granger -
Show More
@@ -1,284 +1,289 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Displayhook for IPython.
2 """Displayhook for IPython.
3
3
4 Authors:
4 Authors:
5
5
6 * Fernando Perez
6 * Fernando Perez
7 * Brian Granger
7 * Brian Granger
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2010 The IPython Development Team
11 # Copyright (C) 2008-2010 The IPython Development Team
12 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
12 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import __builtin__
22 import __builtin__
23 from pprint import PrettyPrinter
23 from pprint import PrettyPrinter
24 pformat = PrettyPrinter().pformat
24 pformat = PrettyPrinter().pformat
25
25
26 from IPython.config.configurable import Configurable
26 from IPython.config.configurable import Configurable
27 from IPython.core import prompts
27 from IPython.core import prompts
28 import IPython.utils.generics
28 import IPython.utils.generics
29 import IPython.utils.io
29 import IPython.utils.io
30 from IPython.utils.traitlets import Instance
30 from IPython.utils.traitlets import Instance
31 from IPython.utils.warn import warn
31 from IPython.utils.warn import warn
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Main displayhook class
34 # Main displayhook class
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 # TODO: The DisplayHook class should be split into two classes, one that
37 # TODO: The DisplayHook class should be split into two classes, one that
38 # manages the prompts and their synchronization and another that just does the
38 # manages the prompts and their synchronization and another that just does the
39 # displayhook logic and calls into the prompt manager.
39 # displayhook logic and calls into the prompt manager.
40
40
41 # TODO: Move the various attributes (cache_size, colors, input_sep,
41 # TODO: Move the various attributes (cache_size, colors, input_sep,
42 # output_sep, output_sep2, ps1, ps2, ps_out, pad_left). Some of these are also
42 # output_sep, output_sep2, ps1, ps2, ps_out, pad_left). Some of these are also
43 # attributes of InteractiveShell. They should be on ONE object only and the
43 # attributes of InteractiveShell. They should be on ONE object only and the
44 # other objects should ask that one object for their values.
44 # other objects should ask that one object for their values.
45
45
46 class DisplayHook(Configurable):
46 class DisplayHook(Configurable):
47 """The custom IPython displayhook to replace sys.displayhook.
47 """The custom IPython displayhook to replace sys.displayhook.
48
48
49 This class does many things, but the basic idea is that it is a callable
49 This class does many things, but the basic idea is that it is a callable
50 that gets called anytime user code returns a value.
50 that gets called anytime user code returns a value.
51
51
52 Currently this class does more than just the displayhook logic and that
52 Currently this class does more than just the displayhook logic and that
53 extra logic should eventually be moved out of here.
53 extra logic should eventually be moved out of here.
54 """
54 """
55
55
56 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
56 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
57
57
58 def __init__(self, shell=None, cache_size=1000,
58 def __init__(self, shell=None, cache_size=1000,
59 colors='NoColor', input_sep='\n',
59 colors='NoColor', input_sep='\n',
60 output_sep='\n', output_sep2='',
60 output_sep='\n', output_sep2='',
61 ps1 = None, ps2 = None, ps_out = None, pad_left=True,
61 ps1 = None, ps2 = None, ps_out = None, pad_left=True,
62 config=None):
62 config=None):
63 super(DisplayHook, self).__init__(shell=shell, config=config)
63 super(DisplayHook, self).__init__(shell=shell, config=config)
64
64
65 cache_size_min = 3
65 cache_size_min = 3
66 if cache_size <= 0:
66 if cache_size <= 0:
67 self.do_full_cache = 0
67 self.do_full_cache = 0
68 cache_size = 0
68 cache_size = 0
69 elif cache_size < cache_size_min:
69 elif cache_size < cache_size_min:
70 self.do_full_cache = 0
70 self.do_full_cache = 0
71 cache_size = 0
71 cache_size = 0
72 warn('caching was disabled (min value for cache size is %s).' %
72 warn('caching was disabled (min value for cache size is %s).' %
73 cache_size_min,level=3)
73 cache_size_min,level=3)
74 else:
74 else:
75 self.do_full_cache = 1
75 self.do_full_cache = 1
76
76
77 self.cache_size = cache_size
77 self.cache_size = cache_size
78 self.input_sep = input_sep
78 self.input_sep = input_sep
79
79
80 # we need a reference to the user-level namespace
80 # we need a reference to the user-level namespace
81 self.shell = shell
81 self.shell = shell
82
82
83 # Set input prompt strings and colors
83 # Set input prompt strings and colors
84 if cache_size == 0:
84 if cache_size == 0:
85 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
85 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
86 or ps1.find(r'\N') > -1:
86 or ps1.find(r'\N') > -1:
87 ps1 = '>>> '
87 ps1 = '>>> '
88 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
88 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
89 or ps2.find(r'\N') > -1:
89 or ps2.find(r'\N') > -1:
90 ps2 = '... '
90 ps2 = '... '
91 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
91 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
92 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
92 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
93 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
93 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
94
94
95 self.color_table = prompts.PromptColors
95 self.color_table = prompts.PromptColors
96 self.prompt1 = prompts.Prompt1(self,sep=input_sep,prompt=self.ps1_str,
96 self.prompt1 = prompts.Prompt1(self,sep=input_sep,prompt=self.ps1_str,
97 pad_left=pad_left)
97 pad_left=pad_left)
98 self.prompt2 = prompts.Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
98 self.prompt2 = prompts.Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
99 self.prompt_out = prompts.PromptOut(self,sep='',prompt=self.ps_out_str,
99 self.prompt_out = prompts.PromptOut(self,sep='',prompt=self.ps_out_str,
100 pad_left=pad_left)
100 pad_left=pad_left)
101 self.set_colors(colors)
101 self.set_colors(colors)
102
102
103 # other more normal stuff
103 # other more normal stuff
104 # b/c each call to the In[] prompt raises it by 1, even the first.
104 # b/c each call to the In[] prompt raises it by 1, even the first.
105 self.prompt_count = 0
105 self.prompt_count = 0
106 # Store the last prompt string each time, we need it for aligning
106 # Store the last prompt string each time, we need it for aligning
107 # continuation and auto-rewrite prompts
107 # continuation and auto-rewrite prompts
108 self.last_prompt = ''
108 self.last_prompt = ''
109 self.output_sep = output_sep
109 self.output_sep = output_sep
110 self.output_sep2 = output_sep2
110 self.output_sep2 = output_sep2
111 self._,self.__,self.___ = '','',''
111 self._,self.__,self.___ = '','',''
112 self.pprint_types = map(type,[(),[],{}])
112 self.pprint_types = map(type,[(),[],{}])
113
113
114 # these are deliberately global:
114 # these are deliberately global:
115 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
115 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
116 self.shell.user_ns.update(to_user_ns)
116 self.shell.user_ns.update(to_user_ns)
117
117
118 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
118 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
119 if p_str is None:
119 if p_str is None:
120 if self.do_full_cache:
120 if self.do_full_cache:
121 return cache_def
121 return cache_def
122 else:
122 else:
123 return no_cache_def
123 return no_cache_def
124 else:
124 else:
125 return p_str
125 return p_str
126
126
127 def set_colors(self, colors):
127 def set_colors(self, colors):
128 """Set the active color scheme and configure colors for the three
128 """Set the active color scheme and configure colors for the three
129 prompt subsystems."""
129 prompt subsystems."""
130
130
131 # FIXME: This modifying of the global prompts.prompt_specials needs
131 # FIXME: This modifying of the global prompts.prompt_specials needs
132 # to be fixed. We need to refactor all of the prompts stuff to use
132 # to be fixed. We need to refactor all of the prompts stuff to use
133 # proper configuration and traits notifications.
133 # proper configuration and traits notifications.
134 if colors.lower()=='nocolor':
134 if colors.lower()=='nocolor':
135 prompts.prompt_specials = prompts.prompt_specials_nocolor
135 prompts.prompt_specials = prompts.prompt_specials_nocolor
136 else:
136 else:
137 prompts.prompt_specials = prompts.prompt_specials_color
137 prompts.prompt_specials = prompts.prompt_specials_color
138
138
139 self.color_table.set_active_scheme(colors)
139 self.color_table.set_active_scheme(colors)
140 self.prompt1.set_colors()
140 self.prompt1.set_colors()
141 self.prompt2.set_colors()
141 self.prompt2.set_colors()
142 self.prompt_out.set_colors()
142 self.prompt_out.set_colors()
143
143
144 #-------------------------------------------------------------------------
144 #-------------------------------------------------------------------------
145 # Methods used in __call__. Override these methods to modify the behavior
145 # Methods used in __call__. Override these methods to modify the behavior
146 # of the displayhook.
146 # of the displayhook.
147 #-------------------------------------------------------------------------
147 #-------------------------------------------------------------------------
148
148
149 def check_for_underscore(self):
149 def check_for_underscore(self):
150 """Check if the user has set the '_' variable by hand."""
150 """Check if the user has set the '_' variable by hand."""
151 # If something injected a '_' variable in __builtin__, delete
151 # If something injected a '_' variable in __builtin__, delete
152 # ipython's automatic one so we don't clobber that. gettext() in
152 # ipython's automatic one so we don't clobber that. gettext() in
153 # particular uses _, so we need to stay away from it.
153 # particular uses _, so we need to stay away from it.
154 if '_' in __builtin__.__dict__:
154 if '_' in __builtin__.__dict__:
155 try:
155 try:
156 del self.shell.user_ns['_']
156 del self.shell.user_ns['_']
157 except KeyError:
157 except KeyError:
158 pass
158 pass
159
159
160 def quite(self):
160 def quiet(self):
161 """Should we silence the display hook because of ';'?"""
161 """Should we silence the display hook because of ';'?"""
162 # do not print output if input ends in ';'
162 # do not print output if input ends in ';'
163 try:
163 try:
164 if self.shell.input_hist[self.prompt_count].endswith(';\n'):
164 if self.shell.input_hist[self.prompt_count].endswith(';\n'):
165 return True
165 return True
166 except IndexError:
166 except IndexError:
167 # some uses of ipshellembed may fail here
167 # some uses of ipshellembed may fail here
168 pass
168 pass
169 return False
169 return False
170
170
171 def start_displayhook(self):
172 """Start the displayhook, initializing resources."""
173 pass
174
171 def write_output_prompt(self):
175 def write_output_prompt(self):
172 """Write the output prompt."""
176 """Write the output prompt."""
173 # Use write, not print which adds an extra space.
177 # Use write, not print which adds an extra space.
174 IPython.utils.io.Term.cout.write(self.output_sep)
178 IPython.utils.io.Term.cout.write(self.output_sep)
175 outprompt = str(self.prompt_out)
179 outprompt = str(self.prompt_out)
176 if self.do_full_cache:
180 if self.do_full_cache:
177 IPython.utils.io.Term.cout.write(outprompt)
181 IPython.utils.io.Term.cout.write(outprompt)
178
182
179 # TODO: Make this method an extension point. The previous implementation
183 # TODO: Make this method an extension point. The previous implementation
180 # has both a result_display hook as well as a result_display generic
184 # has both a result_display hook as well as a result_display generic
181 # function to customize the repr on a per class basis. We need to rethink
185 # function to customize the repr on a per class basis. We need to rethink
182 # the hooks mechanism before doing this though.
186 # the hooks mechanism before doing this though.
183 def compute_result_repr(self, result):
187 def compute_result_repr(self, result):
184 """Compute and return the repr of the object to be displayed.
188 """Compute and return the repr of the object to be displayed.
185
189
186 This method only compute the string form of the repr and should NOT
190 This method only compute the string form of the repr and should NOT
187 actual print or write that to a stream. This method may also transform
191 actual print or write that to a stream. This method may also transform
188 the result itself, but the default implementation passes the original
192 the result itself, but the default implementation passes the original
189 through.
193 through.
190 """
194 """
191 try:
195 try:
192 if self.shell.pprint:
196 if self.shell.pprint:
193 result_repr = pformat(result)
197 result_repr = pformat(result)
194 if '\n' in result_repr:
198 if '\n' in result_repr:
195 # So that multi-line strings line up with the left column of
199 # So that multi-line strings line up with the left column of
196 # the screen, instead of having the output prompt mess up
200 # the screen, instead of having the output prompt mess up
197 # their first line.
201 # their first line.
198 result_repr = '\n' + result_repr
202 result_repr = '\n' + result_repr
199 else:
203 else:
200 result_repr = repr(result)
204 result_repr = repr(result)
201 except TypeError:
205 except TypeError:
202 # This happens when result.__repr__ doesn't return a string,
206 # This happens when result.__repr__ doesn't return a string,
203 # such as when it returns None.
207 # such as when it returns None.
204 result_repr = '\n'
208 result_repr = '\n'
205 return result, result_repr
209 return result, result_repr
206
210
207 def write_result_repr(self, result_repr):
211 def write_result_repr(self, result_repr):
208 # We want to print because we want to always make sure we have a
212 # We want to print because we want to always make sure we have a
209 # newline, even if all the prompt separators are ''. This is the
213 # newline, even if all the prompt separators are ''. This is the
210 # standard IPython behavior.
214 # standard IPython behavior.
211 print >>IPython.utils.io.Term.cout, result_repr
215 print >>IPython.utils.io.Term.cout, result_repr
212
216
213 def update_user_ns(self, result):
217 def update_user_ns(self, result):
214 """Update user_ns with various things like _, __, _1, etc."""
218 """Update user_ns with various things like _, __, _1, etc."""
215
219
216 # Avoid recursive reference when displaying _oh/Out
220 # Avoid recursive reference when displaying _oh/Out
217 if result is not self.shell.user_ns['_oh']:
221 if result is not self.shell.user_ns['_oh']:
218 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
222 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
219 warn('Output cache limit (currently '+
223 warn('Output cache limit (currently '+
220 `self.cache_size`+' entries) hit.\n'
224 `self.cache_size`+' entries) hit.\n'
221 'Flushing cache and resetting history counter...\n'
225 'Flushing cache and resetting history counter...\n'
222 'The only history variables available will be _,__,___ and _1\n'
226 'The only history variables available will be _,__,___ and _1\n'
223 'with the current result.')
227 'with the current result.')
224
228
225 self.flush()
229 self.flush()
226 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
230 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
227 # we cause buggy behavior for things like gettext).
231 # we cause buggy behavior for things like gettext).
228 if '_' not in __builtin__.__dict__:
232 if '_' not in __builtin__.__dict__:
229 self.___ = self.__
233 self.___ = self.__
230 self.__ = self._
234 self.__ = self._
231 self._ = result
235 self._ = result
232 self.shell.user_ns.update({'_':self._,'__':self.__,'___':self.___})
236 self.shell.user_ns.update({'_':self._,'__':self.__,'___':self.___})
233
237
234 # hackish access to top-level namespace to create _1,_2... dynamically
238 # hackish access to top-level namespace to create _1,_2... dynamically
235 to_main = {}
239 to_main = {}
236 if self.do_full_cache:
240 if self.do_full_cache:
237 new_result = '_'+`self.prompt_count`
241 new_result = '_'+`self.prompt_count`
238 to_main[new_result] = result
242 to_main[new_result] = result
239 self.shell.user_ns.update(to_main)
243 self.shell.user_ns.update(to_main)
240 self.shell.user_ns['_oh'][self.prompt_count] = result
244 self.shell.user_ns['_oh'][self.prompt_count] = result
241
245
242 def log_output(self, result):
246 def log_output(self, result):
243 """Log the output."""
247 """Log the output."""
244 if self.shell.logger.log_output:
248 if self.shell.logger.log_output:
245 self.shell.logger.log_write(repr(result),'output')
249 self.shell.logger.log_write(repr(result),'output')
246
250
247 def finish_displayhook(self):
251 def finish_displayhook(self):
248 """Finish up all displayhook activities."""
252 """Finish up all displayhook activities."""
249 IPython.utils.io.Term.cout.write(self.output_sep2)
253 IPython.utils.io.Term.cout.write(self.output_sep2)
250 IPython.utils.io.Term.cout.flush()
254 IPython.utils.io.Term.cout.flush()
251
255
252 def __call__(self, result=None):
256 def __call__(self, result=None):
253 """Printing with history cache management.
257 """Printing with history cache management.
254
258
255 This is invoked everytime the interpreter needs to print, and is
259 This is invoked everytime the interpreter needs to print, and is
256 activated by setting the variable sys.displayhook to it.
260 activated by setting the variable sys.displayhook to it.
257 """
261 """
258 self.check_for_underscore()
262 self.check_for_underscore()
259 if result is not None and not self.quite():
263 if result is not None and not self.quiet():
264 self.start_displayhook()
260 self.write_output_prompt()
265 self.write_output_prompt()
261 result, result_repr = self.compute_result_repr(result)
266 result, result_repr = self.compute_result_repr(result)
262 self.write_result_repr(result_repr)
267 self.write_result_repr(result_repr)
263 self.update_user_ns(result)
268 self.update_user_ns(result)
264 self.log_output(result)
269 self.log_output(result)
265 self.finish_displayhook()
270 self.finish_displayhook()
266
271
267 def flush(self):
272 def flush(self):
268 if not self.do_full_cache:
273 if not self.do_full_cache:
269 raise ValueError,"You shouldn't have reached the cache flush "\
274 raise ValueError,"You shouldn't have reached the cache flush "\
270 "if full caching is not enabled!"
275 "if full caching is not enabled!"
271 # delete auto-generated vars from global namespace
276 # delete auto-generated vars from global namespace
272
277
273 for n in range(1,self.prompt_count + 1):
278 for n in range(1,self.prompt_count + 1):
274 key = '_'+`n`
279 key = '_'+`n`
275 try:
280 try:
276 del self.shell.user_ns[key]
281 del self.shell.user_ns[key]
277 except: pass
282 except: pass
278 self.shell.user_ns['_oh'].clear()
283 self.shell.user_ns['_oh'].clear()
279
284
280 if '_' not in __builtin__.__dict__:
285 if '_' not in __builtin__.__dict__:
281 self.shell.user_ns.update({'_':None,'__':None, '___':None})
286 self.shell.user_ns.update({'_':None,'__':None, '___':None})
282 import gc
287 import gc
283 gc.collect() # xxx needed?
288 gc.collect() # xxx needed?
284
289
@@ -1,2060 +1,2063 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.core import debugger, oinspect
32 from IPython.core import debugger, oinspect
33 from IPython.core import history as ipcorehist
33 from IPython.core import history as ipcorehist
34 from IPython.core import prefilter
34 from IPython.core import prefilter
35 from IPython.core import shadowns
35 from IPython.core import shadowns
36 from IPython.core import ultratb
36 from IPython.core import ultratb
37 from IPython.core.alias import AliasManager
37 from IPython.core.alias import AliasManager
38 from IPython.core.builtin_trap import BuiltinTrap
38 from IPython.core.builtin_trap import BuiltinTrap
39 from IPython.config.configurable import Configurable
39 from IPython.config.configurable import Configurable
40 from IPython.core.display_trap import DisplayTrap
40 from IPython.core.display_trap import DisplayTrap
41 from IPython.core.error import UsageError
41 from IPython.core.error import UsageError
42 from IPython.core.extensions import ExtensionManager
42 from IPython.core.extensions import ExtensionManager
43 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
43 from IPython.core.fakemodule import FakeModule, init_fakemod_dict
44 from IPython.core.inputlist import InputList
44 from IPython.core.inputlist import InputList
45 from IPython.core.logger import Logger
45 from IPython.core.logger import Logger
46 from IPython.core.magic import Magic
46 from IPython.core.magic import Magic
47 from IPython.core.plugin import PluginManager
47 from IPython.core.plugin import PluginManager
48 from IPython.core.prefilter import PrefilterManager
48 from IPython.core.prefilter import PrefilterManager
49 from IPython.core.displayhook import DisplayHook
49 from IPython.core.displayhook import DisplayHook
50 import IPython.core.hooks
50 import IPython.core.hooks
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 pickleshare
53 from IPython.utils import pickleshare
54 from IPython.utils.doctestreload import doctest_reload
54 from IPython.utils.doctestreload import doctest_reload
55 from IPython.utils.ipstruct import Struct
55 from IPython.utils.ipstruct import Struct
56 import IPython.utils.io
56 import IPython.utils.io
57 from IPython.utils.io import ask_yes_no
57 from IPython.utils.io import ask_yes_no
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.warn import warn, error, fatal
63 from IPython.utils.warn import warn, error, fatal
64 from IPython.utils.traitlets import (
64 from IPython.utils.traitlets import (
65 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode, Instance
65 Int, Str, CBool, CaselessStrEnum, Enum, List, Unicode, Instance, Type
66 )
66 )
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 class SyntaxTB(ultratb.ListTB):
108 class SyntaxTB(ultratb.ListTB):
109 """Extension which holds some state: the last exception value"""
109 """Extension which holds some state: the last exception value"""
110
110
111 def __init__(self,color_scheme = 'NoColor'):
111 def __init__(self,color_scheme = 'NoColor'):
112 ultratb.ListTB.__init__(self,color_scheme)
112 ultratb.ListTB.__init__(self,color_scheme)
113 self.last_syntax_error = None
113 self.last_syntax_error = None
114
114
115 def __call__(self, etype, value, elist):
115 def __call__(self, etype, value, elist):
116 self.last_syntax_error = value
116 self.last_syntax_error = value
117 ultratb.ListTB.__call__(self,etype,value,elist)
117 ultratb.ListTB.__call__(self,etype,value,elist)
118
118
119 def clear_err_state(self):
119 def clear_err_state(self):
120 """Return the current error state and clear it"""
120 """Return the current error state and clear it"""
121 e = self.last_syntax_error
121 e = self.last_syntax_error
122 self.last_syntax_error = None
122 self.last_syntax_error = None
123 return e
123 return e
124
124
125
125
126 def get_default_colors():
126 def get_default_colors():
127 if sys.platform=='darwin':
127 if sys.platform=='darwin':
128 return "LightBG"
128 return "LightBG"
129 elif os.name=='nt':
129 elif os.name=='nt':
130 return 'Linux'
130 return 'Linux'
131 else:
131 else:
132 return 'Linux'
132 return 'Linux'
133
133
134
134
135 class SeparateStr(Str):
135 class SeparateStr(Str):
136 """A Str subclass to validate separate_in, separate_out, etc.
136 """A Str subclass to validate separate_in, separate_out, etc.
137
137
138 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
138 This is a Str based trait that converts '0'->'' and '\\n'->'\n'.
139 """
139 """
140
140
141 def validate(self, obj, value):
141 def validate(self, obj, value):
142 if value == '0': value = ''
142 if value == '0': value = ''
143 value = value.replace('\\n','\n')
143 value = value.replace('\\n','\n')
144 return super(SeparateStr, self).validate(obj, value)
144 return super(SeparateStr, self).validate(obj, value)
145
145
146
146
147 #-----------------------------------------------------------------------------
147 #-----------------------------------------------------------------------------
148 # Main IPython class
148 # Main IPython class
149 #-----------------------------------------------------------------------------
149 #-----------------------------------------------------------------------------
150
150
151
151
152 class InteractiveShell(Configurable, Magic):
152 class InteractiveShell(Configurable, Magic):
153 """An enhanced, interactive shell for Python."""
153 """An enhanced, interactive shell for Python."""
154
154
155 autocall = Enum((0,1,2), default_value=1, config=True)
155 autocall = Enum((0,1,2), default_value=1, config=True)
156 # TODO: remove all autoindent logic and put into frontends.
156 # TODO: remove all autoindent logic and put into frontends.
157 # We can't do this yet because even runlines uses the autoindent.
157 # We can't do this yet because even runlines uses the autoindent.
158 autoindent = CBool(True, config=True)
158 autoindent = CBool(True, config=True)
159 automagic = CBool(True, config=True)
159 automagic = CBool(True, config=True)
160 cache_size = Int(1000, config=True)
160 cache_size = Int(1000, config=True)
161 color_info = CBool(True, config=True)
161 color_info = CBool(True, config=True)
162 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
162 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
163 default_value=get_default_colors(), config=True)
163 default_value=get_default_colors(), config=True)
164 debug = CBool(False, config=True)
164 debug = CBool(False, config=True)
165 deep_reload = CBool(False, config=True)
165 deep_reload = CBool(False, config=True)
166 displayhook_class = Type(DisplayHook)
166 filename = Str("<ipython console>")
167 filename = Str("<ipython console>")
167 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
168 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
168 logstart = CBool(False, config=True)
169 logstart = CBool(False, config=True)
169 logfile = Str('', config=True)
170 logfile = Str('', config=True)
170 logappend = Str('', config=True)
171 logappend = Str('', config=True)
171 object_info_string_level = Enum((0,1,2), default_value=0,
172 object_info_string_level = Enum((0,1,2), default_value=0,
172 config=True)
173 config=True)
173 pdb = CBool(False, config=True)
174 pdb = CBool(False, config=True)
174 pprint = CBool(True, config=True)
175 pprint = CBool(True, config=True)
175 profile = Str('', config=True)
176 profile = Str('', config=True)
176 prompt_in1 = Str('In [\\#]: ', config=True)
177 prompt_in1 = Str('In [\\#]: ', config=True)
177 prompt_in2 = Str(' .\\D.: ', config=True)
178 prompt_in2 = Str(' .\\D.: ', config=True)
178 prompt_out = Str('Out[\\#]: ', config=True)
179 prompt_out = Str('Out[\\#]: ', config=True)
179 prompts_pad_left = CBool(True, config=True)
180 prompts_pad_left = CBool(True, config=True)
180 quiet = CBool(False, config=True)
181 quiet = CBool(False, config=True)
181
182
182 # The readline stuff will eventually be moved to the terminal subclass
183 # The readline stuff will eventually be moved to the terminal subclass
183 # but for now, we can't do that as readline is welded in everywhere.
184 # but for now, we can't do that as readline is welded in everywhere.
184 readline_use = CBool(True, config=True)
185 readline_use = CBool(True, config=True)
185 readline_merge_completions = CBool(True, config=True)
186 readline_merge_completions = CBool(True, config=True)
186 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
187 readline_omit__names = Enum((0,1,2), default_value=0, config=True)
187 readline_remove_delims = Str('-/~', config=True)
188 readline_remove_delims = Str('-/~', config=True)
188 readline_parse_and_bind = List([
189 readline_parse_and_bind = List([
189 'tab: complete',
190 'tab: complete',
190 '"\C-l": clear-screen',
191 '"\C-l": clear-screen',
191 'set show-all-if-ambiguous on',
192 'set show-all-if-ambiguous on',
192 '"\C-o": tab-insert',
193 '"\C-o": tab-insert',
193 '"\M-i": " "',
194 '"\M-i": " "',
194 '"\M-o": "\d\d\d\d"',
195 '"\M-o": "\d\d\d\d"',
195 '"\M-I": "\d\d\d\d"',
196 '"\M-I": "\d\d\d\d"',
196 '"\C-r": reverse-search-history',
197 '"\C-r": reverse-search-history',
197 '"\C-s": forward-search-history',
198 '"\C-s": forward-search-history',
198 '"\C-p": history-search-backward',
199 '"\C-p": history-search-backward',
199 '"\C-n": history-search-forward',
200 '"\C-n": history-search-forward',
200 '"\e[A": history-search-backward',
201 '"\e[A": history-search-backward',
201 '"\e[B": history-search-forward',
202 '"\e[B": history-search-forward',
202 '"\C-k": kill-line',
203 '"\C-k": kill-line',
203 '"\C-u": unix-line-discard',
204 '"\C-u": unix-line-discard',
204 ], allow_none=False, config=True)
205 ], allow_none=False, config=True)
205
206
206 # TODO: this part of prompt management should be moved to the frontends.
207 # TODO: this part of prompt management should be moved to the frontends.
207 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
208 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
208 separate_in = SeparateStr('\n', config=True)
209 separate_in = SeparateStr('\n', config=True)
209 separate_out = SeparateStr('\n', config=True)
210 separate_out = SeparateStr('\n', config=True)
210 separate_out2 = SeparateStr('\n', config=True)
211 separate_out2 = SeparateStr('\n', config=True)
211 system_header = Str('IPython system call: ', config=True)
212 system_header = Str('IPython system call: ', config=True)
212 system_verbose = CBool(False, config=True)
213 system_verbose = CBool(False, config=True)
213 wildcards_case_sensitive = CBool(True, config=True)
214 wildcards_case_sensitive = CBool(True, config=True)
214 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
215 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
215 default_value='Context', config=True)
216 default_value='Context', config=True)
216
217
217 # Subcomponents of InteractiveShell
218 # Subcomponents of InteractiveShell
218 alias_manager = Instance('IPython.core.alias.AliasManager')
219 alias_manager = Instance('IPython.core.alias.AliasManager')
219 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
220 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
220 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
221 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
221 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
222 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
222 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
223 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
223 plugin_manager = Instance('IPython.core.plugin.PluginManager')
224 plugin_manager = Instance('IPython.core.plugin.PluginManager')
224
225
225 def __init__(self, config=None, ipython_dir=None,
226 def __init__(self, config=None, ipython_dir=None,
226 user_ns=None, user_global_ns=None,
227 user_ns=None, user_global_ns=None,
227 custom_exceptions=((),None)):
228 custom_exceptions=((),None)):
228
229
229 # This is where traits with a config_key argument are updated
230 # This is where traits with a config_key argument are updated
230 # from the values on config.
231 # from the values on config.
231 super(InteractiveShell, self).__init__(config=config)
232 super(InteractiveShell, self).__init__(config=config)
232
233
233 # These are relatively independent and stateless
234 # These are relatively independent and stateless
234 self.init_ipython_dir(ipython_dir)
235 self.init_ipython_dir(ipython_dir)
235 self.init_instance_attrs()
236 self.init_instance_attrs()
236
237
237 # Create namespaces (user_ns, user_global_ns, etc.)
238 # Create namespaces (user_ns, user_global_ns, etc.)
238 self.init_create_namespaces(user_ns, user_global_ns)
239 self.init_create_namespaces(user_ns, user_global_ns)
239 # This has to be done after init_create_namespaces because it uses
240 # This has to be done after init_create_namespaces because it uses
240 # something in self.user_ns, but before init_sys_modules, which
241 # something in self.user_ns, but before init_sys_modules, which
241 # is the first thing to modify sys.
242 # is the first thing to modify sys.
242 self.save_sys_module_state()
243 self.save_sys_module_state()
243 self.init_sys_modules()
244 self.init_sys_modules()
244
245
245 self.init_history()
246 self.init_history()
246 self.init_encoding()
247 self.init_encoding()
247 self.init_prefilter()
248 self.init_prefilter()
248
249
249 Magic.__init__(self, self)
250 Magic.__init__(self, self)
250
251
251 self.init_syntax_highlighting()
252 self.init_syntax_highlighting()
252 self.init_hooks()
253 self.init_hooks()
253 self.init_pushd_popd_magic()
254 self.init_pushd_popd_magic()
254 # TODO: init_io() needs to happen before init_traceback handlers
255 # TODO: init_io() needs to happen before init_traceback handlers
255 # because the traceback handlers hardcode the stdout/stderr streams.
256 # because the traceback handlers hardcode the stdout/stderr streams.
256 # This logic in in debugger.Pdb and should eventually be changed.
257 # This logic in in debugger.Pdb and should eventually be changed.
257 self.init_io()
258 self.init_io()
258 self.init_traceback_handlers(custom_exceptions)
259 self.init_traceback_handlers(custom_exceptions)
259 self.init_user_ns()
260 self.init_user_ns()
260 self.init_logger()
261 self.init_logger()
261 self.init_alias()
262 self.init_alias()
262 self.init_builtins()
263 self.init_builtins()
263
264
264 # pre_config_initialization
265 # pre_config_initialization
265 self.init_shadow_hist()
266 self.init_shadow_hist()
266
267
267 # The next section should contain averything that was in ipmaker.
268 # The next section should contain averything that was in ipmaker.
268 self.init_logstart()
269 self.init_logstart()
269
270
270 # The following was in post_config_initialization
271 # The following was in post_config_initialization
271 self.init_inspector()
272 self.init_inspector()
272 self.init_readline()
273 self.init_readline()
273 self.init_prompts()
274 self.init_prompts()
274 self.init_displayhook()
275 self.init_displayhook()
275 self.init_reload_doctest()
276 self.init_reload_doctest()
276 self.init_magics()
277 self.init_magics()
277 self.init_pdb()
278 self.init_pdb()
278 self.init_extension_manager()
279 self.init_extension_manager()
279 self.init_plugin_manager()
280 self.init_plugin_manager()
280 self.hooks.late_startup_hook()
281 self.hooks.late_startup_hook()
281
282
282 @classmethod
283 @classmethod
283 def instance(cls, *args, **kwargs):
284 def instance(cls, *args, **kwargs):
284 """Returns a global InteractiveShell instance."""
285 """Returns a global InteractiveShell instance."""
285 if not hasattr(cls, "_instance"):
286 if not hasattr(cls, "_instance"):
286 cls._instance = cls(*args, **kwargs)
287 cls._instance = cls(*args, **kwargs)
287 return cls._instance
288 return cls._instance
288
289
289 @classmethod
290 @classmethod
290 def initialized(cls):
291 def initialized(cls):
291 return hasattr(cls, "_instance")
292 return hasattr(cls, "_instance")
292
293
293 def get_ipython(self):
294 def get_ipython(self):
294 """Return the currently running IPython instance."""
295 """Return the currently running IPython instance."""
295 return self
296 return self
296
297
297 #-------------------------------------------------------------------------
298 #-------------------------------------------------------------------------
298 # Trait changed handlers
299 # Trait changed handlers
299 #-------------------------------------------------------------------------
300 #-------------------------------------------------------------------------
300
301
301 def _ipython_dir_changed(self, name, new):
302 def _ipython_dir_changed(self, name, new):
302 if not os.path.isdir(new):
303 if not os.path.isdir(new):
303 os.makedirs(new, mode = 0777)
304 os.makedirs(new, mode = 0777)
304
305
305 def set_autoindent(self,value=None):
306 def set_autoindent(self,value=None):
306 """Set the autoindent flag, checking for readline support.
307 """Set the autoindent flag, checking for readline support.
307
308
308 If called with no arguments, it acts as a toggle."""
309 If called with no arguments, it acts as a toggle."""
309
310
310 if not self.has_readline:
311 if not self.has_readline:
311 if os.name == 'posix':
312 if os.name == 'posix':
312 warn("The auto-indent feature requires the readline library")
313 warn("The auto-indent feature requires the readline library")
313 self.autoindent = 0
314 self.autoindent = 0
314 return
315 return
315 if value is None:
316 if value is None:
316 self.autoindent = not self.autoindent
317 self.autoindent = not self.autoindent
317 else:
318 else:
318 self.autoindent = value
319 self.autoindent = value
319
320
320 #-------------------------------------------------------------------------
321 #-------------------------------------------------------------------------
321 # init_* methods called by __init__
322 # init_* methods called by __init__
322 #-------------------------------------------------------------------------
323 #-------------------------------------------------------------------------
323
324
324 def init_ipython_dir(self, ipython_dir):
325 def init_ipython_dir(self, ipython_dir):
325 if ipython_dir is not None:
326 if ipython_dir is not None:
326 self.ipython_dir = ipython_dir
327 self.ipython_dir = ipython_dir
327 self.config.Global.ipython_dir = self.ipython_dir
328 self.config.Global.ipython_dir = self.ipython_dir
328 return
329 return
329
330
330 if hasattr(self.config.Global, 'ipython_dir'):
331 if hasattr(self.config.Global, 'ipython_dir'):
331 self.ipython_dir = self.config.Global.ipython_dir
332 self.ipython_dir = self.config.Global.ipython_dir
332 else:
333 else:
333 self.ipython_dir = get_ipython_dir()
334 self.ipython_dir = get_ipython_dir()
334
335
335 # All children can just read this
336 # All children can just read this
336 self.config.Global.ipython_dir = self.ipython_dir
337 self.config.Global.ipython_dir = self.ipython_dir
337
338
338 def init_instance_attrs(self):
339 def init_instance_attrs(self):
339 self.more = False
340 self.more = False
340
341
341 # command compiler
342 # command compiler
342 self.compile = codeop.CommandCompiler()
343 self.compile = codeop.CommandCompiler()
343
344
344 # User input buffer
345 # User input buffer
345 self.buffer = []
346 self.buffer = []
346
347
347 # Make an empty namespace, which extension writers can rely on both
348 # Make an empty namespace, which extension writers can rely on both
348 # existing and NEVER being used by ipython itself. This gives them a
349 # existing and NEVER being used by ipython itself. This gives them a
349 # convenient location for storing additional information and state
350 # convenient location for storing additional information and state
350 # their extensions may require, without fear of collisions with other
351 # their extensions may require, without fear of collisions with other
351 # ipython names that may develop later.
352 # ipython names that may develop later.
352 self.meta = Struct()
353 self.meta = Struct()
353
354
354 # Object variable to store code object waiting execution. This is
355 # Object variable to store code object waiting execution. This is
355 # used mainly by the multithreaded shells, but it can come in handy in
356 # used mainly by the multithreaded shells, but it can come in handy in
356 # other situations. No need to use a Queue here, since it's a single
357 # other situations. No need to use a Queue here, since it's a single
357 # item which gets cleared once run.
358 # item which gets cleared once run.
358 self.code_to_run = None
359 self.code_to_run = None
359
360
360 # Temporary files used for various purposes. Deleted at exit.
361 # Temporary files used for various purposes. Deleted at exit.
361 self.tempfiles = []
362 self.tempfiles = []
362
363
363 # Keep track of readline usage (later set by init_readline)
364 # Keep track of readline usage (later set by init_readline)
364 self.has_readline = False
365 self.has_readline = False
365
366
366 # keep track of where we started running (mainly for crash post-mortem)
367 # keep track of where we started running (mainly for crash post-mortem)
367 # This is not being used anywhere currently.
368 # This is not being used anywhere currently.
368 self.starting_dir = os.getcwd()
369 self.starting_dir = os.getcwd()
369
370
370 # Indentation management
371 # Indentation management
371 self.indent_current_nsp = 0
372 self.indent_current_nsp = 0
372
373
373 def init_encoding(self):
374 def init_encoding(self):
374 # Get system encoding at startup time. Certain terminals (like Emacs
375 # Get system encoding at startup time. Certain terminals (like Emacs
375 # under Win32 have it set to None, and we need to have a known valid
376 # under Win32 have it set to None, and we need to have a known valid
376 # encoding to use in the raw_input() method
377 # encoding to use in the raw_input() method
377 try:
378 try:
378 self.stdin_encoding = sys.stdin.encoding or 'ascii'
379 self.stdin_encoding = sys.stdin.encoding or 'ascii'
379 except AttributeError:
380 except AttributeError:
380 self.stdin_encoding = 'ascii'
381 self.stdin_encoding = 'ascii'
381
382
382 def init_syntax_highlighting(self):
383 def init_syntax_highlighting(self):
383 # Python source parser/formatter for syntax highlighting
384 # Python source parser/formatter for syntax highlighting
384 pyformat = PyColorize.Parser().format
385 pyformat = PyColorize.Parser().format
385 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
386 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
386
387
387 def init_pushd_popd_magic(self):
388 def init_pushd_popd_magic(self):
388 # for pushd/popd management
389 # for pushd/popd management
389 try:
390 try:
390 self.home_dir = get_home_dir()
391 self.home_dir = get_home_dir()
391 except HomeDirError, msg:
392 except HomeDirError, msg:
392 fatal(msg)
393 fatal(msg)
393
394
394 self.dir_stack = []
395 self.dir_stack = []
395
396
396 def init_logger(self):
397 def init_logger(self):
397 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
398 self.logger = Logger(self, logfname='ipython_log.py', logmode='rotate')
398 # local shortcut, this is used a LOT
399 # local shortcut, this is used a LOT
399 self.log = self.logger.log
400 self.log = self.logger.log
400
401
401 def init_logstart(self):
402 def init_logstart(self):
402 if self.logappend:
403 if self.logappend:
403 self.magic_logstart(self.logappend + ' append')
404 self.magic_logstart(self.logappend + ' append')
404 elif self.logfile:
405 elif self.logfile:
405 self.magic_logstart(self.logfile)
406 self.magic_logstart(self.logfile)
406 elif self.logstart:
407 elif self.logstart:
407 self.magic_logstart()
408 self.magic_logstart()
408
409
409 def init_builtins(self):
410 def init_builtins(self):
410 self.builtin_trap = BuiltinTrap(shell=self)
411 self.builtin_trap = BuiltinTrap(shell=self)
411
412
412 def init_inspector(self):
413 def init_inspector(self):
413 # Object inspector
414 # Object inspector
414 self.inspector = oinspect.Inspector(oinspect.InspectColors,
415 self.inspector = oinspect.Inspector(oinspect.InspectColors,
415 PyColorize.ANSICodeColors,
416 PyColorize.ANSICodeColors,
416 'NoColor',
417 'NoColor',
417 self.object_info_string_level)
418 self.object_info_string_level)
418
419
419 def init_io(self):
420 def init_io(self):
420 import IPython.utils.io
421 import IPython.utils.io
421 if sys.platform == 'win32' and readline.have_readline and \
422 if sys.platform == 'win32' and readline.have_readline and \
422 self.readline_use:
423 self.readline_use:
423 Term = IPython.utils.io.IOTerm(
424 Term = IPython.utils.io.IOTerm(
424 cout=readline._outputfile,cerr=readline._outputfile
425 cout=readline._outputfile,cerr=readline._outputfile
425 )
426 )
426 else:
427 else:
427 Term = IPython.utils.io.IOTerm()
428 Term = IPython.utils.io.IOTerm()
428 IPython.utils.io.Term = Term
429 IPython.utils.io.Term = Term
429
430
430 def init_prompts(self):
431 def init_prompts(self):
431 # TODO: This is a pass for now because the prompts are managed inside
432 # TODO: This is a pass for now because the prompts are managed inside
432 # the DisplayHook. Once there is a separate prompt manager, this
433 # the DisplayHook. Once there is a separate prompt manager, this
433 # will initialize that object and all prompt related information.
434 # will initialize that object and all prompt related information.
434 pass
435 pass
435
436
436 def init_displayhook(self):
437 def init_displayhook(self):
437 # Initialize displayhook, set in/out prompts and printing system
438 # Initialize displayhook, set in/out prompts and printing system
438 self.displayhook = DisplayHook( shell=self,
439 self.displayhook = self.displayhook_class(
439 cache_size=self.cache_size,
440 shell=self,
440 input_sep = self.separate_in,
441 cache_size=self.cache_size,
441 output_sep = self.separate_out,
442 input_sep = self.separate_in,
442 output_sep2 = self.separate_out2,
443 output_sep = self.separate_out,
443 ps1 = self.prompt_in1,
444 output_sep2 = self.separate_out2,
444 ps2 = self.prompt_in2,
445 ps1 = self.prompt_in1,
445 ps_out = self.prompt_out,
446 ps2 = self.prompt_in2,
446 pad_left = self.prompts_pad_left)
447 ps_out = self.prompt_out,
448 pad_left = self.prompts_pad_left
449 )
447 # This is a context manager that installs/revmoes the displayhook at
450 # This is a context manager that installs/revmoes the displayhook at
448 # the appropriate time.
451 # the appropriate time.
449 self.display_trap = DisplayTrap(hook=self.displayhook)
452 self.display_trap = DisplayTrap(hook=self.displayhook)
450
453
451 def init_reload_doctest(self):
454 def init_reload_doctest(self):
452 # Do a proper resetting of doctest, including the necessary displayhook
455 # Do a proper resetting of doctest, including the necessary displayhook
453 # monkeypatching
456 # monkeypatching
454 try:
457 try:
455 doctest_reload()
458 doctest_reload()
456 except ImportError:
459 except ImportError:
457 warn("doctest module does not exist.")
460 warn("doctest module does not exist.")
458
461
459 #-------------------------------------------------------------------------
462 #-------------------------------------------------------------------------
460 # Things related to injections into the sys module
463 # Things related to injections into the sys module
461 #-------------------------------------------------------------------------
464 #-------------------------------------------------------------------------
462
465
463 def save_sys_module_state(self):
466 def save_sys_module_state(self):
464 """Save the state of hooks in the sys module.
467 """Save the state of hooks in the sys module.
465
468
466 This has to be called after self.user_ns is created.
469 This has to be called after self.user_ns is created.
467 """
470 """
468 self._orig_sys_module_state = {}
471 self._orig_sys_module_state = {}
469 self._orig_sys_module_state['stdin'] = sys.stdin
472 self._orig_sys_module_state['stdin'] = sys.stdin
470 self._orig_sys_module_state['stdout'] = sys.stdout
473 self._orig_sys_module_state['stdout'] = sys.stdout
471 self._orig_sys_module_state['stderr'] = sys.stderr
474 self._orig_sys_module_state['stderr'] = sys.stderr
472 self._orig_sys_module_state['excepthook'] = sys.excepthook
475 self._orig_sys_module_state['excepthook'] = sys.excepthook
473 try:
476 try:
474 self._orig_sys_modules_main_name = self.user_ns['__name__']
477 self._orig_sys_modules_main_name = self.user_ns['__name__']
475 except KeyError:
478 except KeyError:
476 pass
479 pass
477
480
478 def restore_sys_module_state(self):
481 def restore_sys_module_state(self):
479 """Restore the state of the sys module."""
482 """Restore the state of the sys module."""
480 try:
483 try:
481 for k, v in self._orig_sys_module_state.items():
484 for k, v in self._orig_sys_module_state.items():
482 setattr(sys, k, v)
485 setattr(sys, k, v)
483 except AttributeError:
486 except AttributeError:
484 pass
487 pass
485 try:
488 try:
486 delattr(sys, 'ipcompleter')
489 delattr(sys, 'ipcompleter')
487 except AttributeError:
490 except AttributeError:
488 pass
491 pass
489 # Reset what what done in self.init_sys_modules
492 # Reset what what done in self.init_sys_modules
490 try:
493 try:
491 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
494 sys.modules[self.user_ns['__name__']] = self._orig_sys_modules_main_name
492 except (AttributeError, KeyError):
495 except (AttributeError, KeyError):
493 pass
496 pass
494
497
495 #-------------------------------------------------------------------------
498 #-------------------------------------------------------------------------
496 # Things related to hooks
499 # Things related to hooks
497 #-------------------------------------------------------------------------
500 #-------------------------------------------------------------------------
498
501
499 def init_hooks(self):
502 def init_hooks(self):
500 # hooks holds pointers used for user-side customizations
503 # hooks holds pointers used for user-side customizations
501 self.hooks = Struct()
504 self.hooks = Struct()
502
505
503 self.strdispatchers = {}
506 self.strdispatchers = {}
504
507
505 # Set all default hooks, defined in the IPython.hooks module.
508 # Set all default hooks, defined in the IPython.hooks module.
506 hooks = IPython.core.hooks
509 hooks = IPython.core.hooks
507 for hook_name in hooks.__all__:
510 for hook_name in hooks.__all__:
508 # default hooks have priority 100, i.e. low; user hooks should have
511 # default hooks have priority 100, i.e. low; user hooks should have
509 # 0-100 priority
512 # 0-100 priority
510 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
513 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
511
514
512 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
515 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
513 """set_hook(name,hook) -> sets an internal IPython hook.
516 """set_hook(name,hook) -> sets an internal IPython hook.
514
517
515 IPython exposes some of its internal API as user-modifiable hooks. By
518 IPython exposes some of its internal API as user-modifiable hooks. By
516 adding your function to one of these hooks, you can modify IPython's
519 adding your function to one of these hooks, you can modify IPython's
517 behavior to call at runtime your own routines."""
520 behavior to call at runtime your own routines."""
518
521
519 # At some point in the future, this should validate the hook before it
522 # At some point in the future, this should validate the hook before it
520 # accepts it. Probably at least check that the hook takes the number
523 # accepts it. Probably at least check that the hook takes the number
521 # of args it's supposed to.
524 # of args it's supposed to.
522
525
523 f = new.instancemethod(hook,self,self.__class__)
526 f = new.instancemethod(hook,self,self.__class__)
524
527
525 # check if the hook is for strdispatcher first
528 # check if the hook is for strdispatcher first
526 if str_key is not None:
529 if str_key is not None:
527 sdp = self.strdispatchers.get(name, StrDispatch())
530 sdp = self.strdispatchers.get(name, StrDispatch())
528 sdp.add_s(str_key, f, priority )
531 sdp.add_s(str_key, f, priority )
529 self.strdispatchers[name] = sdp
532 self.strdispatchers[name] = sdp
530 return
533 return
531 if re_key is not None:
534 if re_key is not None:
532 sdp = self.strdispatchers.get(name, StrDispatch())
535 sdp = self.strdispatchers.get(name, StrDispatch())
533 sdp.add_re(re.compile(re_key), f, priority )
536 sdp.add_re(re.compile(re_key), f, priority )
534 self.strdispatchers[name] = sdp
537 self.strdispatchers[name] = sdp
535 return
538 return
536
539
537 dp = getattr(self.hooks, name, None)
540 dp = getattr(self.hooks, name, None)
538 if name not in IPython.core.hooks.__all__:
541 if name not in IPython.core.hooks.__all__:
539 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
542 print "Warning! Hook '%s' is not one of %s" % (name, IPython.core.hooks.__all__ )
540 if not dp:
543 if not dp:
541 dp = IPython.core.hooks.CommandChainDispatcher()
544 dp = IPython.core.hooks.CommandChainDispatcher()
542
545
543 try:
546 try:
544 dp.add(f,priority)
547 dp.add(f,priority)
545 except AttributeError:
548 except AttributeError:
546 # it was not commandchain, plain old func - replace
549 # it was not commandchain, plain old func - replace
547 dp = f
550 dp = f
548
551
549 setattr(self.hooks,name, dp)
552 setattr(self.hooks,name, dp)
550
553
551 #-------------------------------------------------------------------------
554 #-------------------------------------------------------------------------
552 # Things related to the "main" module
555 # Things related to the "main" module
553 #-------------------------------------------------------------------------
556 #-------------------------------------------------------------------------
554
557
555 def new_main_mod(self,ns=None):
558 def new_main_mod(self,ns=None):
556 """Return a new 'main' module object for user code execution.
559 """Return a new 'main' module object for user code execution.
557 """
560 """
558 main_mod = self._user_main_module
561 main_mod = self._user_main_module
559 init_fakemod_dict(main_mod,ns)
562 init_fakemod_dict(main_mod,ns)
560 return main_mod
563 return main_mod
561
564
562 def cache_main_mod(self,ns,fname):
565 def cache_main_mod(self,ns,fname):
563 """Cache a main module's namespace.
566 """Cache a main module's namespace.
564
567
565 When scripts are executed via %run, we must keep a reference to the
568 When scripts are executed via %run, we must keep a reference to the
566 namespace of their __main__ module (a FakeModule instance) around so
569 namespace of their __main__ module (a FakeModule instance) around so
567 that Python doesn't clear it, rendering objects defined therein
570 that Python doesn't clear it, rendering objects defined therein
568 useless.
571 useless.
569
572
570 This method keeps said reference in a private dict, keyed by the
573 This method keeps said reference in a private dict, keyed by the
571 absolute path of the module object (which corresponds to the script
574 absolute path of the module object (which corresponds to the script
572 path). This way, for multiple executions of the same script we only
575 path). This way, for multiple executions of the same script we only
573 keep one copy of the namespace (the last one), thus preventing memory
576 keep one copy of the namespace (the last one), thus preventing memory
574 leaks from old references while allowing the objects from the last
577 leaks from old references while allowing the objects from the last
575 execution to be accessible.
578 execution to be accessible.
576
579
577 Note: we can not allow the actual FakeModule instances to be deleted,
580 Note: we can not allow the actual FakeModule instances to be deleted,
578 because of how Python tears down modules (it hard-sets all their
581 because of how Python tears down modules (it hard-sets all their
579 references to None without regard for reference counts). This method
582 references to None without regard for reference counts). This method
580 must therefore make a *copy* of the given namespace, to allow the
583 must therefore make a *copy* of the given namespace, to allow the
581 original module's __dict__ to be cleared and reused.
584 original module's __dict__ to be cleared and reused.
582
585
583
586
584 Parameters
587 Parameters
585 ----------
588 ----------
586 ns : a namespace (a dict, typically)
589 ns : a namespace (a dict, typically)
587
590
588 fname : str
591 fname : str
589 Filename associated with the namespace.
592 Filename associated with the namespace.
590
593
591 Examples
594 Examples
592 --------
595 --------
593
596
594 In [10]: import IPython
597 In [10]: import IPython
595
598
596 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
599 In [11]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
597
600
598 In [12]: IPython.__file__ in _ip._main_ns_cache
601 In [12]: IPython.__file__ in _ip._main_ns_cache
599 Out[12]: True
602 Out[12]: True
600 """
603 """
601 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
604 self._main_ns_cache[os.path.abspath(fname)] = ns.copy()
602
605
603 def clear_main_mod_cache(self):
606 def clear_main_mod_cache(self):
604 """Clear the cache of main modules.
607 """Clear the cache of main modules.
605
608
606 Mainly for use by utilities like %reset.
609 Mainly for use by utilities like %reset.
607
610
608 Examples
611 Examples
609 --------
612 --------
610
613
611 In [15]: import IPython
614 In [15]: import IPython
612
615
613 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
616 In [16]: _ip.cache_main_mod(IPython.__dict__,IPython.__file__)
614
617
615 In [17]: len(_ip._main_ns_cache) > 0
618 In [17]: len(_ip._main_ns_cache) > 0
616 Out[17]: True
619 Out[17]: True
617
620
618 In [18]: _ip.clear_main_mod_cache()
621 In [18]: _ip.clear_main_mod_cache()
619
622
620 In [19]: len(_ip._main_ns_cache) == 0
623 In [19]: len(_ip._main_ns_cache) == 0
621 Out[19]: True
624 Out[19]: True
622 """
625 """
623 self._main_ns_cache.clear()
626 self._main_ns_cache.clear()
624
627
625 #-------------------------------------------------------------------------
628 #-------------------------------------------------------------------------
626 # Things related to debugging
629 # Things related to debugging
627 #-------------------------------------------------------------------------
630 #-------------------------------------------------------------------------
628
631
629 def init_pdb(self):
632 def init_pdb(self):
630 # Set calling of pdb on exceptions
633 # Set calling of pdb on exceptions
631 # self.call_pdb is a property
634 # self.call_pdb is a property
632 self.call_pdb = self.pdb
635 self.call_pdb = self.pdb
633
636
634 def _get_call_pdb(self):
637 def _get_call_pdb(self):
635 return self._call_pdb
638 return self._call_pdb
636
639
637 def _set_call_pdb(self,val):
640 def _set_call_pdb(self,val):
638
641
639 if val not in (0,1,False,True):
642 if val not in (0,1,False,True):
640 raise ValueError,'new call_pdb value must be boolean'
643 raise ValueError,'new call_pdb value must be boolean'
641
644
642 # store value in instance
645 # store value in instance
643 self._call_pdb = val
646 self._call_pdb = val
644
647
645 # notify the actual exception handlers
648 # notify the actual exception handlers
646 self.InteractiveTB.call_pdb = val
649 self.InteractiveTB.call_pdb = val
647
650
648 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
651 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
649 'Control auto-activation of pdb at exceptions')
652 'Control auto-activation of pdb at exceptions')
650
653
651 def debugger(self,force=False):
654 def debugger(self,force=False):
652 """Call the pydb/pdb debugger.
655 """Call the pydb/pdb debugger.
653
656
654 Keywords:
657 Keywords:
655
658
656 - force(False): by default, this routine checks the instance call_pdb
659 - force(False): by default, this routine checks the instance call_pdb
657 flag and does not actually invoke the debugger if the flag is false.
660 flag and does not actually invoke the debugger if the flag is false.
658 The 'force' option forces the debugger to activate even if the flag
661 The 'force' option forces the debugger to activate even if the flag
659 is false.
662 is false.
660 """
663 """
661
664
662 if not (force or self.call_pdb):
665 if not (force or self.call_pdb):
663 return
666 return
664
667
665 if not hasattr(sys,'last_traceback'):
668 if not hasattr(sys,'last_traceback'):
666 error('No traceback has been produced, nothing to debug.')
669 error('No traceback has been produced, nothing to debug.')
667 return
670 return
668
671
669 # use pydb if available
672 # use pydb if available
670 if debugger.has_pydb:
673 if debugger.has_pydb:
671 from pydb import pm
674 from pydb import pm
672 else:
675 else:
673 # fallback to our internal debugger
676 # fallback to our internal debugger
674 pm = lambda : self.InteractiveTB.debugger(force=True)
677 pm = lambda : self.InteractiveTB.debugger(force=True)
675 self.history_saving_wrapper(pm)()
678 self.history_saving_wrapper(pm)()
676
679
677 #-------------------------------------------------------------------------
680 #-------------------------------------------------------------------------
678 # Things related to IPython's various namespaces
681 # Things related to IPython's various namespaces
679 #-------------------------------------------------------------------------
682 #-------------------------------------------------------------------------
680
683
681 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
684 def init_create_namespaces(self, user_ns=None, user_global_ns=None):
682 # Create the namespace where the user will operate. user_ns is
685 # Create the namespace where the user will operate. user_ns is
683 # normally the only one used, and it is passed to the exec calls as
686 # normally the only one used, and it is passed to the exec calls as
684 # the locals argument. But we do carry a user_global_ns namespace
687 # the locals argument. But we do carry a user_global_ns namespace
685 # given as the exec 'globals' argument, This is useful in embedding
688 # given as the exec 'globals' argument, This is useful in embedding
686 # situations where the ipython shell opens in a context where the
689 # situations where the ipython shell opens in a context where the
687 # distinction between locals and globals is meaningful. For
690 # distinction between locals and globals is meaningful. For
688 # non-embedded contexts, it is just the same object as the user_ns dict.
691 # non-embedded contexts, it is just the same object as the user_ns dict.
689
692
690 # FIXME. For some strange reason, __builtins__ is showing up at user
693 # FIXME. For some strange reason, __builtins__ is showing up at user
691 # level as a dict instead of a module. This is a manual fix, but I
694 # level as a dict instead of a module. This is a manual fix, but I
692 # should really track down where the problem is coming from. Alex
695 # should really track down where the problem is coming from. Alex
693 # Schmolck reported this problem first.
696 # Schmolck reported this problem first.
694
697
695 # A useful post by Alex Martelli on this topic:
698 # A useful post by Alex Martelli on this topic:
696 # Re: inconsistent value from __builtins__
699 # Re: inconsistent value from __builtins__
697 # Von: Alex Martelli <aleaxit@yahoo.com>
700 # Von: Alex Martelli <aleaxit@yahoo.com>
698 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
701 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
699 # Gruppen: comp.lang.python
702 # Gruppen: comp.lang.python
700
703
701 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
704 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
702 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
705 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
703 # > <type 'dict'>
706 # > <type 'dict'>
704 # > >>> print type(__builtins__)
707 # > >>> print type(__builtins__)
705 # > <type 'module'>
708 # > <type 'module'>
706 # > Is this difference in return value intentional?
709 # > Is this difference in return value intentional?
707
710
708 # Well, it's documented that '__builtins__' can be either a dictionary
711 # Well, it's documented that '__builtins__' can be either a dictionary
709 # or a module, and it's been that way for a long time. Whether it's
712 # or a module, and it's been that way for a long time. Whether it's
710 # intentional (or sensible), I don't know. In any case, the idea is
713 # intentional (or sensible), I don't know. In any case, the idea is
711 # that if you need to access the built-in namespace directly, you
714 # that if you need to access the built-in namespace directly, you
712 # should start with "import __builtin__" (note, no 's') which will
715 # should start with "import __builtin__" (note, no 's') which will
713 # definitely give you a module. Yeah, it's somewhat confusing:-(.
716 # definitely give you a module. Yeah, it's somewhat confusing:-(.
714
717
715 # These routines return properly built dicts as needed by the rest of
718 # These routines return properly built dicts as needed by the rest of
716 # the code, and can also be used by extension writers to generate
719 # the code, and can also be used by extension writers to generate
717 # properly initialized namespaces.
720 # properly initialized namespaces.
718 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
721 user_ns, user_global_ns = self.make_user_namespaces(user_ns, user_global_ns)
719
722
720 # Assign namespaces
723 # Assign namespaces
721 # This is the namespace where all normal user variables live
724 # This is the namespace where all normal user variables live
722 self.user_ns = user_ns
725 self.user_ns = user_ns
723 self.user_global_ns = user_global_ns
726 self.user_global_ns = user_global_ns
724
727
725 # An auxiliary namespace that checks what parts of the user_ns were
728 # An auxiliary namespace that checks what parts of the user_ns were
726 # loaded at startup, so we can list later only variables defined in
729 # loaded at startup, so we can list later only variables defined in
727 # actual interactive use. Since it is always a subset of user_ns, it
730 # actual interactive use. Since it is always a subset of user_ns, it
728 # doesn't need to be separately tracked in the ns_table.
731 # doesn't need to be separately tracked in the ns_table.
729 self.user_ns_hidden = {}
732 self.user_ns_hidden = {}
730
733
731 # A namespace to keep track of internal data structures to prevent
734 # A namespace to keep track of internal data structures to prevent
732 # them from cluttering user-visible stuff. Will be updated later
735 # them from cluttering user-visible stuff. Will be updated later
733 self.internal_ns = {}
736 self.internal_ns = {}
734
737
735 # Now that FakeModule produces a real module, we've run into a nasty
738 # Now that FakeModule produces a real module, we've run into a nasty
736 # problem: after script execution (via %run), the module where the user
739 # problem: after script execution (via %run), the module where the user
737 # code ran is deleted. Now that this object is a true module (needed
740 # code ran is deleted. Now that this object is a true module (needed
738 # so docetst and other tools work correctly), the Python module
741 # so docetst and other tools work correctly), the Python module
739 # teardown mechanism runs over it, and sets to None every variable
742 # teardown mechanism runs over it, and sets to None every variable
740 # present in that module. Top-level references to objects from the
743 # present in that module. Top-level references to objects from the
741 # script survive, because the user_ns is updated with them. However,
744 # script survive, because the user_ns is updated with them. However,
742 # calling functions defined in the script that use other things from
745 # calling functions defined in the script that use other things from
743 # the script will fail, because the function's closure had references
746 # the script will fail, because the function's closure had references
744 # to the original objects, which are now all None. So we must protect
747 # to the original objects, which are now all None. So we must protect
745 # these modules from deletion by keeping a cache.
748 # these modules from deletion by keeping a cache.
746 #
749 #
747 # To avoid keeping stale modules around (we only need the one from the
750 # To avoid keeping stale modules around (we only need the one from the
748 # last run), we use a dict keyed with the full path to the script, so
751 # last run), we use a dict keyed with the full path to the script, so
749 # only the last version of the module is held in the cache. Note,
752 # only the last version of the module is held in the cache. Note,
750 # however, that we must cache the module *namespace contents* (their
753 # however, that we must cache the module *namespace contents* (their
751 # __dict__). Because if we try to cache the actual modules, old ones
754 # __dict__). Because if we try to cache the actual modules, old ones
752 # (uncached) could be destroyed while still holding references (such as
755 # (uncached) could be destroyed while still holding references (such as
753 # those held by GUI objects that tend to be long-lived)>
756 # those held by GUI objects that tend to be long-lived)>
754 #
757 #
755 # The %reset command will flush this cache. See the cache_main_mod()
758 # The %reset command will flush this cache. See the cache_main_mod()
756 # and clear_main_mod_cache() methods for details on use.
759 # and clear_main_mod_cache() methods for details on use.
757
760
758 # This is the cache used for 'main' namespaces
761 # This is the cache used for 'main' namespaces
759 self._main_ns_cache = {}
762 self._main_ns_cache = {}
760 # And this is the single instance of FakeModule whose __dict__ we keep
763 # And this is the single instance of FakeModule whose __dict__ we keep
761 # copying and clearing for reuse on each %run
764 # copying and clearing for reuse on each %run
762 self._user_main_module = FakeModule()
765 self._user_main_module = FakeModule()
763
766
764 # A table holding all the namespaces IPython deals with, so that
767 # A table holding all the namespaces IPython deals with, so that
765 # introspection facilities can search easily.
768 # introspection facilities can search easily.
766 self.ns_table = {'user':user_ns,
769 self.ns_table = {'user':user_ns,
767 'user_global':user_global_ns,
770 'user_global':user_global_ns,
768 'internal':self.internal_ns,
771 'internal':self.internal_ns,
769 'builtin':__builtin__.__dict__
772 'builtin':__builtin__.__dict__
770 }
773 }
771
774
772 # Similarly, track all namespaces where references can be held and that
775 # Similarly, track all namespaces where references can be held and that
773 # we can safely clear (so it can NOT include builtin). This one can be
776 # we can safely clear (so it can NOT include builtin). This one can be
774 # a simple list.
777 # a simple list.
775 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
778 self.ns_refs_table = [ user_ns, user_global_ns, self.user_ns_hidden,
776 self.internal_ns, self._main_ns_cache ]
779 self.internal_ns, self._main_ns_cache ]
777
780
778 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
781 def make_user_namespaces(self, user_ns=None, user_global_ns=None):
779 """Return a valid local and global user interactive namespaces.
782 """Return a valid local and global user interactive namespaces.
780
783
781 This builds a dict with the minimal information needed to operate as a
784 This builds a dict with the minimal information needed to operate as a
782 valid IPython user namespace, which you can pass to the various
785 valid IPython user namespace, which you can pass to the various
783 embedding classes in ipython. The default implementation returns the
786 embedding classes in ipython. The default implementation returns the
784 same dict for both the locals and the globals to allow functions to
787 same dict for both the locals and the globals to allow functions to
785 refer to variables in the namespace. Customized implementations can
788 refer to variables in the namespace. Customized implementations can
786 return different dicts. The locals dictionary can actually be anything
789 return different dicts. The locals dictionary can actually be anything
787 following the basic mapping protocol of a dict, but the globals dict
790 following the basic mapping protocol of a dict, but the globals dict
788 must be a true dict, not even a subclass. It is recommended that any
791 must be a true dict, not even a subclass. It is recommended that any
789 custom object for the locals namespace synchronize with the globals
792 custom object for the locals namespace synchronize with the globals
790 dict somehow.
793 dict somehow.
791
794
792 Raises TypeError if the provided globals namespace is not a true dict.
795 Raises TypeError if the provided globals namespace is not a true dict.
793
796
794 Parameters
797 Parameters
795 ----------
798 ----------
796 user_ns : dict-like, optional
799 user_ns : dict-like, optional
797 The current user namespace. The items in this namespace should
800 The current user namespace. The items in this namespace should
798 be included in the output. If None, an appropriate blank
801 be included in the output. If None, an appropriate blank
799 namespace should be created.
802 namespace should be created.
800 user_global_ns : dict, optional
803 user_global_ns : dict, optional
801 The current user global namespace. The items in this namespace
804 The current user global namespace. The items in this namespace
802 should be included in the output. If None, an appropriate
805 should be included in the output. If None, an appropriate
803 blank namespace should be created.
806 blank namespace should be created.
804
807
805 Returns
808 Returns
806 -------
809 -------
807 A pair of dictionary-like object to be used as the local namespace
810 A pair of dictionary-like object to be used as the local namespace
808 of the interpreter and a dict to be used as the global namespace.
811 of the interpreter and a dict to be used as the global namespace.
809 """
812 """
810
813
811
814
812 # We must ensure that __builtin__ (without the final 's') is always
815 # We must ensure that __builtin__ (without the final 's') is always
813 # available and pointing to the __builtin__ *module*. For more details:
816 # available and pointing to the __builtin__ *module*. For more details:
814 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
817 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
815
818
816 if user_ns is None:
819 if user_ns is None:
817 # Set __name__ to __main__ to better match the behavior of the
820 # Set __name__ to __main__ to better match the behavior of the
818 # normal interpreter.
821 # normal interpreter.
819 user_ns = {'__name__' :'__main__',
822 user_ns = {'__name__' :'__main__',
820 '__builtin__' : __builtin__,
823 '__builtin__' : __builtin__,
821 '__builtins__' : __builtin__,
824 '__builtins__' : __builtin__,
822 }
825 }
823 else:
826 else:
824 user_ns.setdefault('__name__','__main__')
827 user_ns.setdefault('__name__','__main__')
825 user_ns.setdefault('__builtin__',__builtin__)
828 user_ns.setdefault('__builtin__',__builtin__)
826 user_ns.setdefault('__builtins__',__builtin__)
829 user_ns.setdefault('__builtins__',__builtin__)
827
830
828 if user_global_ns is None:
831 if user_global_ns is None:
829 user_global_ns = user_ns
832 user_global_ns = user_ns
830 if type(user_global_ns) is not dict:
833 if type(user_global_ns) is not dict:
831 raise TypeError("user_global_ns must be a true dict; got %r"
834 raise TypeError("user_global_ns must be a true dict; got %r"
832 % type(user_global_ns))
835 % type(user_global_ns))
833
836
834 return user_ns, user_global_ns
837 return user_ns, user_global_ns
835
838
836 def init_sys_modules(self):
839 def init_sys_modules(self):
837 # We need to insert into sys.modules something that looks like a
840 # We need to insert into sys.modules something that looks like a
838 # module but which accesses the IPython namespace, for shelve and
841 # module but which accesses the IPython namespace, for shelve and
839 # pickle to work interactively. Normally they rely on getting
842 # pickle to work interactively. Normally they rely on getting
840 # everything out of __main__, but for embedding purposes each IPython
843 # everything out of __main__, but for embedding purposes each IPython
841 # instance has its own private namespace, so we can't go shoving
844 # instance has its own private namespace, so we can't go shoving
842 # everything into __main__.
845 # everything into __main__.
843
846
844 # note, however, that we should only do this for non-embedded
847 # note, however, that we should only do this for non-embedded
845 # ipythons, which really mimic the __main__.__dict__ with their own
848 # ipythons, which really mimic the __main__.__dict__ with their own
846 # namespace. Embedded instances, on the other hand, should not do
849 # namespace. Embedded instances, on the other hand, should not do
847 # this because they need to manage the user local/global namespaces
850 # this because they need to manage the user local/global namespaces
848 # only, but they live within a 'normal' __main__ (meaning, they
851 # only, but they live within a 'normal' __main__ (meaning, they
849 # shouldn't overtake the execution environment of the script they're
852 # shouldn't overtake the execution environment of the script they're
850 # embedded in).
853 # embedded in).
851
854
852 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
855 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
853
856
854 try:
857 try:
855 main_name = self.user_ns['__name__']
858 main_name = self.user_ns['__name__']
856 except KeyError:
859 except KeyError:
857 raise KeyError('user_ns dictionary MUST have a "__name__" key')
860 raise KeyError('user_ns dictionary MUST have a "__name__" key')
858 else:
861 else:
859 sys.modules[main_name] = FakeModule(self.user_ns)
862 sys.modules[main_name] = FakeModule(self.user_ns)
860
863
861 def init_user_ns(self):
864 def init_user_ns(self):
862 """Initialize all user-visible namespaces to their minimum defaults.
865 """Initialize all user-visible namespaces to their minimum defaults.
863
866
864 Certain history lists are also initialized here, as they effectively
867 Certain history lists are also initialized here, as they effectively
865 act as user namespaces.
868 act as user namespaces.
866
869
867 Notes
870 Notes
868 -----
871 -----
869 All data structures here are only filled in, they are NOT reset by this
872 All data structures here are only filled in, they are NOT reset by this
870 method. If they were not empty before, data will simply be added to
873 method. If they were not empty before, data will simply be added to
871 therm.
874 therm.
872 """
875 """
873 # This function works in two parts: first we put a few things in
876 # This function works in two parts: first we put a few things in
874 # user_ns, and we sync that contents into user_ns_hidden so that these
877 # user_ns, and we sync that contents into user_ns_hidden so that these
875 # initial variables aren't shown by %who. After the sync, we add the
878 # initial variables aren't shown by %who. After the sync, we add the
876 # rest of what we *do* want the user to see with %who even on a new
879 # rest of what we *do* want the user to see with %who even on a new
877 # session (probably nothing, so theye really only see their own stuff)
880 # session (probably nothing, so theye really only see their own stuff)
878
881
879 # The user dict must *always* have a __builtin__ reference to the
882 # The user dict must *always* have a __builtin__ reference to the
880 # Python standard __builtin__ namespace, which must be imported.
883 # Python standard __builtin__ namespace, which must be imported.
881 # This is so that certain operations in prompt evaluation can be
884 # This is so that certain operations in prompt evaluation can be
882 # reliably executed with builtins. Note that we can NOT use
885 # reliably executed with builtins. Note that we can NOT use
883 # __builtins__ (note the 's'), because that can either be a dict or a
886 # __builtins__ (note the 's'), because that can either be a dict or a
884 # module, and can even mutate at runtime, depending on the context
887 # module, and can even mutate at runtime, depending on the context
885 # (Python makes no guarantees on it). In contrast, __builtin__ is
888 # (Python makes no guarantees on it). In contrast, __builtin__ is
886 # always a module object, though it must be explicitly imported.
889 # always a module object, though it must be explicitly imported.
887
890
888 # For more details:
891 # For more details:
889 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
892 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
890 ns = dict(__builtin__ = __builtin__)
893 ns = dict(__builtin__ = __builtin__)
891
894
892 # Put 'help' in the user namespace
895 # Put 'help' in the user namespace
893 try:
896 try:
894 from site import _Helper
897 from site import _Helper
895 ns['help'] = _Helper()
898 ns['help'] = _Helper()
896 except ImportError:
899 except ImportError:
897 warn('help() not available - check site.py')
900 warn('help() not available - check site.py')
898
901
899 # make global variables for user access to the histories
902 # make global variables for user access to the histories
900 ns['_ih'] = self.input_hist
903 ns['_ih'] = self.input_hist
901 ns['_oh'] = self.output_hist
904 ns['_oh'] = self.output_hist
902 ns['_dh'] = self.dir_hist
905 ns['_dh'] = self.dir_hist
903
906
904 ns['_sh'] = shadowns
907 ns['_sh'] = shadowns
905
908
906 # user aliases to input and output histories. These shouldn't show up
909 # user aliases to input and output histories. These shouldn't show up
907 # in %who, as they can have very large reprs.
910 # in %who, as they can have very large reprs.
908 ns['In'] = self.input_hist
911 ns['In'] = self.input_hist
909 ns['Out'] = self.output_hist
912 ns['Out'] = self.output_hist
910
913
911 # Store myself as the public api!!!
914 # Store myself as the public api!!!
912 ns['get_ipython'] = self.get_ipython
915 ns['get_ipython'] = self.get_ipython
913
916
914 # Sync what we've added so far to user_ns_hidden so these aren't seen
917 # Sync what we've added so far to user_ns_hidden so these aren't seen
915 # by %who
918 # by %who
916 self.user_ns_hidden.update(ns)
919 self.user_ns_hidden.update(ns)
917
920
918 # Anything put into ns now would show up in %who. Think twice before
921 # Anything put into ns now would show up in %who. Think twice before
919 # putting anything here, as we really want %who to show the user their
922 # putting anything here, as we really want %who to show the user their
920 # stuff, not our variables.
923 # stuff, not our variables.
921
924
922 # Finally, update the real user's namespace
925 # Finally, update the real user's namespace
923 self.user_ns.update(ns)
926 self.user_ns.update(ns)
924
927
925
928
926 def reset(self):
929 def reset(self):
927 """Clear all internal namespaces.
930 """Clear all internal namespaces.
928
931
929 Note that this is much more aggressive than %reset, since it clears
932 Note that this is much more aggressive than %reset, since it clears
930 fully all namespaces, as well as all input/output lists.
933 fully all namespaces, as well as all input/output lists.
931 """
934 """
932 for ns in self.ns_refs_table:
935 for ns in self.ns_refs_table:
933 ns.clear()
936 ns.clear()
934
937
935 self.alias_manager.clear_aliases()
938 self.alias_manager.clear_aliases()
936
939
937 # Clear input and output histories
940 # Clear input and output histories
938 self.input_hist[:] = []
941 self.input_hist[:] = []
939 self.input_hist_raw[:] = []
942 self.input_hist_raw[:] = []
940 self.output_hist.clear()
943 self.output_hist.clear()
941
944
942 # Restore the user namespaces to minimal usability
945 # Restore the user namespaces to minimal usability
943 self.init_user_ns()
946 self.init_user_ns()
944
947
945 # Restore the default and user aliases
948 # Restore the default and user aliases
946 self.alias_manager.init_aliases()
949 self.alias_manager.init_aliases()
947
950
948 def reset_selective(self, regex=None):
951 def reset_selective(self, regex=None):
949 """Clear selective variables from internal namespaces based on a specified regular expression.
952 """Clear selective variables from internal namespaces based on a specified regular expression.
950
953
951 Parameters
954 Parameters
952 ----------
955 ----------
953 regex : string or compiled pattern, optional
956 regex : string or compiled pattern, optional
954 A regular expression pattern that will be used in searching variable names in the users
957 A regular expression pattern that will be used in searching variable names in the users
955 namespaces.
958 namespaces.
956 """
959 """
957 if regex is not None:
960 if regex is not None:
958 try:
961 try:
959 m = re.compile(regex)
962 m = re.compile(regex)
960 except TypeError:
963 except TypeError:
961 raise TypeError('regex must be a string or compiled pattern')
964 raise TypeError('regex must be a string or compiled pattern')
962 # Search for keys in each namespace that match the given regex
965 # Search for keys in each namespace that match the given regex
963 # If a match is found, delete the key/value pair.
966 # If a match is found, delete the key/value pair.
964 for ns in self.ns_refs_table:
967 for ns in self.ns_refs_table:
965 for var in ns:
968 for var in ns:
966 if m.search(var):
969 if m.search(var):
967 del ns[var]
970 del ns[var]
968
971
969 def push(self, variables, interactive=True):
972 def push(self, variables, interactive=True):
970 """Inject a group of variables into the IPython user namespace.
973 """Inject a group of variables into the IPython user namespace.
971
974
972 Parameters
975 Parameters
973 ----------
976 ----------
974 variables : dict, str or list/tuple of str
977 variables : dict, str or list/tuple of str
975 The variables to inject into the user's namespace. If a dict,
978 The variables to inject into the user's namespace. If a dict,
976 a simple update is done. If a str, the string is assumed to
979 a simple update is done. If a str, the string is assumed to
977 have variable names separated by spaces. A list/tuple of str
980 have variable names separated by spaces. A list/tuple of str
978 can also be used to give the variable names. If just the variable
981 can also be used to give the variable names. If just the variable
979 names are give (list/tuple/str) then the variable values looked
982 names are give (list/tuple/str) then the variable values looked
980 up in the callers frame.
983 up in the callers frame.
981 interactive : bool
984 interactive : bool
982 If True (default), the variables will be listed with the ``who``
985 If True (default), the variables will be listed with the ``who``
983 magic.
986 magic.
984 """
987 """
985 vdict = None
988 vdict = None
986
989
987 # We need a dict of name/value pairs to do namespace updates.
990 # We need a dict of name/value pairs to do namespace updates.
988 if isinstance(variables, dict):
991 if isinstance(variables, dict):
989 vdict = variables
992 vdict = variables
990 elif isinstance(variables, (basestring, list, tuple)):
993 elif isinstance(variables, (basestring, list, tuple)):
991 if isinstance(variables, basestring):
994 if isinstance(variables, basestring):
992 vlist = variables.split()
995 vlist = variables.split()
993 else:
996 else:
994 vlist = variables
997 vlist = variables
995 vdict = {}
998 vdict = {}
996 cf = sys._getframe(1)
999 cf = sys._getframe(1)
997 for name in vlist:
1000 for name in vlist:
998 try:
1001 try:
999 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1002 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1000 except:
1003 except:
1001 print ('Could not get variable %s from %s' %
1004 print ('Could not get variable %s from %s' %
1002 (name,cf.f_code.co_name))
1005 (name,cf.f_code.co_name))
1003 else:
1006 else:
1004 raise ValueError('variables must be a dict/str/list/tuple')
1007 raise ValueError('variables must be a dict/str/list/tuple')
1005
1008
1006 # Propagate variables to user namespace
1009 # Propagate variables to user namespace
1007 self.user_ns.update(vdict)
1010 self.user_ns.update(vdict)
1008
1011
1009 # And configure interactive visibility
1012 # And configure interactive visibility
1010 config_ns = self.user_ns_hidden
1013 config_ns = self.user_ns_hidden
1011 if interactive:
1014 if interactive:
1012 for name, val in vdict.iteritems():
1015 for name, val in vdict.iteritems():
1013 config_ns.pop(name, None)
1016 config_ns.pop(name, None)
1014 else:
1017 else:
1015 for name,val in vdict.iteritems():
1018 for name,val in vdict.iteritems():
1016 config_ns[name] = val
1019 config_ns[name] = val
1017
1020
1018 #-------------------------------------------------------------------------
1021 #-------------------------------------------------------------------------
1019 # Things related to history management
1022 # Things related to history management
1020 #-------------------------------------------------------------------------
1023 #-------------------------------------------------------------------------
1021
1024
1022 def init_history(self):
1025 def init_history(self):
1023 # List of input with multi-line handling.
1026 # List of input with multi-line handling.
1024 self.input_hist = InputList()
1027 self.input_hist = InputList()
1025 # This one will hold the 'raw' input history, without any
1028 # This one will hold the 'raw' input history, without any
1026 # pre-processing. This will allow users to retrieve the input just as
1029 # pre-processing. This will allow users to retrieve the input just as
1027 # it was exactly typed in by the user, with %hist -r.
1030 # it was exactly typed in by the user, with %hist -r.
1028 self.input_hist_raw = InputList()
1031 self.input_hist_raw = InputList()
1029
1032
1030 # list of visited directories
1033 # list of visited directories
1031 try:
1034 try:
1032 self.dir_hist = [os.getcwd()]
1035 self.dir_hist = [os.getcwd()]
1033 except OSError:
1036 except OSError:
1034 self.dir_hist = []
1037 self.dir_hist = []
1035
1038
1036 # dict of output history
1039 # dict of output history
1037 self.output_hist = {}
1040 self.output_hist = {}
1038
1041
1039 # Now the history file
1042 # Now the history file
1040 if self.profile:
1043 if self.profile:
1041 histfname = 'history-%s' % self.profile
1044 histfname = 'history-%s' % self.profile
1042 else:
1045 else:
1043 histfname = 'history'
1046 histfname = 'history'
1044 self.histfile = os.path.join(self.ipython_dir, histfname)
1047 self.histfile = os.path.join(self.ipython_dir, histfname)
1045
1048
1046 # Fill the history zero entry, user counter starts at 1
1049 # Fill the history zero entry, user counter starts at 1
1047 self.input_hist.append('\n')
1050 self.input_hist.append('\n')
1048 self.input_hist_raw.append('\n')
1051 self.input_hist_raw.append('\n')
1049
1052
1050 def init_shadow_hist(self):
1053 def init_shadow_hist(self):
1051 try:
1054 try:
1052 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1055 self.db = pickleshare.PickleShareDB(self.ipython_dir + "/db")
1053 except exceptions.UnicodeDecodeError:
1056 except exceptions.UnicodeDecodeError:
1054 print "Your ipython_dir can't be decoded to unicode!"
1057 print "Your ipython_dir can't be decoded to unicode!"
1055 print "Please set HOME environment variable to something that"
1058 print "Please set HOME environment variable to something that"
1056 print r"only has ASCII characters, e.g. c:\home"
1059 print r"only has ASCII characters, e.g. c:\home"
1057 print "Now it is", self.ipython_dir
1060 print "Now it is", self.ipython_dir
1058 sys.exit()
1061 sys.exit()
1059 self.shadowhist = ipcorehist.ShadowHist(self.db)
1062 self.shadowhist = ipcorehist.ShadowHist(self.db)
1060
1063
1061 def savehist(self):
1064 def savehist(self):
1062 """Save input history to a file (via readline library)."""
1065 """Save input history to a file (via readline library)."""
1063
1066
1064 try:
1067 try:
1065 self.readline.write_history_file(self.histfile)
1068 self.readline.write_history_file(self.histfile)
1066 except:
1069 except:
1067 print 'Unable to save IPython command history to file: ' + \
1070 print 'Unable to save IPython command history to file: ' + \
1068 `self.histfile`
1071 `self.histfile`
1069
1072
1070 def reloadhist(self):
1073 def reloadhist(self):
1071 """Reload the input history from disk file."""
1074 """Reload the input history from disk file."""
1072
1075
1073 try:
1076 try:
1074 self.readline.clear_history()
1077 self.readline.clear_history()
1075 self.readline.read_history_file(self.shell.histfile)
1078 self.readline.read_history_file(self.shell.histfile)
1076 except AttributeError:
1079 except AttributeError:
1077 pass
1080 pass
1078
1081
1079 def history_saving_wrapper(self, func):
1082 def history_saving_wrapper(self, func):
1080 """ Wrap func for readline history saving
1083 """ Wrap func for readline history saving
1081
1084
1082 Convert func into callable that saves & restores
1085 Convert func into callable that saves & restores
1083 history around the call """
1086 history around the call """
1084
1087
1085 if self.has_readline:
1088 if self.has_readline:
1086 from IPython.utils import rlineimpl as readline
1089 from IPython.utils import rlineimpl as readline
1087 else:
1090 else:
1088 return func
1091 return func
1089
1092
1090 def wrapper():
1093 def wrapper():
1091 self.savehist()
1094 self.savehist()
1092 try:
1095 try:
1093 func()
1096 func()
1094 finally:
1097 finally:
1095 readline.read_history_file(self.histfile)
1098 readline.read_history_file(self.histfile)
1096 return wrapper
1099 return wrapper
1097
1100
1098 #-------------------------------------------------------------------------
1101 #-------------------------------------------------------------------------
1099 # Things related to exception handling and tracebacks (not debugging)
1102 # Things related to exception handling and tracebacks (not debugging)
1100 #-------------------------------------------------------------------------
1103 #-------------------------------------------------------------------------
1101
1104
1102 def init_traceback_handlers(self, custom_exceptions):
1105 def init_traceback_handlers(self, custom_exceptions):
1103 # Syntax error handler.
1106 # Syntax error handler.
1104 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1107 self.SyntaxTB = SyntaxTB(color_scheme='NoColor')
1105
1108
1106 # The interactive one is initialized with an offset, meaning we always
1109 # The interactive one is initialized with an offset, meaning we always
1107 # want to remove the topmost item in the traceback, which is our own
1110 # want to remove the topmost item in the traceback, which is our own
1108 # internal code. Valid modes: ['Plain','Context','Verbose']
1111 # internal code. Valid modes: ['Plain','Context','Verbose']
1109 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1112 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1110 color_scheme='NoColor',
1113 color_scheme='NoColor',
1111 tb_offset = 1)
1114 tb_offset = 1)
1112
1115
1113 # The instance will store a pointer to the system-wide exception hook,
1116 # The instance will store a pointer to the system-wide exception hook,
1114 # so that runtime code (such as magics) can access it. This is because
1117 # so that runtime code (such as magics) can access it. This is because
1115 # during the read-eval loop, it may get temporarily overwritten.
1118 # during the read-eval loop, it may get temporarily overwritten.
1116 self.sys_excepthook = sys.excepthook
1119 self.sys_excepthook = sys.excepthook
1117
1120
1118 # and add any custom exception handlers the user may have specified
1121 # and add any custom exception handlers the user may have specified
1119 self.set_custom_exc(*custom_exceptions)
1122 self.set_custom_exc(*custom_exceptions)
1120
1123
1121 # Set the exception mode
1124 # Set the exception mode
1122 self.InteractiveTB.set_mode(mode=self.xmode)
1125 self.InteractiveTB.set_mode(mode=self.xmode)
1123
1126
1124 def set_custom_exc(self,exc_tuple,handler):
1127 def set_custom_exc(self,exc_tuple,handler):
1125 """set_custom_exc(exc_tuple,handler)
1128 """set_custom_exc(exc_tuple,handler)
1126
1129
1127 Set a custom exception handler, which will be called if any of the
1130 Set a custom exception handler, which will be called if any of the
1128 exceptions in exc_tuple occur in the mainloop (specifically, in the
1131 exceptions in exc_tuple occur in the mainloop (specifically, in the
1129 runcode() method.
1132 runcode() method.
1130
1133
1131 Inputs:
1134 Inputs:
1132
1135
1133 - exc_tuple: a *tuple* of valid exceptions to call the defined
1136 - exc_tuple: a *tuple* of valid exceptions to call the defined
1134 handler for. It is very important that you use a tuple, and NOT A
1137 handler for. It is very important that you use a tuple, and NOT A
1135 LIST here, because of the way Python's except statement works. If
1138 LIST here, because of the way Python's except statement works. If
1136 you only want to trap a single exception, use a singleton tuple:
1139 you only want to trap a single exception, use a singleton tuple:
1137
1140
1138 exc_tuple == (MyCustomException,)
1141 exc_tuple == (MyCustomException,)
1139
1142
1140 - handler: this must be defined as a function with the following
1143 - handler: this must be defined as a function with the following
1141 basic interface: def my_handler(self,etype,value,tb).
1144 basic interface: def my_handler(self,etype,value,tb).
1142
1145
1143 This will be made into an instance method (via new.instancemethod)
1146 This will be made into an instance method (via new.instancemethod)
1144 of IPython itself, and it will be called if any of the exceptions
1147 of IPython itself, and it will be called if any of the exceptions
1145 listed in the exc_tuple are caught. If the handler is None, an
1148 listed in the exc_tuple are caught. If the handler is None, an
1146 internal basic one is used, which just prints basic info.
1149 internal basic one is used, which just prints basic info.
1147
1150
1148 WARNING: by putting in your own exception handler into IPython's main
1151 WARNING: by putting in your own exception handler into IPython's main
1149 execution loop, you run a very good chance of nasty crashes. This
1152 execution loop, you run a very good chance of nasty crashes. This
1150 facility should only be used if you really know what you are doing."""
1153 facility should only be used if you really know what you are doing."""
1151
1154
1152 assert type(exc_tuple)==type(()) , \
1155 assert type(exc_tuple)==type(()) , \
1153 "The custom exceptions must be given AS A TUPLE."
1156 "The custom exceptions must be given AS A TUPLE."
1154
1157
1155 def dummy_handler(self,etype,value,tb):
1158 def dummy_handler(self,etype,value,tb):
1156 print '*** Simple custom exception handler ***'
1159 print '*** Simple custom exception handler ***'
1157 print 'Exception type :',etype
1160 print 'Exception type :',etype
1158 print 'Exception value:',value
1161 print 'Exception value:',value
1159 print 'Traceback :',tb
1162 print 'Traceback :',tb
1160 print 'Source code :','\n'.join(self.buffer)
1163 print 'Source code :','\n'.join(self.buffer)
1161
1164
1162 if handler is None: handler = dummy_handler
1165 if handler is None: handler = dummy_handler
1163
1166
1164 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1167 self.CustomTB = new.instancemethod(handler,self,self.__class__)
1165 self.custom_exceptions = exc_tuple
1168 self.custom_exceptions = exc_tuple
1166
1169
1167 def excepthook(self, etype, value, tb):
1170 def excepthook(self, etype, value, tb):
1168 """One more defense for GUI apps that call sys.excepthook.
1171 """One more defense for GUI apps that call sys.excepthook.
1169
1172
1170 GUI frameworks like wxPython trap exceptions and call
1173 GUI frameworks like wxPython trap exceptions and call
1171 sys.excepthook themselves. I guess this is a feature that
1174 sys.excepthook themselves. I guess this is a feature that
1172 enables them to keep running after exceptions that would
1175 enables them to keep running after exceptions that would
1173 otherwise kill their mainloop. This is a bother for IPython
1176 otherwise kill their mainloop. This is a bother for IPython
1174 which excepts to catch all of the program exceptions with a try:
1177 which excepts to catch all of the program exceptions with a try:
1175 except: statement.
1178 except: statement.
1176
1179
1177 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1180 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1178 any app directly invokes sys.excepthook, it will look to the user like
1181 any app directly invokes sys.excepthook, it will look to the user like
1179 IPython crashed. In order to work around this, we can disable the
1182 IPython crashed. In order to work around this, we can disable the
1180 CrashHandler and replace it with this excepthook instead, which prints a
1183 CrashHandler and replace it with this excepthook instead, which prints a
1181 regular traceback using our InteractiveTB. In this fashion, apps which
1184 regular traceback using our InteractiveTB. In this fashion, apps which
1182 call sys.excepthook will generate a regular-looking exception from
1185 call sys.excepthook will generate a regular-looking exception from
1183 IPython, and the CrashHandler will only be triggered by real IPython
1186 IPython, and the CrashHandler will only be triggered by real IPython
1184 crashes.
1187 crashes.
1185
1188
1186 This hook should be used sparingly, only in places which are not likely
1189 This hook should be used sparingly, only in places which are not likely
1187 to be true IPython errors.
1190 to be true IPython errors.
1188 """
1191 """
1189 self.showtraceback((etype,value,tb),tb_offset=0)
1192 self.showtraceback((etype,value,tb),tb_offset=0)
1190
1193
1191 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1194 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1192 exception_only=False):
1195 exception_only=False):
1193 """Display the exception that just occurred.
1196 """Display the exception that just occurred.
1194
1197
1195 If nothing is known about the exception, this is the method which
1198 If nothing is known about the exception, this is the method which
1196 should be used throughout the code for presenting user tracebacks,
1199 should be used throughout the code for presenting user tracebacks,
1197 rather than directly invoking the InteractiveTB object.
1200 rather than directly invoking the InteractiveTB object.
1198
1201
1199 A specific showsyntaxerror() also exists, but this method can take
1202 A specific showsyntaxerror() also exists, but this method can take
1200 care of calling it if needed, so unless you are explicitly catching a
1203 care of calling it if needed, so unless you are explicitly catching a
1201 SyntaxError exception, don't try to analyze the stack manually and
1204 SyntaxError exception, don't try to analyze the stack manually and
1202 simply call this method."""
1205 simply call this method."""
1203
1206
1204 try:
1207 try:
1205 if exc_tuple is None:
1208 if exc_tuple is None:
1206 etype, value, tb = sys.exc_info()
1209 etype, value, tb = sys.exc_info()
1207 else:
1210 else:
1208 etype, value, tb = exc_tuple
1211 etype, value, tb = exc_tuple
1209
1212
1210 if etype is None:
1213 if etype is None:
1211 if hasattr(sys, 'last_type'):
1214 if hasattr(sys, 'last_type'):
1212 etype, value, tb = sys.last_type, sys.last_value, \
1215 etype, value, tb = sys.last_type, sys.last_value, \
1213 sys.last_traceback
1216 sys.last_traceback
1214 else:
1217 else:
1215 self.write('No traceback available to show.\n')
1218 self.write('No traceback available to show.\n')
1216 return
1219 return
1217
1220
1218 if etype is SyntaxError:
1221 if etype is SyntaxError:
1219 # Though this won't be called by syntax errors in the input
1222 # Though this won't be called by syntax errors in the input
1220 # line, there may be SyntaxError cases whith imported code.
1223 # line, there may be SyntaxError cases whith imported code.
1221 self.showsyntaxerror(filename)
1224 self.showsyntaxerror(filename)
1222 elif etype is UsageError:
1225 elif etype is UsageError:
1223 print "UsageError:", value
1226 print "UsageError:", value
1224 else:
1227 else:
1225 # WARNING: these variables are somewhat deprecated and not
1228 # WARNING: these variables are somewhat deprecated and not
1226 # necessarily safe to use in a threaded environment, but tools
1229 # necessarily safe to use in a threaded environment, but tools
1227 # like pdb depend on their existence, so let's set them. If we
1230 # like pdb depend on their existence, so let's set them. If we
1228 # find problems in the field, we'll need to revisit their use.
1231 # find problems in the field, we'll need to revisit their use.
1229 sys.last_type = etype
1232 sys.last_type = etype
1230 sys.last_value = value
1233 sys.last_value = value
1231 sys.last_traceback = tb
1234 sys.last_traceback = tb
1232
1235
1233 if etype in self.custom_exceptions:
1236 if etype in self.custom_exceptions:
1234 self.CustomTB(etype,value,tb)
1237 self.CustomTB(etype,value,tb)
1235 else:
1238 else:
1236 if exception_only:
1239 if exception_only:
1237 m = ('An exception has occurred, use %tb to see the '
1240 m = ('An exception has occurred, use %tb to see the '
1238 'full traceback.')
1241 'full traceback.')
1239 print m
1242 print m
1240 self.InteractiveTB.show_exception_only(etype, value)
1243 self.InteractiveTB.show_exception_only(etype, value)
1241 else:
1244 else:
1242 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1245 self.InteractiveTB(etype,value,tb,tb_offset=tb_offset)
1243 if self.InteractiveTB.call_pdb:
1246 if self.InteractiveTB.call_pdb:
1244 # pdb mucks up readline, fix it back
1247 # pdb mucks up readline, fix it back
1245 self.set_completer()
1248 self.set_completer()
1246
1249
1247 except KeyboardInterrupt:
1250 except KeyboardInterrupt:
1248 self.write("\nKeyboardInterrupt\n")
1251 self.write("\nKeyboardInterrupt\n")
1249
1252
1250
1253
1251 def showsyntaxerror(self, filename=None):
1254 def showsyntaxerror(self, filename=None):
1252 """Display the syntax error that just occurred.
1255 """Display the syntax error that just occurred.
1253
1256
1254 This doesn't display a stack trace because there isn't one.
1257 This doesn't display a stack trace because there isn't one.
1255
1258
1256 If a filename is given, it is stuffed in the exception instead
1259 If a filename is given, it is stuffed in the exception instead
1257 of what was there before (because Python's parser always uses
1260 of what was there before (because Python's parser always uses
1258 "<string>" when reading from a string).
1261 "<string>" when reading from a string).
1259 """
1262 """
1260 etype, value, last_traceback = sys.exc_info()
1263 etype, value, last_traceback = sys.exc_info()
1261
1264
1262 # See note about these variables in showtraceback() above
1265 # See note about these variables in showtraceback() above
1263 sys.last_type = etype
1266 sys.last_type = etype
1264 sys.last_value = value
1267 sys.last_value = value
1265 sys.last_traceback = last_traceback
1268 sys.last_traceback = last_traceback
1266
1269
1267 if filename and etype is SyntaxError:
1270 if filename and etype is SyntaxError:
1268 # Work hard to stuff the correct filename in the exception
1271 # Work hard to stuff the correct filename in the exception
1269 try:
1272 try:
1270 msg, (dummy_filename, lineno, offset, line) = value
1273 msg, (dummy_filename, lineno, offset, line) = value
1271 except:
1274 except:
1272 # Not the format we expect; leave it alone
1275 # Not the format we expect; leave it alone
1273 pass
1276 pass
1274 else:
1277 else:
1275 # Stuff in the right filename
1278 # Stuff in the right filename
1276 try:
1279 try:
1277 # Assume SyntaxError is a class exception
1280 # Assume SyntaxError is a class exception
1278 value = SyntaxError(msg, (filename, lineno, offset, line))
1281 value = SyntaxError(msg, (filename, lineno, offset, line))
1279 except:
1282 except:
1280 # If that failed, assume SyntaxError is a string
1283 # If that failed, assume SyntaxError is a string
1281 value = msg, (filename, lineno, offset, line)
1284 value = msg, (filename, lineno, offset, line)
1282 self.SyntaxTB(etype,value,[])
1285 self.SyntaxTB(etype,value,[])
1283
1286
1284 #-------------------------------------------------------------------------
1287 #-------------------------------------------------------------------------
1285 # Things related to tab completion
1288 # Things related to tab completion
1286 #-------------------------------------------------------------------------
1289 #-------------------------------------------------------------------------
1287
1290
1288 def complete(self, text):
1291 def complete(self, text):
1289 """Return a sorted list of all possible completions on text.
1292 """Return a sorted list of all possible completions on text.
1290
1293
1291 Inputs:
1294 Inputs:
1292
1295
1293 - text: a string of text to be completed on.
1296 - text: a string of text to be completed on.
1294
1297
1295 This is a wrapper around the completion mechanism, similar to what
1298 This is a wrapper around the completion mechanism, similar to what
1296 readline does at the command line when the TAB key is hit. By
1299 readline does at the command line when the TAB key is hit. By
1297 exposing it as a method, it can be used by other non-readline
1300 exposing it as a method, it can be used by other non-readline
1298 environments (such as GUIs) for text completion.
1301 environments (such as GUIs) for text completion.
1299
1302
1300 Simple usage example:
1303 Simple usage example:
1301
1304
1302 In [7]: x = 'hello'
1305 In [7]: x = 'hello'
1303
1306
1304 In [8]: x
1307 In [8]: x
1305 Out[8]: 'hello'
1308 Out[8]: 'hello'
1306
1309
1307 In [9]: print x
1310 In [9]: print x
1308 hello
1311 hello
1309
1312
1310 In [10]: _ip.complete('x.l')
1313 In [10]: _ip.complete('x.l')
1311 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1314 Out[10]: ['x.ljust', 'x.lower', 'x.lstrip']
1312 """
1315 """
1313
1316
1314 # Inject names into __builtin__ so we can complete on the added names.
1317 # Inject names into __builtin__ so we can complete on the added names.
1315 with self.builtin_trap:
1318 with self.builtin_trap:
1316 complete = self.Completer.complete
1319 complete = self.Completer.complete
1317 state = 0
1320 state = 0
1318 # use a dict so we get unique keys, since ipyhton's multiple
1321 # use a dict so we get unique keys, since ipyhton's multiple
1319 # completers can return duplicates. When we make 2.4 a requirement,
1322 # completers can return duplicates. When we make 2.4 a requirement,
1320 # start using sets instead, which are faster.
1323 # start using sets instead, which are faster.
1321 comps = {}
1324 comps = {}
1322 while True:
1325 while True:
1323 newcomp = complete(text,state,line_buffer=text)
1326 newcomp = complete(text,state,line_buffer=text)
1324 if newcomp is None:
1327 if newcomp is None:
1325 break
1328 break
1326 comps[newcomp] = 1
1329 comps[newcomp] = 1
1327 state += 1
1330 state += 1
1328 outcomps = comps.keys()
1331 outcomps = comps.keys()
1329 outcomps.sort()
1332 outcomps.sort()
1330 #print "T:",text,"OC:",outcomps # dbg
1333 #print "T:",text,"OC:",outcomps # dbg
1331 #print "vars:",self.user_ns.keys()
1334 #print "vars:",self.user_ns.keys()
1332 return outcomps
1335 return outcomps
1333
1336
1334 def set_custom_completer(self,completer,pos=0):
1337 def set_custom_completer(self,completer,pos=0):
1335 """Adds a new custom completer function.
1338 """Adds a new custom completer function.
1336
1339
1337 The position argument (defaults to 0) is the index in the completers
1340 The position argument (defaults to 0) is the index in the completers
1338 list where you want the completer to be inserted."""
1341 list where you want the completer to be inserted."""
1339
1342
1340 newcomp = new.instancemethod(completer,self.Completer,
1343 newcomp = new.instancemethod(completer,self.Completer,
1341 self.Completer.__class__)
1344 self.Completer.__class__)
1342 self.Completer.matchers.insert(pos,newcomp)
1345 self.Completer.matchers.insert(pos,newcomp)
1343
1346
1344 def set_completer(self):
1347 def set_completer(self):
1345 """Reset readline's completer to be our own."""
1348 """Reset readline's completer to be our own."""
1346 self.readline.set_completer(self.Completer.complete)
1349 self.readline.set_completer(self.Completer.complete)
1347
1350
1348 def set_completer_frame(self, frame=None):
1351 def set_completer_frame(self, frame=None):
1349 """Set the frame of the completer."""
1352 """Set the frame of the completer."""
1350 if frame:
1353 if frame:
1351 self.Completer.namespace = frame.f_locals
1354 self.Completer.namespace = frame.f_locals
1352 self.Completer.global_namespace = frame.f_globals
1355 self.Completer.global_namespace = frame.f_globals
1353 else:
1356 else:
1354 self.Completer.namespace = self.user_ns
1357 self.Completer.namespace = self.user_ns
1355 self.Completer.global_namespace = self.user_global_ns
1358 self.Completer.global_namespace = self.user_global_ns
1356
1359
1357 #-------------------------------------------------------------------------
1360 #-------------------------------------------------------------------------
1358 # Things related to readline
1361 # Things related to readline
1359 #-------------------------------------------------------------------------
1362 #-------------------------------------------------------------------------
1360
1363
1361 def init_readline(self):
1364 def init_readline(self):
1362 """Command history completion/saving/reloading."""
1365 """Command history completion/saving/reloading."""
1363
1366
1364 if self.readline_use:
1367 if self.readline_use:
1365 import IPython.utils.rlineimpl as readline
1368 import IPython.utils.rlineimpl as readline
1366
1369
1367 self.rl_next_input = None
1370 self.rl_next_input = None
1368 self.rl_do_indent = False
1371 self.rl_do_indent = False
1369
1372
1370 if not self.readline_use or not readline.have_readline:
1373 if not self.readline_use or not readline.have_readline:
1371 self.has_readline = False
1374 self.has_readline = False
1372 self.readline = None
1375 self.readline = None
1373 # Set a number of methods that depend on readline to be no-op
1376 # Set a number of methods that depend on readline to be no-op
1374 self.savehist = no_op
1377 self.savehist = no_op
1375 self.reloadhist = no_op
1378 self.reloadhist = no_op
1376 self.set_completer = no_op
1379 self.set_completer = no_op
1377 self.set_custom_completer = no_op
1380 self.set_custom_completer = no_op
1378 self.set_completer_frame = no_op
1381 self.set_completer_frame = no_op
1379 warn('Readline services not available or not loaded.')
1382 warn('Readline services not available or not loaded.')
1380 else:
1383 else:
1381 self.has_readline = True
1384 self.has_readline = True
1382 self.readline = readline
1385 self.readline = readline
1383 sys.modules['readline'] = readline
1386 sys.modules['readline'] = readline
1384 import atexit
1387 import atexit
1385 from IPython.core.completer import IPCompleter
1388 from IPython.core.completer import IPCompleter
1386 self.Completer = IPCompleter(self,
1389 self.Completer = IPCompleter(self,
1387 self.user_ns,
1390 self.user_ns,
1388 self.user_global_ns,
1391 self.user_global_ns,
1389 self.readline_omit__names,
1392 self.readline_omit__names,
1390 self.alias_manager.alias_table)
1393 self.alias_manager.alias_table)
1391 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1394 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1392 self.strdispatchers['complete_command'] = sdisp
1395 self.strdispatchers['complete_command'] = sdisp
1393 self.Completer.custom_completers = sdisp
1396 self.Completer.custom_completers = sdisp
1394 # Platform-specific configuration
1397 # Platform-specific configuration
1395 if os.name == 'nt':
1398 if os.name == 'nt':
1396 self.readline_startup_hook = readline.set_pre_input_hook
1399 self.readline_startup_hook = readline.set_pre_input_hook
1397 else:
1400 else:
1398 self.readline_startup_hook = readline.set_startup_hook
1401 self.readline_startup_hook = readline.set_startup_hook
1399
1402
1400 # Load user's initrc file (readline config)
1403 # Load user's initrc file (readline config)
1401 # Or if libedit is used, load editrc.
1404 # Or if libedit is used, load editrc.
1402 inputrc_name = os.environ.get('INPUTRC')
1405 inputrc_name = os.environ.get('INPUTRC')
1403 if inputrc_name is None:
1406 if inputrc_name is None:
1404 home_dir = get_home_dir()
1407 home_dir = get_home_dir()
1405 if home_dir is not None:
1408 if home_dir is not None:
1406 inputrc_name = '.inputrc'
1409 inputrc_name = '.inputrc'
1407 if readline.uses_libedit:
1410 if readline.uses_libedit:
1408 inputrc_name = '.editrc'
1411 inputrc_name = '.editrc'
1409 inputrc_name = os.path.join(home_dir, inputrc_name)
1412 inputrc_name = os.path.join(home_dir, inputrc_name)
1410 if os.path.isfile(inputrc_name):
1413 if os.path.isfile(inputrc_name):
1411 try:
1414 try:
1412 readline.read_init_file(inputrc_name)
1415 readline.read_init_file(inputrc_name)
1413 except:
1416 except:
1414 warn('Problems reading readline initialization file <%s>'
1417 warn('Problems reading readline initialization file <%s>'
1415 % inputrc_name)
1418 % inputrc_name)
1416
1419
1417 # save this in sys so embedded copies can restore it properly
1420 # save this in sys so embedded copies can restore it properly
1418 sys.ipcompleter = self.Completer.complete
1421 sys.ipcompleter = self.Completer.complete
1419 self.set_completer()
1422 self.set_completer()
1420
1423
1421 # Configure readline according to user's prefs
1424 # Configure readline according to user's prefs
1422 # This is only done if GNU readline is being used. If libedit
1425 # This is only done if GNU readline is being used. If libedit
1423 # is being used (as on Leopard) the readline config is
1426 # is being used (as on Leopard) the readline config is
1424 # not run as the syntax for libedit is different.
1427 # not run as the syntax for libedit is different.
1425 if not readline.uses_libedit:
1428 if not readline.uses_libedit:
1426 for rlcommand in self.readline_parse_and_bind:
1429 for rlcommand in self.readline_parse_and_bind:
1427 #print "loading rl:",rlcommand # dbg
1430 #print "loading rl:",rlcommand # dbg
1428 readline.parse_and_bind(rlcommand)
1431 readline.parse_and_bind(rlcommand)
1429
1432
1430 # Remove some chars from the delimiters list. If we encounter
1433 # Remove some chars from the delimiters list. If we encounter
1431 # unicode chars, discard them.
1434 # unicode chars, discard them.
1432 delims = readline.get_completer_delims().encode("ascii", "ignore")
1435 delims = readline.get_completer_delims().encode("ascii", "ignore")
1433 delims = delims.translate(string._idmap,
1436 delims = delims.translate(string._idmap,
1434 self.readline_remove_delims)
1437 self.readline_remove_delims)
1435 readline.set_completer_delims(delims)
1438 readline.set_completer_delims(delims)
1436 # otherwise we end up with a monster history after a while:
1439 # otherwise we end up with a monster history after a while:
1437 readline.set_history_length(1000)
1440 readline.set_history_length(1000)
1438 try:
1441 try:
1439 #print '*** Reading readline history' # dbg
1442 #print '*** Reading readline history' # dbg
1440 readline.read_history_file(self.histfile)
1443 readline.read_history_file(self.histfile)
1441 except IOError:
1444 except IOError:
1442 pass # It doesn't exist yet.
1445 pass # It doesn't exist yet.
1443
1446
1444 atexit.register(self.atexit_operations)
1447 atexit.register(self.atexit_operations)
1445 del atexit
1448 del atexit
1446
1449
1447 # Configure auto-indent for all platforms
1450 # Configure auto-indent for all platforms
1448 self.set_autoindent(self.autoindent)
1451 self.set_autoindent(self.autoindent)
1449
1452
1450 def set_next_input(self, s):
1453 def set_next_input(self, s):
1451 """ Sets the 'default' input string for the next command line.
1454 """ Sets the 'default' input string for the next command line.
1452
1455
1453 Requires readline.
1456 Requires readline.
1454
1457
1455 Example:
1458 Example:
1456
1459
1457 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1460 [D:\ipython]|1> _ip.set_next_input("Hello Word")
1458 [D:\ipython]|2> Hello Word_ # cursor is here
1461 [D:\ipython]|2> Hello Word_ # cursor is here
1459 """
1462 """
1460
1463
1461 self.rl_next_input = s
1464 self.rl_next_input = s
1462
1465
1463 # Maybe move this to the terminal subclass?
1466 # Maybe move this to the terminal subclass?
1464 def pre_readline(self):
1467 def pre_readline(self):
1465 """readline hook to be used at the start of each line.
1468 """readline hook to be used at the start of each line.
1466
1469
1467 Currently it handles auto-indent only."""
1470 Currently it handles auto-indent only."""
1468
1471
1469 if self.rl_do_indent:
1472 if self.rl_do_indent:
1470 self.readline.insert_text(self._indent_current_str())
1473 self.readline.insert_text(self._indent_current_str())
1471 if self.rl_next_input is not None:
1474 if self.rl_next_input is not None:
1472 self.readline.insert_text(self.rl_next_input)
1475 self.readline.insert_text(self.rl_next_input)
1473 self.rl_next_input = None
1476 self.rl_next_input = None
1474
1477
1475 def _indent_current_str(self):
1478 def _indent_current_str(self):
1476 """return the current level of indentation as a string"""
1479 """return the current level of indentation as a string"""
1477 return self.indent_current_nsp * ' '
1480 return self.indent_current_nsp * ' '
1478
1481
1479 #-------------------------------------------------------------------------
1482 #-------------------------------------------------------------------------
1480 # Things related to magics
1483 # Things related to magics
1481 #-------------------------------------------------------------------------
1484 #-------------------------------------------------------------------------
1482
1485
1483 def init_magics(self):
1486 def init_magics(self):
1484 # FIXME: Move the color initialization to the DisplayHook, which
1487 # FIXME: Move the color initialization to the DisplayHook, which
1485 # should be split into a prompt manager and displayhook. We probably
1488 # should be split into a prompt manager and displayhook. We probably
1486 # even need a centralize colors management object.
1489 # even need a centralize colors management object.
1487 self.magic_colors(self.colors)
1490 self.magic_colors(self.colors)
1488 # History was moved to a separate module
1491 # History was moved to a separate module
1489 from . import history
1492 from . import history
1490 history.init_ipython(self)
1493 history.init_ipython(self)
1491
1494
1492 def magic(self,arg_s):
1495 def magic(self,arg_s):
1493 """Call a magic function by name.
1496 """Call a magic function by name.
1494
1497
1495 Input: a string containing the name of the magic function to call and any
1498 Input: a string containing the name of the magic function to call and any
1496 additional arguments to be passed to the magic.
1499 additional arguments to be passed to the magic.
1497
1500
1498 magic('name -opt foo bar') is equivalent to typing at the ipython
1501 magic('name -opt foo bar') is equivalent to typing at the ipython
1499 prompt:
1502 prompt:
1500
1503
1501 In[1]: %name -opt foo bar
1504 In[1]: %name -opt foo bar
1502
1505
1503 To call a magic without arguments, simply use magic('name').
1506 To call a magic without arguments, simply use magic('name').
1504
1507
1505 This provides a proper Python function to call IPython's magics in any
1508 This provides a proper Python function to call IPython's magics in any
1506 valid Python code you can type at the interpreter, including loops and
1509 valid Python code you can type at the interpreter, including loops and
1507 compound statements.
1510 compound statements.
1508 """
1511 """
1509 args = arg_s.split(' ',1)
1512 args = arg_s.split(' ',1)
1510 magic_name = args[0]
1513 magic_name = args[0]
1511 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1514 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
1512
1515
1513 try:
1516 try:
1514 magic_args = args[1]
1517 magic_args = args[1]
1515 except IndexError:
1518 except IndexError:
1516 magic_args = ''
1519 magic_args = ''
1517 fn = getattr(self,'magic_'+magic_name,None)
1520 fn = getattr(self,'magic_'+magic_name,None)
1518 if fn is None:
1521 if fn is None:
1519 error("Magic function `%s` not found." % magic_name)
1522 error("Magic function `%s` not found." % magic_name)
1520 else:
1523 else:
1521 magic_args = self.var_expand(magic_args,1)
1524 magic_args = self.var_expand(magic_args,1)
1522 with nested(self.builtin_trap,):
1525 with nested(self.builtin_trap,):
1523 result = fn(magic_args)
1526 result = fn(magic_args)
1524 return result
1527 return result
1525
1528
1526 def define_magic(self, magicname, func):
1529 def define_magic(self, magicname, func):
1527 """Expose own function as magic function for ipython
1530 """Expose own function as magic function for ipython
1528
1531
1529 def foo_impl(self,parameter_s=''):
1532 def foo_impl(self,parameter_s=''):
1530 'My very own magic!. (Use docstrings, IPython reads them).'
1533 'My very own magic!. (Use docstrings, IPython reads them).'
1531 print 'Magic function. Passed parameter is between < >:'
1534 print 'Magic function. Passed parameter is between < >:'
1532 print '<%s>' % parameter_s
1535 print '<%s>' % parameter_s
1533 print 'The self object is:',self
1536 print 'The self object is:',self
1534
1537
1535 self.define_magic('foo',foo_impl)
1538 self.define_magic('foo',foo_impl)
1536 """
1539 """
1537
1540
1538 import new
1541 import new
1539 im = new.instancemethod(func,self, self.__class__)
1542 im = new.instancemethod(func,self, self.__class__)
1540 old = getattr(self, "magic_" + magicname, None)
1543 old = getattr(self, "magic_" + magicname, None)
1541 setattr(self, "magic_" + magicname, im)
1544 setattr(self, "magic_" + magicname, im)
1542 return old
1545 return old
1543
1546
1544 #-------------------------------------------------------------------------
1547 #-------------------------------------------------------------------------
1545 # Things related to macros
1548 # Things related to macros
1546 #-------------------------------------------------------------------------
1549 #-------------------------------------------------------------------------
1547
1550
1548 def define_macro(self, name, themacro):
1551 def define_macro(self, name, themacro):
1549 """Define a new macro
1552 """Define a new macro
1550
1553
1551 Parameters
1554 Parameters
1552 ----------
1555 ----------
1553 name : str
1556 name : str
1554 The name of the macro.
1557 The name of the macro.
1555 themacro : str or Macro
1558 themacro : str or Macro
1556 The action to do upon invoking the macro. If a string, a new
1559 The action to do upon invoking the macro. If a string, a new
1557 Macro object is created by passing the string to it.
1560 Macro object is created by passing the string to it.
1558 """
1561 """
1559
1562
1560 from IPython.core import macro
1563 from IPython.core import macro
1561
1564
1562 if isinstance(themacro, basestring):
1565 if isinstance(themacro, basestring):
1563 themacro = macro.Macro(themacro)
1566 themacro = macro.Macro(themacro)
1564 if not isinstance(themacro, macro.Macro):
1567 if not isinstance(themacro, macro.Macro):
1565 raise ValueError('A macro must be a string or a Macro instance.')
1568 raise ValueError('A macro must be a string or a Macro instance.')
1566 self.user_ns[name] = themacro
1569 self.user_ns[name] = themacro
1567
1570
1568 #-------------------------------------------------------------------------
1571 #-------------------------------------------------------------------------
1569 # Things related to the running of system commands
1572 # Things related to the running of system commands
1570 #-------------------------------------------------------------------------
1573 #-------------------------------------------------------------------------
1571
1574
1572 def system(self, cmd):
1575 def system(self, cmd):
1573 """Make a system call, using IPython."""
1576 """Make a system call, using IPython."""
1574 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1577 return self.hooks.shell_hook(self.var_expand(cmd, depth=2))
1575
1578
1576 #-------------------------------------------------------------------------
1579 #-------------------------------------------------------------------------
1577 # Things related to aliases
1580 # Things related to aliases
1578 #-------------------------------------------------------------------------
1581 #-------------------------------------------------------------------------
1579
1582
1580 def init_alias(self):
1583 def init_alias(self):
1581 self.alias_manager = AliasManager(shell=self, config=self.config)
1584 self.alias_manager = AliasManager(shell=self, config=self.config)
1582 self.ns_table['alias'] = self.alias_manager.alias_table,
1585 self.ns_table['alias'] = self.alias_manager.alias_table,
1583
1586
1584 #-------------------------------------------------------------------------
1587 #-------------------------------------------------------------------------
1585 # Things related to extensions and plugins
1588 # Things related to extensions and plugins
1586 #-------------------------------------------------------------------------
1589 #-------------------------------------------------------------------------
1587
1590
1588 def init_extension_manager(self):
1591 def init_extension_manager(self):
1589 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1592 self.extension_manager = ExtensionManager(shell=self, config=self.config)
1590
1593
1591 def init_plugin_manager(self):
1594 def init_plugin_manager(self):
1592 self.plugin_manager = PluginManager(config=self.config)
1595 self.plugin_manager = PluginManager(config=self.config)
1593
1596
1594 #-------------------------------------------------------------------------
1597 #-------------------------------------------------------------------------
1595 # Things related to the prefilter
1598 # Things related to the prefilter
1596 #-------------------------------------------------------------------------
1599 #-------------------------------------------------------------------------
1597
1600
1598 def init_prefilter(self):
1601 def init_prefilter(self):
1599 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1602 self.prefilter_manager = PrefilterManager(shell=self, config=self.config)
1600 # Ultimately this will be refactored in the new interpreter code, but
1603 # Ultimately this will be refactored in the new interpreter code, but
1601 # for now, we should expose the main prefilter method (there's legacy
1604 # for now, we should expose the main prefilter method (there's legacy
1602 # code out there that may rely on this).
1605 # code out there that may rely on this).
1603 self.prefilter = self.prefilter_manager.prefilter_lines
1606 self.prefilter = self.prefilter_manager.prefilter_lines
1604
1607
1605 #-------------------------------------------------------------------------
1608 #-------------------------------------------------------------------------
1606 # Things related to the running of code
1609 # Things related to the running of code
1607 #-------------------------------------------------------------------------
1610 #-------------------------------------------------------------------------
1608
1611
1609 def ex(self, cmd):
1612 def ex(self, cmd):
1610 """Execute a normal python statement in user namespace."""
1613 """Execute a normal python statement in user namespace."""
1611 with nested(self.builtin_trap,):
1614 with nested(self.builtin_trap,):
1612 exec cmd in self.user_global_ns, self.user_ns
1615 exec cmd in self.user_global_ns, self.user_ns
1613
1616
1614 def ev(self, expr):
1617 def ev(self, expr):
1615 """Evaluate python expression expr in user namespace.
1618 """Evaluate python expression expr in user namespace.
1616
1619
1617 Returns the result of evaluation
1620 Returns the result of evaluation
1618 """
1621 """
1619 with nested(self.builtin_trap,):
1622 with nested(self.builtin_trap,):
1620 return eval(expr, self.user_global_ns, self.user_ns)
1623 return eval(expr, self.user_global_ns, self.user_ns)
1621
1624
1622 def safe_execfile(self, fname, *where, **kw):
1625 def safe_execfile(self, fname, *where, **kw):
1623 """A safe version of the builtin execfile().
1626 """A safe version of the builtin execfile().
1624
1627
1625 This version will never throw an exception, but instead print
1628 This version will never throw an exception, but instead print
1626 helpful error messages to the screen. This only works on pure
1629 helpful error messages to the screen. This only works on pure
1627 Python files with the .py extension.
1630 Python files with the .py extension.
1628
1631
1629 Parameters
1632 Parameters
1630 ----------
1633 ----------
1631 fname : string
1634 fname : string
1632 The name of the file to be executed.
1635 The name of the file to be executed.
1633 where : tuple
1636 where : tuple
1634 One or two namespaces, passed to execfile() as (globals,locals).
1637 One or two namespaces, passed to execfile() as (globals,locals).
1635 If only one is given, it is passed as both.
1638 If only one is given, it is passed as both.
1636 exit_ignore : bool (False)
1639 exit_ignore : bool (False)
1637 If True, then silence SystemExit for non-zero status (it is always
1640 If True, then silence SystemExit for non-zero status (it is always
1638 silenced for zero status, as it is so common).
1641 silenced for zero status, as it is so common).
1639 """
1642 """
1640 kw.setdefault('exit_ignore', False)
1643 kw.setdefault('exit_ignore', False)
1641
1644
1642 fname = os.path.abspath(os.path.expanduser(fname))
1645 fname = os.path.abspath(os.path.expanduser(fname))
1643
1646
1644 # Make sure we have a .py file
1647 # Make sure we have a .py file
1645 if not fname.endswith('.py'):
1648 if not fname.endswith('.py'):
1646 warn('File must end with .py to be run using execfile: <%s>' % fname)
1649 warn('File must end with .py to be run using execfile: <%s>' % fname)
1647
1650
1648 # Make sure we can open the file
1651 # Make sure we can open the file
1649 try:
1652 try:
1650 with open(fname) as thefile:
1653 with open(fname) as thefile:
1651 pass
1654 pass
1652 except:
1655 except:
1653 warn('Could not open file <%s> for safe execution.' % fname)
1656 warn('Could not open file <%s> for safe execution.' % fname)
1654 return
1657 return
1655
1658
1656 # Find things also in current directory. This is needed to mimic the
1659 # Find things also in current directory. This is needed to mimic the
1657 # behavior of running a script from the system command line, where
1660 # behavior of running a script from the system command line, where
1658 # Python inserts the script's directory into sys.path
1661 # Python inserts the script's directory into sys.path
1659 dname = os.path.dirname(fname)
1662 dname = os.path.dirname(fname)
1660
1663
1661 with prepended_to_syspath(dname):
1664 with prepended_to_syspath(dname):
1662 try:
1665 try:
1663 execfile(fname,*where)
1666 execfile(fname,*where)
1664 except SystemExit, status:
1667 except SystemExit, status:
1665 # If the call was made with 0 or None exit status (sys.exit(0)
1668 # If the call was made with 0 or None exit status (sys.exit(0)
1666 # or sys.exit() ), don't bother showing a traceback, as both of
1669 # or sys.exit() ), don't bother showing a traceback, as both of
1667 # these are considered normal by the OS:
1670 # these are considered normal by the OS:
1668 # > python -c'import sys;sys.exit(0)'; echo $?
1671 # > python -c'import sys;sys.exit(0)'; echo $?
1669 # 0
1672 # 0
1670 # > python -c'import sys;sys.exit()'; echo $?
1673 # > python -c'import sys;sys.exit()'; echo $?
1671 # 0
1674 # 0
1672 # For other exit status, we show the exception unless
1675 # For other exit status, we show the exception unless
1673 # explicitly silenced, but only in short form.
1676 # explicitly silenced, but only in short form.
1674 if status.code not in (0, None) and not kw['exit_ignore']:
1677 if status.code not in (0, None) and not kw['exit_ignore']:
1675 self.showtraceback(exception_only=True)
1678 self.showtraceback(exception_only=True)
1676 except:
1679 except:
1677 self.showtraceback()
1680 self.showtraceback()
1678
1681
1679 def safe_execfile_ipy(self, fname):
1682 def safe_execfile_ipy(self, fname):
1680 """Like safe_execfile, but for .ipy files with IPython syntax.
1683 """Like safe_execfile, but for .ipy files with IPython syntax.
1681
1684
1682 Parameters
1685 Parameters
1683 ----------
1686 ----------
1684 fname : str
1687 fname : str
1685 The name of the file to execute. The filename must have a
1688 The name of the file to execute. The filename must have a
1686 .ipy extension.
1689 .ipy extension.
1687 """
1690 """
1688 fname = os.path.abspath(os.path.expanduser(fname))
1691 fname = os.path.abspath(os.path.expanduser(fname))
1689
1692
1690 # Make sure we have a .py file
1693 # Make sure we have a .py file
1691 if not fname.endswith('.ipy'):
1694 if not fname.endswith('.ipy'):
1692 warn('File must end with .py to be run using execfile: <%s>' % fname)
1695 warn('File must end with .py to be run using execfile: <%s>' % fname)
1693
1696
1694 # Make sure we can open the file
1697 # Make sure we can open the file
1695 try:
1698 try:
1696 with open(fname) as thefile:
1699 with open(fname) as thefile:
1697 pass
1700 pass
1698 except:
1701 except:
1699 warn('Could not open file <%s> for safe execution.' % fname)
1702 warn('Could not open file <%s> for safe execution.' % fname)
1700 return
1703 return
1701
1704
1702 # Find things also in current directory. This is needed to mimic the
1705 # Find things also in current directory. This is needed to mimic the
1703 # behavior of running a script from the system command line, where
1706 # behavior of running a script from the system command line, where
1704 # Python inserts the script's directory into sys.path
1707 # Python inserts the script's directory into sys.path
1705 dname = os.path.dirname(fname)
1708 dname = os.path.dirname(fname)
1706
1709
1707 with prepended_to_syspath(dname):
1710 with prepended_to_syspath(dname):
1708 try:
1711 try:
1709 with open(fname) as thefile:
1712 with open(fname) as thefile:
1710 script = thefile.read()
1713 script = thefile.read()
1711 # self.runlines currently captures all exceptions
1714 # self.runlines currently captures all exceptions
1712 # raise in user code. It would be nice if there were
1715 # raise in user code. It would be nice if there were
1713 # versions of runlines, execfile that did raise, so
1716 # versions of runlines, execfile that did raise, so
1714 # we could catch the errors.
1717 # we could catch the errors.
1715 self.runlines(script, clean=True)
1718 self.runlines(script, clean=True)
1716 except:
1719 except:
1717 self.showtraceback()
1720 self.showtraceback()
1718 warn('Unknown failure executing file: <%s>' % fname)
1721 warn('Unknown failure executing file: <%s>' % fname)
1719
1722
1720 def runlines(self, lines, clean=False):
1723 def runlines(self, lines, clean=False):
1721 """Run a string of one or more lines of source.
1724 """Run a string of one or more lines of source.
1722
1725
1723 This method is capable of running a string containing multiple source
1726 This method is capable of running a string containing multiple source
1724 lines, as if they had been entered at the IPython prompt. Since it
1727 lines, as if they had been entered at the IPython prompt. Since it
1725 exposes IPython's processing machinery, the given strings can contain
1728 exposes IPython's processing machinery, the given strings can contain
1726 magic calls (%magic), special shell access (!cmd), etc.
1729 magic calls (%magic), special shell access (!cmd), etc.
1727 """
1730 """
1728
1731
1729 if isinstance(lines, (list, tuple)):
1732 if isinstance(lines, (list, tuple)):
1730 lines = '\n'.join(lines)
1733 lines = '\n'.join(lines)
1731
1734
1732 if clean:
1735 if clean:
1733 lines = self._cleanup_ipy_script(lines)
1736 lines = self._cleanup_ipy_script(lines)
1734
1737
1735 # We must start with a clean buffer, in case this is run from an
1738 # We must start with a clean buffer, in case this is run from an
1736 # interactive IPython session (via a magic, for example).
1739 # interactive IPython session (via a magic, for example).
1737 self.resetbuffer()
1740 self.resetbuffer()
1738 lines = lines.splitlines()
1741 lines = lines.splitlines()
1739 more = 0
1742 more = 0
1740
1743
1741 with nested(self.builtin_trap, self.display_trap):
1744 with nested(self.builtin_trap, self.display_trap):
1742 for line in lines:
1745 for line in lines:
1743 # skip blank lines so we don't mess up the prompt counter, but do
1746 # skip blank lines so we don't mess up the prompt counter, but do
1744 # NOT skip even a blank line if we are in a code block (more is
1747 # NOT skip even a blank line if we are in a code block (more is
1745 # true)
1748 # true)
1746
1749
1747 if line or more:
1750 if line or more:
1748 # push to raw history, so hist line numbers stay in sync
1751 # push to raw history, so hist line numbers stay in sync
1749 self.input_hist_raw.append("# " + line + "\n")
1752 self.input_hist_raw.append("# " + line + "\n")
1750 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1753 prefiltered = self.prefilter_manager.prefilter_lines(line,more)
1751 more = self.push_line(prefiltered)
1754 more = self.push_line(prefiltered)
1752 # IPython's runsource returns None if there was an error
1755 # IPython's runsource returns None if there was an error
1753 # compiling the code. This allows us to stop processing right
1756 # compiling the code. This allows us to stop processing right
1754 # away, so the user gets the error message at the right place.
1757 # away, so the user gets the error message at the right place.
1755 if more is None:
1758 if more is None:
1756 break
1759 break
1757 else:
1760 else:
1758 self.input_hist_raw.append("\n")
1761 self.input_hist_raw.append("\n")
1759 # final newline in case the input didn't have it, so that the code
1762 # final newline in case the input didn't have it, so that the code
1760 # actually does get executed
1763 # actually does get executed
1761 if more:
1764 if more:
1762 self.push_line('\n')
1765 self.push_line('\n')
1763
1766
1764 def runsource(self, source, filename='<input>', symbol='single'):
1767 def runsource(self, source, filename='<input>', symbol='single'):
1765 """Compile and run some source in the interpreter.
1768 """Compile and run some source in the interpreter.
1766
1769
1767 Arguments are as for compile_command().
1770 Arguments are as for compile_command().
1768
1771
1769 One several things can happen:
1772 One several things can happen:
1770
1773
1771 1) The input is incorrect; compile_command() raised an
1774 1) The input is incorrect; compile_command() raised an
1772 exception (SyntaxError or OverflowError). A syntax traceback
1775 exception (SyntaxError or OverflowError). A syntax traceback
1773 will be printed by calling the showsyntaxerror() method.
1776 will be printed by calling the showsyntaxerror() method.
1774
1777
1775 2) The input is incomplete, and more input is required;
1778 2) The input is incomplete, and more input is required;
1776 compile_command() returned None. Nothing happens.
1779 compile_command() returned None. Nothing happens.
1777
1780
1778 3) The input is complete; compile_command() returned a code
1781 3) The input is complete; compile_command() returned a code
1779 object. The code is executed by calling self.runcode() (which
1782 object. The code is executed by calling self.runcode() (which
1780 also handles run-time exceptions, except for SystemExit).
1783 also handles run-time exceptions, except for SystemExit).
1781
1784
1782 The return value is:
1785 The return value is:
1783
1786
1784 - True in case 2
1787 - True in case 2
1785
1788
1786 - False in the other cases, unless an exception is raised, where
1789 - False in the other cases, unless an exception is raised, where
1787 None is returned instead. This can be used by external callers to
1790 None is returned instead. This can be used by external callers to
1788 know whether to continue feeding input or not.
1791 know whether to continue feeding input or not.
1789
1792
1790 The return value can be used to decide whether to use sys.ps1 or
1793 The return value can be used to decide whether to use sys.ps1 or
1791 sys.ps2 to prompt the next line."""
1794 sys.ps2 to prompt the next line."""
1792
1795
1793 # if the source code has leading blanks, add 'if 1:\n' to it
1796 # if the source code has leading blanks, add 'if 1:\n' to it
1794 # this allows execution of indented pasted code. It is tempting
1797 # this allows execution of indented pasted code. It is tempting
1795 # to add '\n' at the end of source to run commands like ' a=1'
1798 # to add '\n' at the end of source to run commands like ' a=1'
1796 # directly, but this fails for more complicated scenarios
1799 # directly, but this fails for more complicated scenarios
1797 source=source.encode(self.stdin_encoding)
1800 source=source.encode(self.stdin_encoding)
1798 if source[:1] in [' ', '\t']:
1801 if source[:1] in [' ', '\t']:
1799 source = 'if 1:\n%s' % source
1802 source = 'if 1:\n%s' % source
1800
1803
1801 try:
1804 try:
1802 code = self.compile(source,filename,symbol)
1805 code = self.compile(source,filename,symbol)
1803 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1806 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
1804 # Case 1
1807 # Case 1
1805 self.showsyntaxerror(filename)
1808 self.showsyntaxerror(filename)
1806 return None
1809 return None
1807
1810
1808 if code is None:
1811 if code is None:
1809 # Case 2
1812 # Case 2
1810 return True
1813 return True
1811
1814
1812 # Case 3
1815 # Case 3
1813 # We store the code object so that threaded shells and
1816 # We store the code object so that threaded shells and
1814 # custom exception handlers can access all this info if needed.
1817 # custom exception handlers can access all this info if needed.
1815 # The source corresponding to this can be obtained from the
1818 # The source corresponding to this can be obtained from the
1816 # buffer attribute as '\n'.join(self.buffer).
1819 # buffer attribute as '\n'.join(self.buffer).
1817 self.code_to_run = code
1820 self.code_to_run = code
1818 # now actually execute the code object
1821 # now actually execute the code object
1819 if self.runcode(code) == 0:
1822 if self.runcode(code) == 0:
1820 return False
1823 return False
1821 else:
1824 else:
1822 return None
1825 return None
1823
1826
1824 def runcode(self,code_obj):
1827 def runcode(self,code_obj):
1825 """Execute a code object.
1828 """Execute a code object.
1826
1829
1827 When an exception occurs, self.showtraceback() is called to display a
1830 When an exception occurs, self.showtraceback() is called to display a
1828 traceback.
1831 traceback.
1829
1832
1830 Return value: a flag indicating whether the code to be run completed
1833 Return value: a flag indicating whether the code to be run completed
1831 successfully:
1834 successfully:
1832
1835
1833 - 0: successful execution.
1836 - 0: successful execution.
1834 - 1: an error occurred.
1837 - 1: an error occurred.
1835 """
1838 """
1836
1839
1837 # Set our own excepthook in case the user code tries to call it
1840 # Set our own excepthook in case the user code tries to call it
1838 # directly, so that the IPython crash handler doesn't get triggered
1841 # directly, so that the IPython crash handler doesn't get triggered
1839 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1842 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
1840
1843
1841 # we save the original sys.excepthook in the instance, in case config
1844 # we save the original sys.excepthook in the instance, in case config
1842 # code (such as magics) needs access to it.
1845 # code (such as magics) needs access to it.
1843 self.sys_excepthook = old_excepthook
1846 self.sys_excepthook = old_excepthook
1844 outflag = 1 # happens in more places, so it's easier as default
1847 outflag = 1 # happens in more places, so it's easier as default
1845 try:
1848 try:
1846 try:
1849 try:
1847 self.hooks.pre_runcode_hook()
1850 self.hooks.pre_runcode_hook()
1848 exec code_obj in self.user_global_ns, self.user_ns
1851 exec code_obj in self.user_global_ns, self.user_ns
1849 finally:
1852 finally:
1850 # Reset our crash handler in place
1853 # Reset our crash handler in place
1851 sys.excepthook = old_excepthook
1854 sys.excepthook = old_excepthook
1852 except SystemExit:
1855 except SystemExit:
1853 self.resetbuffer()
1856 self.resetbuffer()
1854 self.showtraceback(exception_only=True)
1857 self.showtraceback(exception_only=True)
1855 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1858 warn("To exit: use any of 'exit', 'quit', %Exit or Ctrl-D.", level=1)
1856 except self.custom_exceptions:
1859 except self.custom_exceptions:
1857 etype,value,tb = sys.exc_info()
1860 etype,value,tb = sys.exc_info()
1858 self.CustomTB(etype,value,tb)
1861 self.CustomTB(etype,value,tb)
1859 except:
1862 except:
1860 self.showtraceback()
1863 self.showtraceback()
1861 else:
1864 else:
1862 outflag = 0
1865 outflag = 0
1863 if softspace(sys.stdout, 0):
1866 if softspace(sys.stdout, 0):
1864 print
1867 print
1865 # Flush out code object which has been run (and source)
1868 # Flush out code object which has been run (and source)
1866 self.code_to_run = None
1869 self.code_to_run = None
1867 return outflag
1870 return outflag
1868
1871
1869 def push_line(self, line):
1872 def push_line(self, line):
1870 """Push a line to the interpreter.
1873 """Push a line to the interpreter.
1871
1874
1872 The line should not have a trailing newline; it may have
1875 The line should not have a trailing newline; it may have
1873 internal newlines. The line is appended to a buffer and the
1876 internal newlines. The line is appended to a buffer and the
1874 interpreter's runsource() method is called with the
1877 interpreter's runsource() method is called with the
1875 concatenated contents of the buffer as source. If this
1878 concatenated contents of the buffer as source. If this
1876 indicates that the command was executed or invalid, the buffer
1879 indicates that the command was executed or invalid, the buffer
1877 is reset; otherwise, the command is incomplete, and the buffer
1880 is reset; otherwise, the command is incomplete, and the buffer
1878 is left as it was after the line was appended. The return
1881 is left as it was after the line was appended. The return
1879 value is 1 if more input is required, 0 if the line was dealt
1882 value is 1 if more input is required, 0 if the line was dealt
1880 with in some way (this is the same as runsource()).
1883 with in some way (this is the same as runsource()).
1881 """
1884 """
1882
1885
1883 # autoindent management should be done here, and not in the
1886 # autoindent management should be done here, and not in the
1884 # interactive loop, since that one is only seen by keyboard input. We
1887 # interactive loop, since that one is only seen by keyboard input. We
1885 # need this done correctly even for code run via runlines (which uses
1888 # need this done correctly even for code run via runlines (which uses
1886 # push).
1889 # push).
1887
1890
1888 #print 'push line: <%s>' % line # dbg
1891 #print 'push line: <%s>' % line # dbg
1889 for subline in line.splitlines():
1892 for subline in line.splitlines():
1890 self._autoindent_update(subline)
1893 self._autoindent_update(subline)
1891 self.buffer.append(line)
1894 self.buffer.append(line)
1892 more = self.runsource('\n'.join(self.buffer), self.filename)
1895 more = self.runsource('\n'.join(self.buffer), self.filename)
1893 if not more:
1896 if not more:
1894 self.resetbuffer()
1897 self.resetbuffer()
1895 return more
1898 return more
1896
1899
1897 def resetbuffer(self):
1900 def resetbuffer(self):
1898 """Reset the input buffer."""
1901 """Reset the input buffer."""
1899 self.buffer[:] = []
1902 self.buffer[:] = []
1900
1903
1901 def _is_secondary_block_start(self, s):
1904 def _is_secondary_block_start(self, s):
1902 if not s.endswith(':'):
1905 if not s.endswith(':'):
1903 return False
1906 return False
1904 if (s.startswith('elif') or
1907 if (s.startswith('elif') or
1905 s.startswith('else') or
1908 s.startswith('else') or
1906 s.startswith('except') or
1909 s.startswith('except') or
1907 s.startswith('finally')):
1910 s.startswith('finally')):
1908 return True
1911 return True
1909
1912
1910 def _cleanup_ipy_script(self, script):
1913 def _cleanup_ipy_script(self, script):
1911 """Make a script safe for self.runlines()
1914 """Make a script safe for self.runlines()
1912
1915
1913 Currently, IPython is lines based, with blocks being detected by
1916 Currently, IPython is lines based, with blocks being detected by
1914 empty lines. This is a problem for block based scripts that may
1917 empty lines. This is a problem for block based scripts that may
1915 not have empty lines after blocks. This script adds those empty
1918 not have empty lines after blocks. This script adds those empty
1916 lines to make scripts safe for running in the current line based
1919 lines to make scripts safe for running in the current line based
1917 IPython.
1920 IPython.
1918 """
1921 """
1919 res = []
1922 res = []
1920 lines = script.splitlines()
1923 lines = script.splitlines()
1921 level = 0
1924 level = 0
1922
1925
1923 for l in lines:
1926 for l in lines:
1924 lstripped = l.lstrip()
1927 lstripped = l.lstrip()
1925 stripped = l.strip()
1928 stripped = l.strip()
1926 if not stripped:
1929 if not stripped:
1927 continue
1930 continue
1928 newlevel = len(l) - len(lstripped)
1931 newlevel = len(l) - len(lstripped)
1929 if level > 0 and newlevel == 0 and \
1932 if level > 0 and newlevel == 0 and \
1930 not self._is_secondary_block_start(stripped):
1933 not self._is_secondary_block_start(stripped):
1931 # add empty line
1934 # add empty line
1932 res.append('')
1935 res.append('')
1933 res.append(l)
1936 res.append(l)
1934 level = newlevel
1937 level = newlevel
1935
1938
1936 return '\n'.join(res) + '\n'
1939 return '\n'.join(res) + '\n'
1937
1940
1938 def _autoindent_update(self,line):
1941 def _autoindent_update(self,line):
1939 """Keep track of the indent level."""
1942 """Keep track of the indent level."""
1940
1943
1941 #debugx('line')
1944 #debugx('line')
1942 #debugx('self.indent_current_nsp')
1945 #debugx('self.indent_current_nsp')
1943 if self.autoindent:
1946 if self.autoindent:
1944 if line:
1947 if line:
1945 inisp = num_ini_spaces(line)
1948 inisp = num_ini_spaces(line)
1946 if inisp < self.indent_current_nsp:
1949 if inisp < self.indent_current_nsp:
1947 self.indent_current_nsp = inisp
1950 self.indent_current_nsp = inisp
1948
1951
1949 if line[-1] == ':':
1952 if line[-1] == ':':
1950 self.indent_current_nsp += 4
1953 self.indent_current_nsp += 4
1951 elif dedent_re.match(line):
1954 elif dedent_re.match(line):
1952 self.indent_current_nsp -= 4
1955 self.indent_current_nsp -= 4
1953 else:
1956 else:
1954 self.indent_current_nsp = 0
1957 self.indent_current_nsp = 0
1955
1958
1956 #-------------------------------------------------------------------------
1959 #-------------------------------------------------------------------------
1957 # Things related to GUI support and pylab
1960 # Things related to GUI support and pylab
1958 #-------------------------------------------------------------------------
1961 #-------------------------------------------------------------------------
1959
1962
1960 def enable_pylab(self, gui=None):
1963 def enable_pylab(self, gui=None):
1961 raise NotImplementedError('Implement enable_pylab in a subclass')
1964 raise NotImplementedError('Implement enable_pylab in a subclass')
1962
1965
1963 #-------------------------------------------------------------------------
1966 #-------------------------------------------------------------------------
1964 # Utilities
1967 # Utilities
1965 #-------------------------------------------------------------------------
1968 #-------------------------------------------------------------------------
1966
1969
1967 def getoutput(self, cmd):
1970 def getoutput(self, cmd):
1968 return getoutput(self.var_expand(cmd,depth=2),
1971 return getoutput(self.var_expand(cmd,depth=2),
1969 header=self.system_header,
1972 header=self.system_header,
1970 verbose=self.system_verbose)
1973 verbose=self.system_verbose)
1971
1974
1972 def getoutputerror(self, cmd):
1975 def getoutputerror(self, cmd):
1973 return getoutputerror(self.var_expand(cmd,depth=2),
1976 return getoutputerror(self.var_expand(cmd,depth=2),
1974 header=self.system_header,
1977 header=self.system_header,
1975 verbose=self.system_verbose)
1978 verbose=self.system_verbose)
1976
1979
1977 def var_expand(self,cmd,depth=0):
1980 def var_expand(self,cmd,depth=0):
1978 """Expand python variables in a string.
1981 """Expand python variables in a string.
1979
1982
1980 The depth argument indicates how many frames above the caller should
1983 The depth argument indicates how many frames above the caller should
1981 be walked to look for the local namespace where to expand variables.
1984 be walked to look for the local namespace where to expand variables.
1982
1985
1983 The global namespace for expansion is always the user's interactive
1986 The global namespace for expansion is always the user's interactive
1984 namespace.
1987 namespace.
1985 """
1988 """
1986
1989
1987 return str(ItplNS(cmd,
1990 return str(ItplNS(cmd,
1988 self.user_ns, # globals
1991 self.user_ns, # globals
1989 # Skip our own frame in searching for locals:
1992 # Skip our own frame in searching for locals:
1990 sys._getframe(depth+1).f_locals # locals
1993 sys._getframe(depth+1).f_locals # locals
1991 ))
1994 ))
1992
1995
1993 def mktempfile(self,data=None):
1996 def mktempfile(self,data=None):
1994 """Make a new tempfile and return its filename.
1997 """Make a new tempfile and return its filename.
1995
1998
1996 This makes a call to tempfile.mktemp, but it registers the created
1999 This makes a call to tempfile.mktemp, but it registers the created
1997 filename internally so ipython cleans it up at exit time.
2000 filename internally so ipython cleans it up at exit time.
1998
2001
1999 Optional inputs:
2002 Optional inputs:
2000
2003
2001 - data(None): if data is given, it gets written out to the temp file
2004 - data(None): if data is given, it gets written out to the temp file
2002 immediately, and the file is closed again."""
2005 immediately, and the file is closed again."""
2003
2006
2004 filename = tempfile.mktemp('.py','ipython_edit_')
2007 filename = tempfile.mktemp('.py','ipython_edit_')
2005 self.tempfiles.append(filename)
2008 self.tempfiles.append(filename)
2006
2009
2007 if data:
2010 if data:
2008 tmp_file = open(filename,'w')
2011 tmp_file = open(filename,'w')
2009 tmp_file.write(data)
2012 tmp_file.write(data)
2010 tmp_file.close()
2013 tmp_file.close()
2011 return filename
2014 return filename
2012
2015
2013 # TODO: This should be removed when Term is refactored.
2016 # TODO: This should be removed when Term is refactored.
2014 def write(self,data):
2017 def write(self,data):
2015 """Write a string to the default output"""
2018 """Write a string to the default output"""
2016 IPython.utils.io.Term.cout.write(data)
2019 IPython.utils.io.Term.cout.write(data)
2017
2020
2018 # TODO: This should be removed when Term is refactored.
2021 # TODO: This should be removed when Term is refactored.
2019 def write_err(self,data):
2022 def write_err(self,data):
2020 """Write a string to the default error output"""
2023 """Write a string to the default error output"""
2021 IPython.utils.io.Term.cerr.write(data)
2024 IPython.utils.io.Term.cerr.write(data)
2022
2025
2023 def ask_yes_no(self,prompt,default=True):
2026 def ask_yes_no(self,prompt,default=True):
2024 if self.quiet:
2027 if self.quiet:
2025 return True
2028 return True
2026 return ask_yes_no(prompt,default)
2029 return ask_yes_no(prompt,default)
2027
2030
2028 #-------------------------------------------------------------------------
2031 #-------------------------------------------------------------------------
2029 # Things related to IPython exiting
2032 # Things related to IPython exiting
2030 #-------------------------------------------------------------------------
2033 #-------------------------------------------------------------------------
2031
2034
2032 def atexit_operations(self):
2035 def atexit_operations(self):
2033 """This will be executed at the time of exit.
2036 """This will be executed at the time of exit.
2034
2037
2035 Saving of persistent data should be performed here.
2038 Saving of persistent data should be performed here.
2036 """
2039 """
2037 self.savehist()
2040 self.savehist()
2038
2041
2039 # Cleanup all tempfiles left around
2042 # Cleanup all tempfiles left around
2040 for tfile in self.tempfiles:
2043 for tfile in self.tempfiles:
2041 try:
2044 try:
2042 os.unlink(tfile)
2045 os.unlink(tfile)
2043 except OSError:
2046 except OSError:
2044 pass
2047 pass
2045
2048
2046 # Clear all user namespaces to release all references cleanly.
2049 # Clear all user namespaces to release all references cleanly.
2047 self.reset()
2050 self.reset()
2048
2051
2049 # Run user hooks
2052 # Run user hooks
2050 self.hooks.shutdown_hook()
2053 self.hooks.shutdown_hook()
2051
2054
2052 def cleanup(self):
2055 def cleanup(self):
2053 self.restore_sys_module_state()
2056 self.restore_sys_module_state()
2054
2057
2055
2058
2056 class InteractiveShellABC(object):
2059 class InteractiveShellABC(object):
2057 """An abstract base class for InteractiveShell."""
2060 """An abstract base class for InteractiveShell."""
2058 __metaclass__ = abc.ABCMeta
2061 __metaclass__ = abc.ABCMeta
2059
2062
2060 InteractiveShellABC.register(InteractiveShell)
2063 InteractiveShellABC.register(InteractiveShell)
@@ -1,100 +1,102 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Simple tests for :mod:`IPython.extensions.pretty`.
4 Simple tests for :mod:`IPython.extensions.pretty`.
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 from unittest import TestCase
18 from unittest import TestCase
19
19
20 from IPython.config.configurable import Configurable
20 from IPython.config.configurable import Configurable
21 from IPython.core.interactiveshell import InteractiveShellABC
21 from IPython.core.interactiveshell import InteractiveShellABC
22 from IPython.extensions import pretty as pretty_ext
22 from IPython.extensions import pretty as pretty_ext
23 from IPython.external import pretty
23 from IPython.external import pretty
24 from IPython.testing import decorators as dec
24 from IPython.testing import decorators as dec
25 from IPython.testing import tools as tt
25 from IPython.testing import tools as tt
26 from IPython.utils.traitlets import Bool
26 from IPython.utils.traitlets import Bool
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Tests
29 # Tests
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 class InteractiveShellStub(Configurable):
32 class InteractiveShellStub(Configurable):
33 pprint = Bool(True)
33 pprint = Bool(True)
34
34
35 InteractiveShellABC.register(InteractiveShellStub)
35 InteractiveShellABC.register(InteractiveShellStub)
36
36
37 class A(object):
37 class A(object):
38 pass
38 pass
39
39
40 def a_pprinter(o, p, c):
40 def a_pprinter(o, p, c):
41 return p.text("<A>")
41 return p.text("<A>")
42
42
43 class TestPrettyResultDisplay(TestCase):
43 class TestPrettyResultDisplay(TestCase):
44
44
45 def setUp(self):
45 def setUp(self):
46 self.ip = InteractiveShellStub()
46 self.ip = InteractiveShellStub()
47 self.prd = pretty_ext.PrettyResultDisplay(shell=self.ip, config=None)
47 self.prd = pretty_ext.PrettyResultDisplay(shell=self.ip, config=None)
48
48
49 @dec.skip_known_failure
49 def test_for_type(self):
50 def test_for_type(self):
50 self.prd.for_type(A, a_pprinter)
51 self.prd.for_type(A, a_pprinter)
51 a = A()
52 a = A()
52 result = pretty.pretty(a)
53 result = pretty.pretty(a)
53 self.assertEquals(result, "<A>")
54 self.assertEquals(result, "<A>")
54
55
55 ipy_src = """
56 ipy_src = """
56 class A(object):
57 class A(object):
57 def __repr__(self):
58 def __repr__(self):
58 return 'A()'
59 return 'A()'
59
60
60 class B(object):
61 class B(object):
61 def __repr__(self):
62 def __repr__(self):
62 return 'B()'
63 return 'B()'
63
64
64 a = A()
65 a = A()
65 b = B()
66 b = B()
66
67
67 def a_pretty_printer(obj, p, cycle):
68 def a_pretty_printer(obj, p, cycle):
68 p.text('<A>')
69 p.text('<A>')
69
70
70 def b_pretty_printer(obj, p, cycle):
71 def b_pretty_printer(obj, p, cycle):
71 p.text('<B>')
72 p.text('<B>')
72
73
73
74
74 a
75 a
75 b
76 b
76
77
77 ip = get_ipython()
78 ip = get_ipython()
78 ip.extension_manager.load_extension('pretty')
79 ip.extension_manager.load_extension('pretty')
79 prd = ip.plugin_manager.get_plugin('pretty_result_display')
80 prd = ip.plugin_manager.get_plugin('pretty_result_display')
80 prd.for_type(A, a_pretty_printer)
81 prd.for_type(A, a_pretty_printer)
81 prd.for_type_by_name(B.__module__, B.__name__, b_pretty_printer)
82 prd.for_type_by_name(B.__module__, B.__name__, b_pretty_printer)
82
83
83 a
84 a
84 b
85 b
85 """
86 """
86 ipy_out = """
87 ipy_out = """
87 A()
88 A()
88 B()
89 B()
89 <A>
90 <A>
90 <B>
91 <B>
91 """
92 """
92
93
93 class TestPrettyInteractively(tt.TempFileMixin):
94 class TestPrettyInteractively(tt.TempFileMixin):
94
95
95 # XXX Unfortunately, ipexec_validate fails under win32. If someone helps
96 # XXX Unfortunately, ipexec_validate fails under win32. If someone helps
96 # us write a win32-compatible version, we can reactivate this test.
97 # us write a win32-compatible version, we can reactivate this test.
98 @dec.skip_known_failure
97 @dec.skip_win32
99 @dec.skip_win32
98 def test_printers(self):
100 def test_printers(self):
99 self.mktmp(ipy_src, '.ipy')
101 self.mktmp(ipy_src, '.ipy')
100 tt.ipexec_validate(self.fname, ipy_out)
102 tt.ipexec_validate(self.fname, ipy_out)
@@ -1,206 +1,212 b''
1 # System library imports
1 # System library imports
2 from PyQt4 import QtCore, QtGui
2 from PyQt4 import QtCore, QtGui
3
3
4 # Local imports
4 # Local imports
5 from IPython.core.usage import default_banner
5 from IPython.core.usage import default_banner
6 from frontend_widget import FrontendWidget
6 from frontend_widget import FrontendWidget
7
7
8
8
9 class IPythonWidget(FrontendWidget):
9 class IPythonWidget(FrontendWidget):
10 """ A FrontendWidget for an IPython kernel.
10 """ A FrontendWidget for an IPython kernel.
11 """
11 """
12
12
13 # The default stylesheet: black text on a white background.
13 # The default stylesheet: black text on a white background.
14 default_stylesheet = """
14 default_stylesheet = """
15 .error { color: red; }
15 .error { color: red; }
16 .in-prompt { color: navy; }
16 .in-prompt { color: navy; }
17 .in-prompt-number { font-weight: bold; }
17 .in-prompt-number { font-weight: bold; }
18 .out-prompt { color: darkred; }
18 .out-prompt { color: darkred; }
19 .out-prompt-number { font-weight: bold; }
19 .out-prompt-number { font-weight: bold; }
20 """
20 """
21
21
22 # A dark stylesheet: white text on a black background.
22 # A dark stylesheet: white text on a black background.
23 dark_stylesheet = """
23 dark_stylesheet = """
24 QPlainTextEdit { background-color: black; color: white }
24 QPlainTextEdit { background-color: black; color: white }
25 QFrame { border: 1px solid grey; }
25 QFrame { border: 1px solid grey; }
26 .error { color: red; }
26 .error { color: red; }
27 .in-prompt { color: lime; }
27 .in-prompt { color: lime; }
28 .in-prompt-number { color: lime; font-weight: bold; }
28 .in-prompt-number { color: lime; font-weight: bold; }
29 .out-prompt { color: red; }
29 .out-prompt { color: red; }
30 .out-prompt-number { color: red; font-weight: bold; }
30 .out-prompt-number { color: red; font-weight: bold; }
31 """
31 """
32
32
33 # Default prompts.
33 # Default prompts.
34 in_prompt = '<br/>In [<span class="in-prompt-number">%i</span>]: '
34 in_prompt = '<br/>In [<span class="in-prompt-number">%i</span>]: '
35 out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
35 out_prompt = 'Out[<span class="out-prompt-number">%i</span>]: '
36
36
37 #---------------------------------------------------------------------------
37 #---------------------------------------------------------------------------
38 # 'object' interface
38 # 'object' interface
39 #---------------------------------------------------------------------------
39 #---------------------------------------------------------------------------
40
40
41 def __init__(self, *args, **kw):
41 def __init__(self, *args, **kw):
42 super(IPythonWidget, self).__init__(*args, **kw)
42 super(IPythonWidget, self).__init__(*args, **kw)
43
43
44 # Initialize protected variables.
44 # Initialize protected variables.
45 self._previous_prompt_blocks = []
45 self._previous_prompt_blocks = []
46 self._prompt_count = 0
46 self._prompt_count = 0
47
47
48 # Set a default stylesheet.
48 # Set a default stylesheet.
49 self.reset_styling()
49 self.reset_styling()
50
50
51 #---------------------------------------------------------------------------
51 #---------------------------------------------------------------------------
52 # 'FrontendWidget' interface
52 # 'FrontendWidget' interface
53 #---------------------------------------------------------------------------
53 #---------------------------------------------------------------------------
54
54
55 def execute_file(self, path, hidden=False):
55 def execute_file(self, path, hidden=False):
56 """ Reimplemented to use the 'run' magic.
56 """ Reimplemented to use the 'run' magic.
57 """
57 """
58 self.execute('run %s' % path, hidden=hidden)
58 self.execute('run %s' % path, hidden=hidden)
59
59
60 #---------------------------------------------------------------------------
60 #---------------------------------------------------------------------------
61 # 'FrontendWidget' protected interface
61 # 'FrontendWidget' protected interface
62 #---------------------------------------------------------------------------
62 #---------------------------------------------------------------------------
63
63
64 def _get_banner(self):
64 def _get_banner(self):
65 """ Reimplemented to return IPython's default banner.
65 """ Reimplemented to return IPython's default banner.
66 """
66 """
67 return default_banner
67 return default_banner
68
68
69 def _show_interpreter_prompt(self):
69 def _show_interpreter_prompt(self):
70 """ Reimplemented for IPython-style prompts.
70 """ Reimplemented for IPython-style prompts.
71 """
71 """
72 # Update old prompt numbers if necessary.
72 # Update old prompt numbers if necessary.
73 previous_prompt_number = self._prompt_count
73 previous_prompt_number = self._prompt_count
74 if previous_prompt_number != self._prompt_count:
74 if previous_prompt_number != self._prompt_count:
75 for i, (block, length) in enumerate(self._previous_prompt_blocks):
75 for i, (block, length) in enumerate(self._previous_prompt_blocks):
76 if block.isValid():
76 if block.isValid():
77 cursor = QtGui.QTextCursor(block)
77 cursor = QtGui.QTextCursor(block)
78 cursor.movePosition(QtGui.QTextCursor.Right,
78 cursor.movePosition(QtGui.QTextCursor.Right,
79 QtGui.QTextCursor.KeepAnchor, length-1)
79 QtGui.QTextCursor.KeepAnchor, length-1)
80 if i == 0:
80 if i == 0:
81 prompt = self._make_in_prompt(previous_prompt_number)
81 prompt = self._make_in_prompt(previous_prompt_number)
82 else:
82 else:
83 prompt = self._make_out_prompt(previous_prompt_number)
83 prompt = self._make_out_prompt(previous_prompt_number)
84 self._insert_html(cursor, prompt)
84 self._insert_html(cursor, prompt)
85 self._previous_prompt_blocks = []
85 self._previous_prompt_blocks = []
86
86
87 # Show a new prompt.
87 # Show a new prompt.
88 self._prompt_count += 1
88 self._prompt_count += 1
89 self._show_prompt(self._make_in_prompt(self._prompt_count), html=True)
89 self._show_prompt(self._make_in_prompt(self._prompt_count), html=True)
90 self._save_prompt_block()
90 self._save_prompt_block()
91
91
92 # Update continuation prompt to reflect (possibly) new prompt length.
92 # Update continuation prompt to reflect (possibly) new prompt length.
93 self._set_continuation_prompt(
93 self._set_continuation_prompt(
94 self._make_continuation_prompt(self._prompt), html=True)
94 self._make_continuation_prompt(self._prompt), html=True)
95
95
96 #------ Signal handlers ----------------------------------------------------
96 #------ Signal handlers ----------------------------------------------------
97
97
98 def _handle_execute_error(self, reply):
98 def _handle_execute_error(self, reply):
99 """ Reimplemented for IPython-style traceback formatting.
99 """ Reimplemented for IPython-style traceback formatting.
100 """
100 """
101 content = reply['content']
101 content = reply['content']
102 traceback_lines = content['traceback'][:]
102 traceback_lines = content['traceback'][:]
103 traceback = ''.join(traceback_lines)
103 traceback = ''.join(traceback_lines)
104 traceback = traceback.replace(' ', '&nbsp;')
104 traceback = traceback.replace(' ', '&nbsp;')
105 traceback = traceback.replace('\n', '<br/>')
105 traceback = traceback.replace('\n', '<br/>')
106
106
107 ename = content['ename']
107 ename = content['ename']
108 ename_styled = '<span class="error">%s</span>' % ename
108 ename_styled = '<span class="error">%s</span>' % ename
109 traceback = traceback.replace(ename, ename_styled)
109 traceback = traceback.replace(ename, ename_styled)
110
110
111 self._append_html(traceback)
111 self._append_html(traceback)
112
112
113 def _handle_pyout(self, omsg):
113 def _handle_pyout(self, omsg):
114 """ Reimplemented for IPython-style "display hook".
114 """ Reimplemented for IPython-style "display hook".
115 """
115 """
116 self._append_html(self._make_out_prompt(self._prompt_count))
116 # self._append_html(self._make_out_prompt(self._prompt_count))
117 # TODO: Also look at the output_sep, output_sep2 keys of content.
118 # They are used in terminal based frontends to add empty spaces before
119 # and after the Out[]: prompt. I doubt you want to use them, but they
120 # are there. I am thinking we should even take them out of the msg.
121 prompt_number = omsg['content']['prompt_number']
122 data = omsg['content']['data']
123 self._append_html(self._make_out_prompt(prompt_number))
117 self._save_prompt_block()
124 self._save_prompt_block()
118
125 self._append_plain_text(data + '\n')
119 self._append_plain_text(omsg['content']['data'] + '\n')
120
126
121 #---------------------------------------------------------------------------
127 #---------------------------------------------------------------------------
122 # 'IPythonWidget' interface
128 # 'IPythonWidget' interface
123 #---------------------------------------------------------------------------
129 #---------------------------------------------------------------------------
124
130
125 def reset_styling(self):
131 def reset_styling(self):
126 """ Restores the default IPythonWidget styling.
132 """ Restores the default IPythonWidget styling.
127 """
133 """
128 self.set_styling(self.default_stylesheet, syntax_style='default')
134 self.set_styling(self.default_stylesheet, syntax_style='default')
129 #self.set_styling(self.dark_stylesheet, syntax_style='monokai')
135 #self.set_styling(self.dark_stylesheet, syntax_style='monokai')
130
136
131 def set_styling(self, stylesheet, syntax_style=None):
137 def set_styling(self, stylesheet, syntax_style=None):
132 """ Sets the IPythonWidget styling.
138 """ Sets the IPythonWidget styling.
133
139
134 Parameters:
140 Parameters:
135 -----------
141 -----------
136 stylesheet : str
142 stylesheet : str
137 A CSS stylesheet. The stylesheet can contain classes for:
143 A CSS stylesheet. The stylesheet can contain classes for:
138 1. Qt: QPlainTextEdit, QFrame, QWidget, etc
144 1. Qt: QPlainTextEdit, QFrame, QWidget, etc
139 2. Pygments: .c, .k, .o, etc (see PygmentsHighlighter)
145 2. Pygments: .c, .k, .o, etc (see PygmentsHighlighter)
140 3. IPython: .error, .in-prompt, .out-prompt, etc.
146 3. IPython: .error, .in-prompt, .out-prompt, etc.
141
147
142 syntax_style : str or None [default None]
148 syntax_style : str or None [default None]
143 If specified, use the Pygments style with given name. Otherwise,
149 If specified, use the Pygments style with given name. Otherwise,
144 the stylesheet is queried for Pygments style information.
150 the stylesheet is queried for Pygments style information.
145 """
151 """
146 self.setStyleSheet(stylesheet)
152 self.setStyleSheet(stylesheet)
147 self._control.document().setDefaultStyleSheet(stylesheet)
153 self._control.document().setDefaultStyleSheet(stylesheet)
148
154
149 if syntax_style is None:
155 if syntax_style is None:
150 self._highlighter.set_style_sheet(stylesheet)
156 self._highlighter.set_style_sheet(stylesheet)
151 else:
157 else:
152 self._highlighter.set_style(syntax_style)
158 self._highlighter.set_style(syntax_style)
153
159
154 #---------------------------------------------------------------------------
160 #---------------------------------------------------------------------------
155 # 'IPythonWidget' protected interface
161 # 'IPythonWidget' protected interface
156 #---------------------------------------------------------------------------
162 #---------------------------------------------------------------------------
157
163
158 def _make_in_prompt(self, number):
164 def _make_in_prompt(self, number):
159 """ Given a prompt number, returns an HTML In prompt.
165 """ Given a prompt number, returns an HTML In prompt.
160 """
166 """
161 body = self.in_prompt % number
167 body = self.in_prompt % number
162 return '<span class="in-prompt">%s</span>' % body
168 return '<span class="in-prompt">%s</span>' % body
163
169
164 def _make_continuation_prompt(self, prompt):
170 def _make_continuation_prompt(self, prompt):
165 """ Given a plain text version of an In prompt, returns an HTML
171 """ Given a plain text version of an In prompt, returns an HTML
166 continuation prompt.
172 continuation prompt.
167 """
173 """
168 end_chars = '...: '
174 end_chars = '...: '
169 space_count = len(prompt.lstrip('\n')) - len(end_chars)
175 space_count = len(prompt.lstrip('\n')) - len(end_chars)
170 body = '&nbsp;' * space_count + end_chars
176 body = '&nbsp;' * space_count + end_chars
171 return '<span class="in-prompt">%s</span>' % body
177 return '<span class="in-prompt">%s</span>' % body
172
178
173 def _make_out_prompt(self, number):
179 def _make_out_prompt(self, number):
174 """ Given a prompt number, returns an HTML Out prompt.
180 """ Given a prompt number, returns an HTML Out prompt.
175 """
181 """
176 body = self.out_prompt % number
182 body = self.out_prompt % number
177 return '<span class="out-prompt">%s</span>' % body
183 return '<span class="out-prompt">%s</span>' % body
178
184
179 def _save_prompt_block(self):
185 def _save_prompt_block(self):
180 """ Assuming a prompt has just been written at the end of the buffer,
186 """ Assuming a prompt has just been written at the end of the buffer,
181 store the QTextBlock that contains it and its length.
187 store the QTextBlock that contains it and its length.
182 """
188 """
183 block = self._control.document().lastBlock()
189 block = self._control.document().lastBlock()
184 self._previous_prompt_blocks.append((block, block.length()))
190 self._previous_prompt_blocks.append((block, block.length()))
185
191
186
192
187 if __name__ == '__main__':
193 if __name__ == '__main__':
188 from IPython.frontend.qt.kernelmanager import QtKernelManager
194 from IPython.frontend.qt.kernelmanager import QtKernelManager
189
195
190 # Don't let Qt or ZMQ swallow KeyboardInterupts.
196 # Don't let Qt or ZMQ swallow KeyboardInterupts.
191 import signal
197 import signal
192 signal.signal(signal.SIGINT, signal.SIG_DFL)
198 signal.signal(signal.SIGINT, signal.SIG_DFL)
193
199
194 # Create a KernelManager.
200 # Create a KernelManager.
195 kernel_manager = QtKernelManager()
201 kernel_manager = QtKernelManager()
196 kernel_manager.start_kernel()
202 kernel_manager.start_kernel()
197 kernel_manager.start_channels()
203 kernel_manager.start_channels()
198
204
199 # Launch the application.
205 # Launch the application.
200 app = QtGui.QApplication([])
206 app = QtGui.QApplication([])
201 widget = IPythonWidget()
207 widget = IPythonWidget()
202 widget.kernel_manager = kernel_manager
208 widget.kernel_manager = kernel_manager
203 widget.setWindowTitle('Python')
209 widget.setWindowTitle('Python')
204 widget.resize(640, 480)
210 widget.resize(640, 480)
205 widget.show()
211 widget.show()
206 app.exec_()
212 app.exec_()
@@ -1,184 +1,185 b''
1 """ Defines a KernelManager that provides signals and slots.
1 """ Defines a KernelManager that provides signals and slots.
2 """
2 """
3
3
4 # System library imports.
4 # System library imports.
5 from PyQt4 import QtCore
5 from PyQt4 import QtCore
6 import zmq
6 import zmq
7
7
8 # IPython imports.
8 # IPython imports.
9 from IPython.utils.traitlets import Type
9 from IPython.zmq.kernelmanager import KernelManager, SubSocketChannel, \
10 from IPython.zmq.kernelmanager import KernelManager, SubSocketChannel, \
10 XReqSocketChannel, RepSocketChannel
11 XReqSocketChannel, RepSocketChannel
11 from util import MetaQObjectHasTraits
12 from util import MetaQObjectHasTraits
12
13
13 # When doing multiple inheritance from QtCore.QObject and other classes
14 # When doing multiple inheritance from QtCore.QObject and other classes
14 # the calling of the parent __init__'s is a subtle issue:
15 # the calling of the parent __init__'s is a subtle issue:
15 # * QtCore.QObject does not call super so you can't use super and put
16 # * QtCore.QObject does not call super so you can't use super and put
16 # QObject first in the inheritance list.
17 # QObject first in the inheritance list.
17 # * QtCore.QObject.__init__ takes 1 argument, the parent. So if you are going
18 # * QtCore.QObject.__init__ takes 1 argument, the parent. So if you are going
18 # to use super, any class that comes before QObject must pass it something
19 # to use super, any class that comes before QObject must pass it something
19 # reasonable.
20 # reasonable.
20 # In summary, I don't think using super in these situations will work.
21 # In summary, I don't think using super in these situations will work.
21 # Instead we will need to call the __init__ methods of both parents
22 # Instead we will need to call the __init__ methods of both parents
22 # by hand. Not pretty, but it works.
23 # by hand. Not pretty, but it works.
23
24
24 class QtSubSocketChannel(SubSocketChannel, QtCore.QObject):
25 class QtSubSocketChannel(SubSocketChannel, QtCore.QObject):
25
26
26 # Emitted when any message is received.
27 # Emitted when any message is received.
27 message_received = QtCore.pyqtSignal(object)
28 message_received = QtCore.pyqtSignal(object)
28
29
29 # Emitted when a message of type 'pyout' or 'stdout' is received.
30 # Emitted when a message of type 'pyout' or 'stdout' is received.
30 output_received = QtCore.pyqtSignal(object)
31 output_received = QtCore.pyqtSignal(object)
31
32
32 # Emitted when a message of type 'pyerr' or 'stderr' is received.
33 # Emitted when a message of type 'pyerr' or 'stderr' is received.
33 error_received = QtCore.pyqtSignal(object)
34 error_received = QtCore.pyqtSignal(object)
34
35
35 #---------------------------------------------------------------------------
36 #---------------------------------------------------------------------------
36 # 'object' interface
37 # 'object' interface
37 #---------------------------------------------------------------------------
38 #---------------------------------------------------------------------------
38
39
39 def __init__(self, *args, **kw):
40 def __init__(self, *args, **kw):
40 """ Reimplemented to ensure that QtCore.QObject is initialized first.
41 """ Reimplemented to ensure that QtCore.QObject is initialized first.
41 """
42 """
42 QtCore.QObject.__init__(self)
43 QtCore.QObject.__init__(self)
43 SubSocketChannel.__init__(self, *args, **kw)
44 SubSocketChannel.__init__(self, *args, **kw)
44
45
45 #---------------------------------------------------------------------------
46 #---------------------------------------------------------------------------
46 # 'SubSocketChannel' interface
47 # 'SubSocketChannel' interface
47 #---------------------------------------------------------------------------
48 #---------------------------------------------------------------------------
48
49
49 def call_handlers(self, msg):
50 def call_handlers(self, msg):
50 """ Reimplemented to emit signals instead of making callbacks.
51 """ Reimplemented to emit signals instead of making callbacks.
51 """
52 """
52 # Emit the generic signal.
53 # Emit the generic signal.
53 self.message_received.emit(msg)
54 self.message_received.emit(msg)
54
55
55 # Emit signals for specialized message types.
56 # Emit signals for specialized message types.
56 msg_type = msg['msg_type']
57 msg_type = msg['msg_type']
57 if msg_type in ('pyout', 'stdout'):
58 if msg_type in ('pyout', 'stdout'):
58 self.output_received.emit(msg)
59 self.output_received.emit(msg)
59 elif msg_type in ('pyerr', 'stderr'):
60 elif msg_type in ('pyerr', 'stderr'):
60 self.error_received.emit(msg)
61 self.error_received.emit(msg)
61
62
62 def flush(self):
63 def flush(self):
63 """ Reimplemented to ensure that signals are dispatched immediately.
64 """ Reimplemented to ensure that signals are dispatched immediately.
64 """
65 """
65 super(QtSubSocketChannel, self).flush()
66 super(QtSubSocketChannel, self).flush()
66 QtCore.QCoreApplication.instance().processEvents()
67 QtCore.QCoreApplication.instance().processEvents()
67
68
68
69
69 class QtXReqSocketChannel(XReqSocketChannel, QtCore.QObject):
70 class QtXReqSocketChannel(XReqSocketChannel, QtCore.QObject):
70
71
71 # Emitted when any message is received.
72 # Emitted when any message is received.
72 message_received = QtCore.pyqtSignal(object)
73 message_received = QtCore.pyqtSignal(object)
73
74
74 # Emitted when a reply has been received for the corresponding request type.
75 # Emitted when a reply has been received for the corresponding request type.
75 execute_reply = QtCore.pyqtSignal(object)
76 execute_reply = QtCore.pyqtSignal(object)
76 complete_reply = QtCore.pyqtSignal(object)
77 complete_reply = QtCore.pyqtSignal(object)
77 object_info_reply = QtCore.pyqtSignal(object)
78 object_info_reply = QtCore.pyqtSignal(object)
78
79
79 #---------------------------------------------------------------------------
80 #---------------------------------------------------------------------------
80 # 'object' interface
81 # 'object' interface
81 #---------------------------------------------------------------------------
82 #---------------------------------------------------------------------------
82
83
83 def __init__(self, *args, **kw):
84 def __init__(self, *args, **kw):
84 """ Reimplemented to ensure that QtCore.QObject is initialized first.
85 """ Reimplemented to ensure that QtCore.QObject is initialized first.
85 """
86 """
86 QtCore.QObject.__init__(self)
87 QtCore.QObject.__init__(self)
87 XReqSocketChannel.__init__(self, *args, **kw)
88 XReqSocketChannel.__init__(self, *args, **kw)
88
89
89 #---------------------------------------------------------------------------
90 #---------------------------------------------------------------------------
90 # 'XReqSocketChannel' interface
91 # 'XReqSocketChannel' interface
91 #---------------------------------------------------------------------------
92 #---------------------------------------------------------------------------
92
93
93 def call_handlers(self, msg):
94 def call_handlers(self, msg):
94 """ Reimplemented to emit signals instead of making callbacks.
95 """ Reimplemented to emit signals instead of making callbacks.
95 """
96 """
96 # Emit the generic signal.
97 # Emit the generic signal.
97 self.message_received.emit(msg)
98 self.message_received.emit(msg)
98
99
99 # Emit signals for specialized message types.
100 # Emit signals for specialized message types.
100 msg_type = msg['msg_type']
101 msg_type = msg['msg_type']
101 signal = getattr(self, msg_type, None)
102 signal = getattr(self, msg_type, None)
102 if signal:
103 if signal:
103 signal.emit(msg)
104 signal.emit(msg)
104
105
105
106
106 class QtRepSocketChannel(RepSocketChannel, QtCore.QObject):
107 class QtRepSocketChannel(RepSocketChannel, QtCore.QObject):
107
108
108 # Emitted when any message is received.
109 # Emitted when any message is received.
109 message_received = QtCore.pyqtSignal(object)
110 message_received = QtCore.pyqtSignal(object)
110
111
111 # Emitted when an input request is received.
112 # Emitted when an input request is received.
112 input_requested = QtCore.pyqtSignal(object)
113 input_requested = QtCore.pyqtSignal(object)
113
114
114 #---------------------------------------------------------------------------
115 #---------------------------------------------------------------------------
115 # 'object' interface
116 # 'object' interface
116 #---------------------------------------------------------------------------
117 #---------------------------------------------------------------------------
117
118
118 def __init__(self, *args, **kw):
119 def __init__(self, *args, **kw):
119 """ Reimplemented to ensure that QtCore.QObject is initialized first.
120 """ Reimplemented to ensure that QtCore.QObject is initialized first.
120 """
121 """
121 QtCore.QObject.__init__(self)
122 QtCore.QObject.__init__(self)
122 RepSocketChannel.__init__(self, *args, **kw)
123 RepSocketChannel.__init__(self, *args, **kw)
123
124
124 #---------------------------------------------------------------------------
125 #---------------------------------------------------------------------------
125 # 'RepSocketChannel' interface
126 # 'RepSocketChannel' interface
126 #---------------------------------------------------------------------------
127 #---------------------------------------------------------------------------
127
128
128 def call_handlers(self, msg):
129 def call_handlers(self, msg):
129 """ Reimplemented to emit signals instead of making callbacks.
130 """ Reimplemented to emit signals instead of making callbacks.
130 """
131 """
131 # Emit the generic signal.
132 # Emit the generic signal.
132 self.message_received.emit(msg)
133 self.message_received.emit(msg)
133
134
134 # Emit signals for specialized message types.
135 # Emit signals for specialized message types.
135 msg_type = msg['msg_type']
136 msg_type = msg['msg_type']
136 if msg_type == 'input_request':
137 if msg_type == 'input_request':
137 self.input_requested.emit(msg)
138 self.input_requested.emit(msg)
138
139
139 class QtKernelManager(KernelManager, QtCore.QObject):
140 class QtKernelManager(KernelManager, QtCore.QObject):
140 """ A KernelManager that provides signals and slots.
141 """ A KernelManager that provides signals and slots.
141 """
142 """
142
143
143 __metaclass__ = MetaQObjectHasTraits
144 __metaclass__ = MetaQObjectHasTraits
144
145
145 # Emitted when the kernel manager has started listening.
146 # Emitted when the kernel manager has started listening.
146 started_channels = QtCore.pyqtSignal()
147 started_channels = QtCore.pyqtSignal()
147
148
148 # Emitted when the kernel manager has stopped listening.
149 # Emitted when the kernel manager has stopped listening.
149 stopped_channels = QtCore.pyqtSignal()
150 stopped_channels = QtCore.pyqtSignal()
150
151
151 # Use Qt-specific channel classes that emit signals.
152 # Use Qt-specific channel classes that emit signals.
152 sub_channel_class = QtSubSocketChannel
153 sub_channel_class = Type(QtSubSocketChannel)
153 xreq_channel_class = QtXReqSocketChannel
154 xreq_channel_class = Type(QtXReqSocketChannel)
154 rep_channel_class = QtRepSocketChannel
155 rep_channel_class = Type(QtRepSocketChannel)
155
156
156 def __init__(self, *args, **kw):
157 def __init__(self, *args, **kw):
157 QtCore.QObject.__init__(self)
158 QtCore.QObject.__init__(self)
158 KernelManager.__init__(self, *args, **kw)
159 KernelManager.__init__(self, *args, **kw)
159
160
160 #---------------------------------------------------------------------------
161 #---------------------------------------------------------------------------
161 # 'object' interface
162 # 'object' interface
162 #---------------------------------------------------------------------------
163 #---------------------------------------------------------------------------
163
164
164 def __init__(self, *args, **kw):
165 def __init__(self, *args, **kw):
165 """ Reimplemented to ensure that QtCore.QObject is initialized first.
166 """ Reimplemented to ensure that QtCore.QObject is initialized first.
166 """
167 """
167 QtCore.QObject.__init__(self)
168 QtCore.QObject.__init__(self)
168 KernelManager.__init__(self, *args, **kw)
169 KernelManager.__init__(self, *args, **kw)
169
170
170 #---------------------------------------------------------------------------
171 #---------------------------------------------------------------------------
171 # 'KernelManager' interface
172 # 'KernelManager' interface
172 #---------------------------------------------------------------------------
173 #---------------------------------------------------------------------------
173
174
174 def start_channels(self):
175 def start_channels(self):
175 """ Reimplemented to emit signal.
176 """ Reimplemented to emit signal.
176 """
177 """
177 super(QtKernelManager, self).start_channels()
178 super(QtKernelManager, self).start_channels()
178 self.started_channels.emit()
179 self.started_channels.emit()
179
180
180 def stop_channels(self):
181 def stop_channels(self):
181 """ Reimplemented to emit signal.
182 """ Reimplemented to emit signal.
182 """
183 """
183 super(QtKernelManager, self).stop_channels()
184 super(QtKernelManager, self).stop_channels()
184 self.stopped_channels.emit()
185 self.stopped_channels.emit()
@@ -1,324 +1,324 b''
1 """Decorators for labeling test objects.
1 """Decorators for labeling test objects.
2
2
3 Decorators that merely return a modified version of the original function
3 Decorators that merely return a modified version of the original function
4 object are straightforward. Decorators that return a new function object need
4 object are straightforward. Decorators that return a new function object need
5 to use nose.tools.make_decorator(original_function)(decorator) in returning the
5 to use nose.tools.make_decorator(original_function)(decorator) in returning the
6 decorator, in order to preserve metadata such as function name, setup and
6 decorator, in order to preserve metadata such as function name, setup and
7 teardown functions and so on - see nose.tools for more information.
7 teardown functions and so on - see nose.tools for more information.
8
8
9 This module provides a set of useful decorators meant to be ready to use in
9 This module provides a set of useful decorators meant to be ready to use in
10 your own tests. See the bottom of the file for the ready-made ones, and if you
10 your own tests. See the bottom of the file for the ready-made ones, and if you
11 find yourself writing a new one that may be of generic use, add it here.
11 find yourself writing a new one that may be of generic use, add it here.
12
12
13 Included decorators:
13 Included decorators:
14
14
15
15
16 Lightweight testing that remains unittest-compatible.
16 Lightweight testing that remains unittest-compatible.
17
17
18 - @parametric, for parametric test support that is vastly easier to use than
18 - @parametric, for parametric test support that is vastly easier to use than
19 nose's for debugging. With ours, if a test fails, the stack under inspection
19 nose's for debugging. With ours, if a test fails, the stack under inspection
20 is that of the test and not that of the test framework.
20 is that of the test and not that of the test framework.
21
21
22 - An @as_unittest decorator can be used to tag any normal parameter-less
22 - An @as_unittest decorator can be used to tag any normal parameter-less
23 function as a unittest TestCase. Then, both nose and normal unittest will
23 function as a unittest TestCase. Then, both nose and normal unittest will
24 recognize it as such. This will make it easier to migrate away from Nose if
24 recognize it as such. This will make it easier to migrate away from Nose if
25 we ever need/want to while maintaining very lightweight tests.
25 we ever need/want to while maintaining very lightweight tests.
26
26
27 NOTE: This file contains IPython-specific decorators and imports the
27 NOTE: This file contains IPython-specific decorators and imports the
28 numpy.testing.decorators file, which we've copied verbatim. Any of our own
28 numpy.testing.decorators file, which we've copied verbatim. Any of our own
29 code will be added at the bottom if we end up extending this.
29 code will be added at the bottom if we end up extending this.
30
30
31 Authors
31 Authors
32 -------
32 -------
33
33
34 - Fernando Perez <Fernando.Perez@berkeley.edu>
34 - Fernando Perez <Fernando.Perez@berkeley.edu>
35 """
35 """
36
36
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38 # Copyright (C) 2009-2010 The IPython Development Team
38 # Copyright (C) 2009-2010 The IPython Development Team
39 #
39 #
40 # Distributed under the terms of the BSD License. The full license is in
40 # Distributed under the terms of the BSD License. The full license is in
41 # the file COPYING, distributed as part of this software.
41 # the file COPYING, distributed as part of this software.
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45 # Imports
45 # Imports
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47
47
48 # Stdlib imports
48 # Stdlib imports
49 import inspect
49 import inspect
50 import sys
50 import sys
51 import unittest
51 import unittest
52
52
53 # Third-party imports
53 # Third-party imports
54
54
55 # This is Michele Simionato's decorator module, kept verbatim.
55 # This is Michele Simionato's decorator module, kept verbatim.
56 from IPython.external.decorator import decorator, update_wrapper
56 from IPython.external.decorator import decorator, update_wrapper
57
57
58 # We already have python3-compliant code for parametric tests
58 # We already have python3-compliant code for parametric tests
59 if sys.version[0]=='2':
59 if sys.version[0]=='2':
60 from _paramtestpy2 import parametric, ParametricTestCase
60 from _paramtestpy2 import parametric, ParametricTestCase
61 else:
61 else:
62 from _paramtestpy3 import parametric, ParametricTestCase
62 from _paramtestpy3 import parametric, ParametricTestCase
63
63
64 # Expose the unittest-driven decorators
64 # Expose the unittest-driven decorators
65 from ipunittest import ipdoctest, ipdocstring
65 from ipunittest import ipdoctest, ipdocstring
66
66
67 # Grab the numpy-specific decorators which we keep in a file that we
67 # Grab the numpy-specific decorators which we keep in a file that we
68 # occasionally update from upstream: decorators.py is a copy of
68 # occasionally update from upstream: decorators.py is a copy of
69 # numpy.testing.decorators, we expose all of it here.
69 # numpy.testing.decorators, we expose all of it here.
70 from IPython.external.decorators import *
70 from IPython.external.decorators import *
71
71
72 #-----------------------------------------------------------------------------
72 #-----------------------------------------------------------------------------
73 # Classes and functions
73 # Classes and functions
74 #-----------------------------------------------------------------------------
74 #-----------------------------------------------------------------------------
75
75
76 # Simple example of the basic idea
76 # Simple example of the basic idea
77 def as_unittest(func):
77 def as_unittest(func):
78 """Decorator to make a simple function into a normal test via unittest."""
78 """Decorator to make a simple function into a normal test via unittest."""
79 class Tester(unittest.TestCase):
79 class Tester(unittest.TestCase):
80 def test(self):
80 def test(self):
81 func()
81 func()
82
82
83 Tester.__name__ = func.__name__
83 Tester.__name__ = func.__name__
84
84
85 return Tester
85 return Tester
86
86
87 # Utility functions
87 # Utility functions
88
88
89 def apply_wrapper(wrapper,func):
89 def apply_wrapper(wrapper,func):
90 """Apply a wrapper to a function for decoration.
90 """Apply a wrapper to a function for decoration.
91
91
92 This mixes Michele Simionato's decorator tool with nose's make_decorator,
92 This mixes Michele Simionato's decorator tool with nose's make_decorator,
93 to apply a wrapper in a decorator so that all nose attributes, as well as
93 to apply a wrapper in a decorator so that all nose attributes, as well as
94 function signature and other properties, survive the decoration cleanly.
94 function signature and other properties, survive the decoration cleanly.
95 This will ensure that wrapped functions can still be well introspected via
95 This will ensure that wrapped functions can still be well introspected via
96 IPython, for example.
96 IPython, for example.
97 """
97 """
98 import nose.tools
98 import nose.tools
99
99
100 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
100 return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
101
101
102
102
103 def make_label_dec(label,ds=None):
103 def make_label_dec(label,ds=None):
104 """Factory function to create a decorator that applies one or more labels.
104 """Factory function to create a decorator that applies one or more labels.
105
105
106 Parameters
106 Parameters
107 ----------
107 ----------
108 label : string or sequence
108 label : string or sequence
109 One or more labels that will be applied by the decorator to the functions
109 One or more labels that will be applied by the decorator to the functions
110 it decorates. Labels are attributes of the decorated function with their
110 it decorates. Labels are attributes of the decorated function with their
111 value set to True.
111 value set to True.
112
112
113 ds : string
113 ds : string
114 An optional docstring for the resulting decorator. If not given, a
114 An optional docstring for the resulting decorator. If not given, a
115 default docstring is auto-generated.
115 default docstring is auto-generated.
116
116
117 Returns
117 Returns
118 -------
118 -------
119 A decorator.
119 A decorator.
120
120
121 Examples
121 Examples
122 --------
122 --------
123
123
124 A simple labeling decorator:
124 A simple labeling decorator:
125 >>> slow = make_label_dec('slow')
125 >>> slow = make_label_dec('slow')
126 >>> print slow.__doc__
126 >>> print slow.__doc__
127 Labels a test as 'slow'.
127 Labels a test as 'slow'.
128
128
129 And one that uses multiple labels and a custom docstring:
129 And one that uses multiple labels and a custom docstring:
130 >>> rare = make_label_dec(['slow','hard'],
130 >>> rare = make_label_dec(['slow','hard'],
131 ... "Mix labels 'slow' and 'hard' for rare tests.")
131 ... "Mix labels 'slow' and 'hard' for rare tests.")
132 >>> print rare.__doc__
132 >>> print rare.__doc__
133 Mix labels 'slow' and 'hard' for rare tests.
133 Mix labels 'slow' and 'hard' for rare tests.
134
134
135 Now, let's test using this one:
135 Now, let's test using this one:
136 >>> @rare
136 >>> @rare
137 ... def f(): pass
137 ... def f(): pass
138 ...
138 ...
139 >>>
139 >>>
140 >>> f.slow
140 >>> f.slow
141 True
141 True
142 >>> f.hard
142 >>> f.hard
143 True
143 True
144 """
144 """
145
145
146 if isinstance(label,basestring):
146 if isinstance(label,basestring):
147 labels = [label]
147 labels = [label]
148 else:
148 else:
149 labels = label
149 labels = label
150
150
151 # Validate that the given label(s) are OK for use in setattr() by doing a
151 # Validate that the given label(s) are OK for use in setattr() by doing a
152 # dry run on a dummy function.
152 # dry run on a dummy function.
153 tmp = lambda : None
153 tmp = lambda : None
154 for label in labels:
154 for label in labels:
155 setattr(tmp,label,True)
155 setattr(tmp,label,True)
156
156
157 # This is the actual decorator we'll return
157 # This is the actual decorator we'll return
158 def decor(f):
158 def decor(f):
159 for label in labels:
159 for label in labels:
160 setattr(f,label,True)
160 setattr(f,label,True)
161 return f
161 return f
162
162
163 # Apply the user's docstring, or autogenerate a basic one
163 # Apply the user's docstring, or autogenerate a basic one
164 if ds is None:
164 if ds is None:
165 ds = "Labels a test as %r." % label
165 ds = "Labels a test as %r." % label
166 decor.__doc__ = ds
166 decor.__doc__ = ds
167
167
168 return decor
168 return decor
169
169
170
170
171 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
171 # Inspired by numpy's skipif, but uses the full apply_wrapper utility to
172 # preserve function metadata better and allows the skip condition to be a
172 # preserve function metadata better and allows the skip condition to be a
173 # callable.
173 # callable.
174 def skipif(skip_condition, msg=None):
174 def skipif(skip_condition, msg=None):
175 ''' Make function raise SkipTest exception if skip_condition is true
175 ''' Make function raise SkipTest exception if skip_condition is true
176
176
177 Parameters
177 Parameters
178 ----------
178 ----------
179 skip_condition : bool or callable.
179 skip_condition : bool or callable.
180 Flag to determine whether to skip test. If the condition is a
180 Flag to determine whether to skip test. If the condition is a
181 callable, it is used at runtime to dynamically make the decision. This
181 callable, it is used at runtime to dynamically make the decision. This
182 is useful for tests that may require costly imports, to delay the cost
182 is useful for tests that may require costly imports, to delay the cost
183 until the test suite is actually executed.
183 until the test suite is actually executed.
184 msg : string
184 msg : string
185 Message to give on raising a SkipTest exception
185 Message to give on raising a SkipTest exception
186
186
187 Returns
187 Returns
188 -------
188 -------
189 decorator : function
189 decorator : function
190 Decorator, which, when applied to a function, causes SkipTest
190 Decorator, which, when applied to a function, causes SkipTest
191 to be raised when the skip_condition was True, and the function
191 to be raised when the skip_condition was True, and the function
192 to be called normally otherwise.
192 to be called normally otherwise.
193
193
194 Notes
194 Notes
195 -----
195 -----
196 You will see from the code that we had to further decorate the
196 You will see from the code that we had to further decorate the
197 decorator with the nose.tools.make_decorator function in order to
197 decorator with the nose.tools.make_decorator function in order to
198 transmit function name, and various other metadata.
198 transmit function name, and various other metadata.
199 '''
199 '''
200
200
201 def skip_decorator(f):
201 def skip_decorator(f):
202 # Local import to avoid a hard nose dependency and only incur the
202 # Local import to avoid a hard nose dependency and only incur the
203 # import time overhead at actual test-time.
203 # import time overhead at actual test-time.
204 import nose
204 import nose
205
205
206 # Allow for both boolean or callable skip conditions.
206 # Allow for both boolean or callable skip conditions.
207 if callable(skip_condition):
207 if callable(skip_condition):
208 skip_val = skip_condition
208 skip_val = skip_condition
209 else:
209 else:
210 skip_val = lambda : skip_condition
210 skip_val = lambda : skip_condition
211
211
212 def get_msg(func,msg=None):
212 def get_msg(func,msg=None):
213 """Skip message with information about function being skipped."""
213 """Skip message with information about function being skipped."""
214 if msg is None: out = 'Test skipped due to test condition.'
214 if msg is None: out = 'Test skipped due to test condition.'
215 else: out = msg
215 else: out = msg
216 return "Skipping test: %s. %s" % (func.__name__,out)
216 return "Skipping test: %s. %s" % (func.__name__,out)
217
217
218 # We need to define *two* skippers because Python doesn't allow both
218 # We need to define *two* skippers because Python doesn't allow both
219 # return with value and yield inside the same function.
219 # return with value and yield inside the same function.
220 def skipper_func(*args, **kwargs):
220 def skipper_func(*args, **kwargs):
221 """Skipper for normal test functions."""
221 """Skipper for normal test functions."""
222 if skip_val():
222 if skip_val():
223 raise nose.SkipTest(get_msg(f,msg))
223 raise nose.SkipTest(get_msg(f,msg))
224 else:
224 else:
225 return f(*args, **kwargs)
225 return f(*args, **kwargs)
226
226
227 def skipper_gen(*args, **kwargs):
227 def skipper_gen(*args, **kwargs):
228 """Skipper for test generators."""
228 """Skipper for test generators."""
229 if skip_val():
229 if skip_val():
230 raise nose.SkipTest(get_msg(f,msg))
230 raise nose.SkipTest(get_msg(f,msg))
231 else:
231 else:
232 for x in f(*args, **kwargs):
232 for x in f(*args, **kwargs):
233 yield x
233 yield x
234
234
235 # Choose the right skipper to use when building the actual generator.
235 # Choose the right skipper to use when building the actual generator.
236 if nose.util.isgenerator(f):
236 if nose.util.isgenerator(f):
237 skipper = skipper_gen
237 skipper = skipper_gen
238 else:
238 else:
239 skipper = skipper_func
239 skipper = skipper_func
240
240
241 return nose.tools.make_decorator(f)(skipper)
241 return nose.tools.make_decorator(f)(skipper)
242
242
243 return skip_decorator
243 return skip_decorator
244
244
245 # A version with the condition set to true, common case just to attacha message
245 # A version with the condition set to true, common case just to attacha message
246 # to a skip decorator
246 # to a skip decorator
247 def skip(msg=None):
247 def skip(msg=None):
248 """Decorator factory - mark a test function for skipping from test suite.
248 """Decorator factory - mark a test function for skipping from test suite.
249
249
250 Parameters
250 Parameters
251 ----------
251 ----------
252 msg : string
252 msg : string
253 Optional message to be added.
253 Optional message to be added.
254
254
255 Returns
255 Returns
256 -------
256 -------
257 decorator : function
257 decorator : function
258 Decorator, which, when applied to a function, causes SkipTest
258 Decorator, which, when applied to a function, causes SkipTest
259 to be raised, with the optional message added.
259 to be raised, with the optional message added.
260 """
260 """
261
261
262 return skipif(True,msg)
262 return skipif(True,msg)
263
263
264
264
265 def onlyif(condition, msg):
265 def onlyif(condition, msg):
266 """The reverse from skipif, see skipif for details."""
266 """The reverse from skipif, see skipif for details."""
267
267
268 if callable(condition):
268 if callable(condition):
269 skip_condition = lambda : not condition()
269 skip_condition = lambda : not condition()
270 else:
270 else:
271 skip_condition = lambda : not condition
271 skip_condition = lambda : not condition
272
272
273 return skipif(skip_condition, msg)
273 return skipif(skip_condition, msg)
274
274
275 #-----------------------------------------------------------------------------
275 #-----------------------------------------------------------------------------
276 # Utility functions for decorators
276 # Utility functions for decorators
277 def numpy_not_available():
277 def numpy_not_available():
278 """Can numpy be imported? Returns true if numpy does NOT import.
278 """Can numpy be imported? Returns true if numpy does NOT import.
279
279
280 This is used to make a decorator to skip tests that require numpy to be
280 This is used to make a decorator to skip tests that require numpy to be
281 available, but delay the 'import numpy' to test execution time.
281 available, but delay the 'import numpy' to test execution time.
282 """
282 """
283 try:
283 try:
284 import numpy
284 import numpy
285 np_not_avail = False
285 np_not_avail = False
286 except ImportError:
286 except ImportError:
287 np_not_avail = True
287 np_not_avail = True
288
288
289 return np_not_avail
289 return np_not_avail
290
290
291 #-----------------------------------------------------------------------------
291 #-----------------------------------------------------------------------------
292 # Decorators for public use
292 # Decorators for public use
293
293
294 skip_doctest = make_label_dec('skip_doctest',
294 skip_doctest = make_label_dec('skip_doctest',
295 """Decorator - mark a function or method for skipping its doctest.
295 """Decorator - mark a function or method for skipping its doctest.
296
296
297 This decorator allows you to mark a function whose docstring you wish to
297 This decorator allows you to mark a function whose docstring you wish to
298 omit from testing, while preserving the docstring for introspection, help,
298 omit from testing, while preserving the docstring for introspection, help,
299 etc.""")
299 etc.""")
300
300
301 # Decorators to skip certain tests on specific platforms.
301 # Decorators to skip certain tests on specific platforms.
302 skip_win32 = skipif(sys.platform == 'win32',
302 skip_win32 = skipif(sys.platform == 'win32',
303 "This test does not run under Windows")
303 "This test does not run under Windows")
304 skip_linux = skipif(sys.platform == 'linux2',
304 skip_linux = skipif(sys.platform == 'linux2',
305 "This test does not run under Linux")
305 "This test does not run under Linux")
306 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
306 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
307
307
308
308
309 # Decorators to skip tests if not on specific platforms.
309 # Decorators to skip tests if not on specific platforms.
310 skip_if_not_win32 = skipif(sys.platform != 'win32',
310 skip_if_not_win32 = skipif(sys.platform != 'win32',
311 "This test only runs under Windows")
311 "This test only runs under Windows")
312 skip_if_not_linux = skipif(sys.platform != 'linux2',
312 skip_if_not_linux = skipif(sys.platform != 'linux2',
313 "This test only runs under Linux")
313 "This test only runs under Linux")
314 skip_if_not_osx = skipif(sys.platform != 'darwin',
314 skip_if_not_osx = skipif(sys.platform != 'darwin',
315 "This test only runs under OSX")
315 "This test only runs under OSX")
316
316
317 # Other skip decorators
317 # Other skip decorators
318 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
318 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
319
319
320 skipknownfailure = skip('This test is known to fail')
320 skip_known_failure = skip('This test is known to fail')
321
321
322 # A null 'decorator', useful to make more readable code that needs to pick
322 # A null 'decorator', useful to make more readable code that needs to pick
323 # between different decorators based on OS or other conditions
323 # between different decorators based on OS or other conditions
324 null_deco = lambda f: f
324 null_deco = lambda f: f
@@ -1,132 +1,132 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Testing related decorators for use with twisted.trial.
3 Testing related decorators for use with twisted.trial.
4
4
5 The decorators in this files are designed to follow the same API as those
5 The decorators in this files are designed to follow the same API as those
6 in the decorators module (in this same directory). But they can be used
6 in the decorators module (in this same directory). But they can be used
7 with twisted.trial
7 with twisted.trial
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2009 The IPython Development Team
11 # Copyright (C) 2008-2009 The IPython Development Team
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 import os
21 import os
22 import sys
22 import sys
23
23
24 from IPython.testing.decorators import make_label_dec
24 from IPython.testing.decorators import make_label_dec
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Testing decorators
27 # Testing decorators
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30
30
31 def skipif(skip_condition, msg=None):
31 def skipif(skip_condition, msg=None):
32 """Create a decorator that marks a test function for skipping.
32 """Create a decorator that marks a test function for skipping.
33
33
34 The is a decorator factory that returns a decorator that will
34 The is a decorator factory that returns a decorator that will
35 conditionally skip a test based on the value of skip_condition. The
35 conditionally skip a test based on the value of skip_condition. The
36 skip_condition argument can either be a boolean or a callable that returns
36 skip_condition argument can either be a boolean or a callable that returns
37 a boolean.
37 a boolean.
38
38
39 Parameters
39 Parameters
40 ----------
40 ----------
41 skip_condition : boolean or callable
41 skip_condition : boolean or callable
42 If this evaluates to True, the test is skipped.
42 If this evaluates to True, the test is skipped.
43 msg : str
43 msg : str
44 The message to print if the test is skipped.
44 The message to print if the test is skipped.
45
45
46 Returns
46 Returns
47 -------
47 -------
48 decorator : function
48 decorator : function
49 The decorator function that can be applied to the test function.
49 The decorator function that can be applied to the test function.
50 """
50 """
51
51
52 def skip_decorator(f):
52 def skip_decorator(f):
53
53
54 # Allow for both boolean or callable skip conditions.
54 # Allow for both boolean or callable skip conditions.
55 if callable(skip_condition):
55 if callable(skip_condition):
56 skip_val = lambda : skip_condition()
56 skip_val = lambda : skip_condition()
57 else:
57 else:
58 skip_val = lambda : skip_condition
58 skip_val = lambda : skip_condition
59
59
60 if msg is None:
60 if msg is None:
61 out = 'Test skipped due to test condition.'
61 out = 'Test skipped due to test condition.'
62 else:
62 else:
63 out = msg
63 out = msg
64 final_msg = "Skipping test: %s. %s" % (f.__name__,out)
64 final_msg = "Skipping test: %s. %s" % (f.__name__,out)
65
65
66 if skip_val():
66 if skip_val():
67 f.skip = final_msg
67 f.skip = final_msg
68
68
69 return f
69 return f
70 return skip_decorator
70 return skip_decorator
71
71
72
72
73 def skip(msg=None):
73 def skip(msg=None):
74 """Create a decorator that marks a test function for skipping.
74 """Create a decorator that marks a test function for skipping.
75
75
76 This is a decorator factory that returns a decorator that will cause
76 This is a decorator factory that returns a decorator that will cause
77 tests to be skipped.
77 tests to be skipped.
78
78
79 Parameters
79 Parameters
80 ----------
80 ----------
81 msg : str
81 msg : str
82 Optional message to be added.
82 Optional message to be added.
83
83
84 Returns
84 Returns
85 -------
85 -------
86 decorator : function
86 decorator : function
87 Decorator, which, when applied to a function, sets the skip
87 Decorator, which, when applied to a function, sets the skip
88 attribute of the function causing `twisted.trial` to skip it.
88 attribute of the function causing `twisted.trial` to skip it.
89 """
89 """
90
90
91 return skipif(True,msg)
91 return skipif(True,msg)
92
92
93
93
94 def numpy_not_available():
94 def numpy_not_available():
95 """Can numpy be imported? Returns true if numpy does NOT import.
95 """Can numpy be imported? Returns true if numpy does NOT import.
96
96
97 This is used to make a decorator to skip tests that require numpy to be
97 This is used to make a decorator to skip tests that require numpy to be
98 available, but delay the 'import numpy' to test execution time.
98 available, but delay the 'import numpy' to test execution time.
99 """
99 """
100 try:
100 try:
101 import numpy
101 import numpy
102 np_not_avail = False
102 np_not_avail = False
103 except ImportError:
103 except ImportError:
104 np_not_avail = True
104 np_not_avail = True
105
105
106 return np_not_avail
106 return np_not_avail
107
107
108 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
109 # Decorators for public use
109 # Decorators for public use
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111
111
112 # Decorators to skip certain tests on specific platforms.
112 # Decorators to skip certain tests on specific platforms.
113 skip_win32 = skipif(sys.platform == 'win32',
113 skip_win32 = skipif(sys.platform == 'win32',
114 "This test does not run under Windows")
114 "This test does not run under Windows")
115 skip_linux = skipif(sys.platform == 'linux2',
115 skip_linux = skipif(sys.platform == 'linux2',
116 "This test does not run under Linux")
116 "This test does not run under Linux")
117 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
117 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
118
118
119 # Decorators to skip tests if not on specific platforms.
119 # Decorators to skip tests if not on specific platforms.
120 skip_if_not_win32 = skipif(sys.platform != 'win32',
120 skip_if_not_win32 = skipif(sys.platform != 'win32',
121 "This test only runs under Windows")
121 "This test only runs under Windows")
122 skip_if_not_linux = skipif(sys.platform != 'linux2',
122 skip_if_not_linux = skipif(sys.platform != 'linux2',
123 "This test only runs under Linux")
123 "This test only runs under Linux")
124 skip_if_not_osx = skipif(sys.platform != 'darwin',
124 skip_if_not_osx = skipif(sys.platform != 'darwin',
125 "This test only runs under OSX")
125 "This test only runs under OSX")
126
126
127 # Other skip decorators
127 # Other skip decorators
128 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
128 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
129
129
130 skipknownfailure = skip('This test is known to fail')
130 skip_known_failure = skip('This test is known to fail')
131
131
132
132
@@ -1,367 +1,369 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
16
17 # Standard library imports.
17 # Standard library imports.
18 import __builtin__
18 import __builtin__
19 from code import CommandCompiler
19 from code import CommandCompiler
20 import os
20 import os
21 import sys
21 import sys
22 import time
22 import time
23 import traceback
23 import traceback
24
24
25 # System library imports.
25 # System library imports.
26 import zmq
26 import zmq
27
27
28 # Local imports.
28 # Local imports.
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
30 from IPython.zmq.zmqshell import ZMQInteractiveShell
30 from IPython.zmq.zmqshell import ZMQInteractiveShell
31 from IPython.external.argparse import ArgumentParser
31 from IPython.external.argparse import ArgumentParser
32 from IPython.utils.traitlets import Instance
32 from IPython.utils.traitlets import Instance
33 from IPython.zmq.session import Session, Message
33 from IPython.zmq.session import Session, Message
34 from completer import KernelCompleter
34 from completer import KernelCompleter
35 from iostream import OutStream
35 from iostream import OutStream
36 from displayhook import DisplayHook
36 from displayhook import DisplayHook
37 from exitpoller import ExitPollerUnix, ExitPollerWindows
37 from exitpoller import ExitPollerUnix, ExitPollerWindows
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Main kernel class
40 # Main kernel class
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42
42
43 class Kernel(Configurable):
43 class Kernel(Configurable):
44
44
45 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
45 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
46 session = Instance('IPython.zmq.session.Session')
46 session = Instance('IPython.zmq.session.Session')
47 reply_socket = Instance('zmq.Socket')
47 reply_socket = Instance('zmq.Socket')
48 pub_socket = Instance('zmq.Socket')
48 pub_socket = Instance('zmq.Socket')
49 req_socket = Instance('zmq.Socket')
49 req_socket = Instance('zmq.Socket')
50
50
51 def __init__(self, **kwargs):
51 def __init__(self, **kwargs):
52 super(Kernel, self).__init__(**kwargs)
52 super(Kernel, self).__init__(**kwargs)
53
54 # Initialize the InteractiveShell subclass
53 self.shell = ZMQInteractiveShell.instance()
55 self.shell = ZMQInteractiveShell.instance()
54
56 self.shell.displayhook.session = self.session
57 self.shell.displayhook.pub_socket = self.pub_socket
58
55 # Build dict of handlers for message types
59 # Build dict of handlers for message types
56 msg_types = [ 'execute_request', 'complete_request',
60 msg_types = [ 'execute_request', 'complete_request',
57 'object_info_request' ]
61 'object_info_request' ]
58 self.handlers = {}
62 self.handlers = {}
59 for msg_type in msg_types:
63 for msg_type in msg_types:
60 self.handlers[msg_type] = getattr(self, msg_type)
64 self.handlers[msg_type] = getattr(self, msg_type)
61
65
62 def abort_queue(self):
66 def abort_queue(self):
63 while True:
67 while True:
64 try:
68 try:
65 ident = self.reply_socket.recv(zmq.NOBLOCK)
69 ident = self.reply_socket.recv(zmq.NOBLOCK)
66 except zmq.ZMQError, e:
70 except zmq.ZMQError, e:
67 if e.errno == zmq.EAGAIN:
71 if e.errno == zmq.EAGAIN:
68 break
72 break
69 else:
73 else:
70 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
74 assert self.reply_socket.rcvmore(), "Unexpected missing message part."
71 msg = self.reply_socket.recv_json()
75 msg = self.reply_socket.recv_json()
72 print>>sys.__stdout__, "Aborting:"
76 print>>sys.__stdout__, "Aborting:"
73 print>>sys.__stdout__, Message(msg)
77 print>>sys.__stdout__, Message(msg)
74 msg_type = msg['msg_type']
78 msg_type = msg['msg_type']
75 reply_type = msg_type.split('_')[0] + '_reply'
79 reply_type = msg_type.split('_')[0] + '_reply'
76 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
80 reply_msg = self.session.msg(reply_type, {'status' : 'aborted'}, msg)
77 print>>sys.__stdout__, Message(reply_msg)
81 print>>sys.__stdout__, Message(reply_msg)
78 self.reply_socket.send(ident,zmq.SNDMORE)
82 self.reply_socket.send(ident,zmq.SNDMORE)
79 self.reply_socket.send_json(reply_msg)
83 self.reply_socket.send_json(reply_msg)
80 # We need to wait a bit for requests to come in. This can probably
84 # We need to wait a bit for requests to come in. This can probably
81 # be set shorter for true asynchronous clients.
85 # be set shorter for true asynchronous clients.
82 time.sleep(0.1)
86 time.sleep(0.1)
83
87
84 def execute_request(self, ident, parent):
88 def execute_request(self, ident, parent):
85 try:
89 try:
86 code = parent[u'content'][u'code']
90 code = parent[u'content'][u'code']
87 except:
91 except:
88 print>>sys.__stderr__, "Got bad msg: "
92 print>>sys.__stderr__, "Got bad msg: "
89 print>>sys.__stderr__, Message(parent)
93 print>>sys.__stderr__, Message(parent)
90 return
94 return
91 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
95 pyin_msg = self.session.msg(u'pyin',{u'code':code}, parent=parent)
92 self.pub_socket.send_json(pyin_msg)
96 self.pub_socket.send_json(pyin_msg)
93
97
94 try:
98 try:
95 # Replace raw_input. Note that is not sufficient to replace
99 # Replace raw_input. Note that is not sufficient to replace
96 # raw_input in the user namespace.
100 # raw_input in the user namespace.
97 raw_input = lambda prompt='': self.raw_input(prompt, ident, parent)
101 raw_input = lambda prompt='': self.raw_input(prompt, ident, parent)
98 __builtin__.raw_input = raw_input
102 __builtin__.raw_input = raw_input
99
103
100 # Configure the display hook.
104 # Set the parent message of the display hook.
101 sys.displayhook.set_parent(parent)
105 self.shell.displayhook.set_parent(parent)
102
106
103 self.shell.runlines(code)
107 self.shell.runlines(code)
104 # exec comp_code in self.user_ns, self.user_ns
108 # exec comp_code in self.user_ns, self.user_ns
105 except:
109 except:
106 etype, evalue, tb = sys.exc_info()
110 etype, evalue, tb = sys.exc_info()
107 tb = traceback.format_exception(etype, evalue, tb)
111 tb = traceback.format_exception(etype, evalue, tb)
108 exc_content = {
112 exc_content = {
109 u'status' : u'error',
113 u'status' : u'error',
110 u'traceback' : tb,
114 u'traceback' : tb,
111 u'ename' : unicode(etype.__name__),
115 u'ename' : unicode(etype.__name__),
112 u'evalue' : unicode(evalue)
116 u'evalue' : unicode(evalue)
113 }
117 }
114 exc_msg = self.session.msg(u'pyerr', exc_content, parent)
118 exc_msg = self.session.msg(u'pyerr', exc_content, parent)
115 self.pub_socket.send_json(exc_msg)
119 self.pub_socket.send_json(exc_msg)
116 reply_content = exc_content
120 reply_content = exc_content
117 else:
121 else:
118 reply_content = {'status' : 'ok'}
122 reply_content = {'status' : 'ok'}
119
123
120 # Flush output before sending the reply.
124 # Flush output before sending the reply.
121 sys.stderr.flush()
125 sys.stderr.flush()
122 sys.stdout.flush()
126 sys.stdout.flush()
123
127
124 # Send the reply.
128 # Send the reply.
125 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
129 reply_msg = self.session.msg(u'execute_reply', reply_content, parent)
126 print>>sys.__stdout__, Message(reply_msg)
130 print>>sys.__stdout__, Message(reply_msg)
127 self.reply_socket.send(ident, zmq.SNDMORE)
131 self.reply_socket.send(ident, zmq.SNDMORE)
128 self.reply_socket.send_json(reply_msg)
132 self.reply_socket.send_json(reply_msg)
129 if reply_msg['content']['status'] == u'error':
133 if reply_msg['content']['status'] == u'error':
130 self.abort_queue()
134 self.abort_queue()
131
135
132 def raw_input(self, prompt, ident, parent):
136 def raw_input(self, prompt, ident, parent):
133 # Flush output before making the request.
137 # Flush output before making the request.
134 sys.stderr.flush()
138 sys.stderr.flush()
135 sys.stdout.flush()
139 sys.stdout.flush()
136
140
137 # Send the input request.
141 # Send the input request.
138 content = dict(prompt=prompt)
142 content = dict(prompt=prompt)
139 msg = self.session.msg(u'input_request', content, parent)
143 msg = self.session.msg(u'input_request', content, parent)
140 self.req_socket.send_json(msg)
144 self.req_socket.send_json(msg)
141
145
142 # Await a response.
146 # Await a response.
143 reply = self.req_socket.recv_json()
147 reply = self.req_socket.recv_json()
144 try:
148 try:
145 value = reply['content']['value']
149 value = reply['content']['value']
146 except:
150 except:
147 print>>sys.__stderr__, "Got bad raw_input reply: "
151 print>>sys.__stderr__, "Got bad raw_input reply: "
148 print>>sys.__stderr__, Message(parent)
152 print>>sys.__stderr__, Message(parent)
149 value = ''
153 value = ''
150 return value
154 return value
151
155
152 def complete_request(self, ident, parent):
156 def complete_request(self, ident, parent):
153 matches = {'matches' : self.complete(parent),
157 matches = {'matches' : self.complete(parent),
154 'status' : 'ok'}
158 'status' : 'ok'}
155 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
159 completion_msg = self.session.send(self.reply_socket, 'complete_reply',
156 matches, parent, ident)
160 matches, parent, ident)
157 print >> sys.__stdout__, completion_msg
161 print >> sys.__stdout__, completion_msg
158
162
159 def complete(self, msg):
163 def complete(self, msg):
160 return self.shell.complete(msg.content.line)
164 return self.shell.complete(msg.content.line)
161
165
162 def object_info_request(self, ident, parent):
166 def object_info_request(self, ident, parent):
163 context = parent['content']['oname'].split('.')
167 context = parent['content']['oname'].split('.')
164 object_info = self.object_info(context)
168 object_info = self.object_info(context)
165 msg = self.session.send(self.reply_socket, 'object_info_reply',
169 msg = self.session.send(self.reply_socket, 'object_info_reply',
166 object_info, parent, ident)
170 object_info, parent, ident)
167 print >> sys.__stdout__, msg
171 print >> sys.__stdout__, msg
168
172
169 def object_info(self, context):
173 def object_info(self, context):
170 symbol, leftover = self.symbol_from_context(context)
174 symbol, leftover = self.symbol_from_context(context)
171 if symbol is not None and not leftover:
175 if symbol is not None and not leftover:
172 doc = getattr(symbol, '__doc__', '')
176 doc = getattr(symbol, '__doc__', '')
173 else:
177 else:
174 doc = ''
178 doc = ''
175 object_info = dict(docstring = doc)
179 object_info = dict(docstring = doc)
176 return object_info
180 return object_info
177
181
178 def symbol_from_context(self, context):
182 def symbol_from_context(self, context):
179 if not context:
183 if not context:
180 return None, context
184 return None, context
181
185
182 base_symbol_string = context[0]
186 base_symbol_string = context[0]
183 symbol = self.shell.user_ns.get(base_symbol_string, None)
187 symbol = self.shell.user_ns.get(base_symbol_string, None)
184 if symbol is None:
188 if symbol is None:
185 symbol = __builtin__.__dict__.get(base_symbol_string, None)
189 symbol = __builtin__.__dict__.get(base_symbol_string, None)
186 if symbol is None:
190 if symbol is None:
187 return None, context
191 return None, context
188
192
189 context = context[1:]
193 context = context[1:]
190 for i, name in enumerate(context):
194 for i, name in enumerate(context):
191 new_symbol = getattr(symbol, name, None)
195 new_symbol = getattr(symbol, name, None)
192 if new_symbol is None:
196 if new_symbol is None:
193 return symbol, context[i:]
197 return symbol, context[i:]
194 else:
198 else:
195 symbol = new_symbol
199 symbol = new_symbol
196
200
197 return symbol, []
201 return symbol, []
198
202
199 def start(self):
203 def start(self):
200 while True:
204 while True:
201 ident = self.reply_socket.recv()
205 ident = self.reply_socket.recv()
202 assert self.reply_socket.rcvmore(), "Missing message part."
206 assert self.reply_socket.rcvmore(), "Missing message part."
203 msg = self.reply_socket.recv_json()
207 msg = self.reply_socket.recv_json()
204 omsg = Message(msg)
208 omsg = Message(msg)
205 print>>sys.__stdout__
209 print>>sys.__stdout__
206 print>>sys.__stdout__, omsg
210 print>>sys.__stdout__, omsg
207 handler = self.handlers.get(omsg.msg_type, None)
211 handler = self.handlers.get(omsg.msg_type, None)
208 if handler is None:
212 if handler is None:
209 print >> sys.__stderr__, "UNKNOWN MESSAGE TYPE:", omsg
213 print >> sys.__stderr__, "UNKNOWN MESSAGE TYPE:", omsg
210 else:
214 else:
211 handler(ident, omsg)
215 handler(ident, omsg)
212
216
213 #-----------------------------------------------------------------------------
217 #-----------------------------------------------------------------------------
214 # Kernel main and launch functions
218 # Kernel main and launch functions
215 #-----------------------------------------------------------------------------
219 #-----------------------------------------------------------------------------
216
220
217 def bind_port(socket, ip, port):
221 def bind_port(socket, ip, port):
218 """ Binds the specified ZMQ socket. If the port is less than zero, a random
222 """ Binds the specified ZMQ socket. If the port is less than zero, a random
219 port is chosen. Returns the port that was bound.
223 port is chosen. Returns the port that was bound.
220 """
224 """
221 connection = 'tcp://%s' % ip
225 connection = 'tcp://%s' % ip
222 if port <= 0:
226 if port <= 0:
223 port = socket.bind_to_random_port(connection)
227 port = socket.bind_to_random_port(connection)
224 else:
228 else:
225 connection += ':%i' % port
229 connection += ':%i' % port
226 socket.bind(connection)
230 socket.bind(connection)
227 return port
231 return port
228
232
229
233
230 def main():
234 def main():
231 """ Main entry point for launching a kernel.
235 """ Main entry point for launching a kernel.
232 """
236 """
233 # Parse command line arguments.
237 # Parse command line arguments.
234 parser = ArgumentParser()
238 parser = ArgumentParser()
235 parser.add_argument('--ip', type=str, default='127.0.0.1',
239 parser.add_argument('--ip', type=str, default='127.0.0.1',
236 help='set the kernel\'s IP address [default: local]')
240 help='set the kernel\'s IP address [default: local]')
237 parser.add_argument('--xrep', type=int, metavar='PORT', default=0,
241 parser.add_argument('--xrep', type=int, metavar='PORT', default=0,
238 help='set the XREP channel port [default: random]')
242 help='set the XREP channel port [default: random]')
239 parser.add_argument('--pub', type=int, metavar='PORT', default=0,
243 parser.add_argument('--pub', type=int, metavar='PORT', default=0,
240 help='set the PUB channel port [default: random]')
244 help='set the PUB channel port [default: random]')
241 parser.add_argument('--req', type=int, metavar='PORT', default=0,
245 parser.add_argument('--req', type=int, metavar='PORT', default=0,
242 help='set the REQ channel port [default: random]')
246 help='set the REQ channel port [default: random]')
243 if sys.platform == 'win32':
247 if sys.platform == 'win32':
244 parser.add_argument('--parent', type=int, metavar='HANDLE',
248 parser.add_argument('--parent', type=int, metavar='HANDLE',
245 default=0, help='kill this process if the process '
249 default=0, help='kill this process if the process '
246 'with HANDLE dies')
250 'with HANDLE dies')
247 else:
251 else:
248 parser.add_argument('--parent', action='store_true',
252 parser.add_argument('--parent', action='store_true',
249 help='kill this process if its parent dies')
253 help='kill this process if its parent dies')
250 namespace = parser.parse_args()
254 namespace = parser.parse_args()
251
255
252 # Create a context, a session, and the kernel sockets.
256 # Create a context, a session, and the kernel sockets.
253 print >>sys.__stdout__, "Starting the kernel..."
257 print >>sys.__stdout__, "Starting the kernel..."
254 context = zmq.Context()
258 context = zmq.Context()
255 session = Session(username=u'kernel')
259 session = Session(username=u'kernel')
256
260
257 reply_socket = context.socket(zmq.XREP)
261 reply_socket = context.socket(zmq.XREP)
258 xrep_port = bind_port(reply_socket, namespace.ip, namespace.xrep)
262 xrep_port = bind_port(reply_socket, namespace.ip, namespace.xrep)
259 print >>sys.__stdout__, "XREP Channel on port", xrep_port
263 print >>sys.__stdout__, "XREP Channel on port", xrep_port
260
264
261 pub_socket = context.socket(zmq.PUB)
265 pub_socket = context.socket(zmq.PUB)
262 pub_port = bind_port(pub_socket, namespace.ip, namespace.pub)
266 pub_port = bind_port(pub_socket, namespace.ip, namespace.pub)
263 print >>sys.__stdout__, "PUB Channel on port", pub_port
267 print >>sys.__stdout__, "PUB Channel on port", pub_port
264
268
265 req_socket = context.socket(zmq.XREQ)
269 req_socket = context.socket(zmq.XREQ)
266 req_port = bind_port(req_socket, namespace.ip, namespace.req)
270 req_port = bind_port(req_socket, namespace.ip, namespace.req)
267 print >>sys.__stdout__, "REQ Channel on port", req_port
271 print >>sys.__stdout__, "REQ Channel on port", req_port
268
272
269 # Redirect input streams. This needs to be done before the Kernel is done
273 # Redirect input streams. This needs to be done before the Kernel is done
270 # because currently the Kernel creates a ZMQInteractiveShell, which
274 # because currently the Kernel creates a ZMQInteractiveShell, which
271 # holds references to sys.stdout and sys.stderr.
275 # holds references to sys.stdout and sys.stderr.
272 sys.stdout = OutStream(session, pub_socket, u'stdout')
276 sys.stdout = OutStream(session, pub_socket, u'stdout')
273 sys.stderr = OutStream(session, pub_socket, u'stderr')
277 sys.stderr = OutStream(session, pub_socket, u'stderr')
274 # Set a displayhook.
275 sys.displayhook = DisplayHook(session, pub_socket)
276
278
277 # Create the kernel.
279 # Create the kernel.
278 kernel = Kernel(
280 kernel = Kernel(
279 session=session, reply_socket=reply_socket,
281 session=session, reply_socket=reply_socket,
280 pub_socket=pub_socket, req_socket=req_socket
282 pub_socket=pub_socket, req_socket=req_socket
281 )
283 )
282
284
283 # Configure this kernel/process to die on parent termination, if necessary.
285 # Configure this kernel/process to die on parent termination, if necessary.
284 if namespace.parent:
286 if namespace.parent:
285 if sys.platform == 'win32':
287 if sys.platform == 'win32':
286 poller = ExitPollerWindows(namespace.parent)
288 poller = ExitPollerWindows(namespace.parent)
287 else:
289 else:
288 poller = ExitPollerUnix()
290 poller = ExitPollerUnix()
289 poller.start()
291 poller.start()
290
292
291 # Start the kernel mainloop.
293 # Start the kernel mainloop.
292 kernel.start()
294 kernel.start()
293
295
294
296
295 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False):
297 def launch_kernel(xrep_port=0, pub_port=0, req_port=0, independent=False):
296 """ Launches a localhost kernel, binding to the specified ports.
298 """ Launches a localhost kernel, binding to the specified ports.
297
299
298 Parameters
300 Parameters
299 ----------
301 ----------
300 xrep_port : int, optional
302 xrep_port : int, optional
301 The port to use for XREP channel.
303 The port to use for XREP channel.
302
304
303 pub_port : int, optional
305 pub_port : int, optional
304 The port to use for the SUB channel.
306 The port to use for the SUB channel.
305
307
306 req_port : int, optional
308 req_port : int, optional
307 The port to use for the REQ (raw input) channel.
309 The port to use for the REQ (raw input) channel.
308
310
309 independent : bool, optional (default False)
311 independent : bool, optional (default False)
310 If set, the kernel process is guaranteed to survive if this process
312 If set, the kernel process is guaranteed to survive if this process
311 dies. If not set, an effort is made to ensure that the kernel is killed
313 dies. If not set, an effort is made to ensure that the kernel is killed
312 when this process dies. Note that in this case it is still good practice
314 when this process dies. Note that in this case it is still good practice
313 to kill kernels manually before exiting.
315 to kill kernels manually before exiting.
314
316
315 Returns
317 Returns
316 -------
318 -------
317 A tuple of form:
319 A tuple of form:
318 (kernel_process, xrep_port, pub_port, req_port)
320 (kernel_process, xrep_port, pub_port, req_port)
319 where kernel_process is a Popen object and the ports are integers.
321 where kernel_process is a Popen object and the ports are integers.
320 """
322 """
321 import socket
323 import socket
322 from subprocess import Popen
324 from subprocess import Popen
323
325
324 # Find open ports as necessary.
326 # Find open ports as necessary.
325 ports = []
327 ports = []
326 ports_needed = int(xrep_port <= 0) + int(pub_port <= 0) + int(req_port <= 0)
328 ports_needed = int(xrep_port <= 0) + int(pub_port <= 0) + int(req_port <= 0)
327 for i in xrange(ports_needed):
329 for i in xrange(ports_needed):
328 sock = socket.socket()
330 sock = socket.socket()
329 sock.bind(('', 0))
331 sock.bind(('', 0))
330 ports.append(sock)
332 ports.append(sock)
331 for i, sock in enumerate(ports):
333 for i, sock in enumerate(ports):
332 port = sock.getsockname()[1]
334 port = sock.getsockname()[1]
333 sock.close()
335 sock.close()
334 ports[i] = port
336 ports[i] = port
335 if xrep_port <= 0:
337 if xrep_port <= 0:
336 xrep_port = ports.pop(0)
338 xrep_port = ports.pop(0)
337 if pub_port <= 0:
339 if pub_port <= 0:
338 pub_port = ports.pop(0)
340 pub_port = ports.pop(0)
339 if req_port <= 0:
341 if req_port <= 0:
340 req_port = ports.pop(0)
342 req_port = ports.pop(0)
341
343
342 # Spawn a kernel.
344 # Spawn a kernel.
343 command = 'from IPython.zmq.ipkernel import main; main()'
345 command = 'from IPython.zmq.ipkernel import main; main()'
344 arguments = [ sys.executable, '-c', command, '--xrep', str(xrep_port),
346 arguments = [ sys.executable, '-c', command, '--xrep', str(xrep_port),
345 '--pub', str(pub_port), '--req', str(req_port) ]
347 '--pub', str(pub_port), '--req', str(req_port) ]
346 if independent:
348 if independent:
347 if sys.platform == 'win32':
349 if sys.platform == 'win32':
348 proc = Popen(['start', '/b'] + arguments, shell=True)
350 proc = Popen(['start', '/b'] + arguments, shell=True)
349 else:
351 else:
350 proc = Popen(arguments, preexec_fn=lambda: os.setsid())
352 proc = Popen(arguments, preexec_fn=lambda: os.setsid())
351 else:
353 else:
352 if sys.platform == 'win32':
354 if sys.platform == 'win32':
353 from _subprocess import DuplicateHandle, GetCurrentProcess, \
355 from _subprocess import DuplicateHandle, GetCurrentProcess, \
354 DUPLICATE_SAME_ACCESS
356 DUPLICATE_SAME_ACCESS
355 pid = GetCurrentProcess()
357 pid = GetCurrentProcess()
356 handle = DuplicateHandle(pid, pid, pid, 0,
358 handle = DuplicateHandle(pid, pid, pid, 0,
357 True, # Inheritable by new processes.
359 True, # Inheritable by new processes.
358 DUPLICATE_SAME_ACCESS)
360 DUPLICATE_SAME_ACCESS)
359 proc = Popen(arguments + ['--parent', str(int(handle))])
361 proc = Popen(arguments + ['--parent', str(int(handle))])
360 else:
362 else:
361 proc = Popen(arguments + ['--parent'])
363 proc = Popen(arguments + ['--parent'])
362
364
363 return proc, xrep_port, pub_port, req_port
365 return proc, xrep_port, pub_port, req_port
364
366
365
367
366 if __name__ == '__main__':
368 if __name__ == '__main__':
367 main()
369 main()
@@ -1,31 +1,72 b''
1 import sys
1 import sys
2 from subprocess import Popen, PIPE
2 from subprocess import Popen, PIPE
3 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
3
4 from IPython.core.interactiveshell import (
5 InteractiveShell, InteractiveShellABC
6 )
7 from IPython.core.displayhook import DisplayHook
8 from IPython.utils.traitlets import Instance, Type, Dict
9 from IPython.zmq.session import extract_header
10
11
12 class ZMQDisplayTrap(DisplayHook):
13
14 session = Instance('IPython.zmq.session.Session')
15 pub_socket = Instance('zmq.Socket')
16 parent_header = Dict({})
17
18 def set_parent(self, parent):
19 """Set the parent for outbound messages."""
20 self.parent_header = extract_header(parent)
21
22 def start_displayhook(self):
23 self.msg = self.session.msg(u'pyout', {}, parent=self.parent_header)
24
25 def write_output_prompt(self):
26 """Write the output prompt."""
27 if self.do_full_cache:
28 self.msg['content']['output_sep'] = self.output_sep
29 self.msg['content']['prompt_string'] = str(self.prompt_out)
30 self.msg['content']['prompt_number'] = self.prompt_count
31 self.msg['content']['output_sep2'] = self.output_sep2
32
33 def write_result_repr(self, result_repr):
34 self.msg['content']['data'] = result_repr
35
36 def finish_displayhook(self):
37 """Finish up all displayhook activities."""
38 self.pub_socket.send_json(self.msg)
39 self.msg = None
4
40
5
41
6 class ZMQInteractiveShell(InteractiveShell):
42 class ZMQInteractiveShell(InteractiveShell):
7 """A subclass of InteractiveShell for ZMQ."""
43 """A subclass of InteractiveShell for ZMQ."""
8
44
45 displayhook_class = Type(ZMQDisplayTrap)
46
9 def system(self, cmd):
47 def system(self, cmd):
10 cmd = self.var_expand(cmd, depth=2)
48 cmd = self.var_expand(cmd, depth=2)
11 sys.stdout.flush()
49 sys.stdout.flush()
12 sys.stderr.flush()
50 sys.stderr.flush()
13 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
51 p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
14 for line in p.stdout.read().split('\n'):
52 for line in p.stdout.read().split('\n'):
15 if len(line) > 0:
53 if len(line) > 0:
16 print line
54 print line
17 for line in p.stderr.read().split('\n'):
55 for line in p.stderr.read().split('\n'):
18 if len(line) > 0:
56 if len(line) > 0:
19 print line
57 print line
20 p.wait()
58 p.wait()
21
59
22 def init_io(self):
60 def init_io(self):
23 # This will just use sys.stdout and sys.stderr. If you want to
61 # This will just use sys.stdout and sys.stderr. If you want to
24 # override sys.stdout and sys.stderr themselves, you need to do that
62 # override sys.stdout and sys.stderr themselves, you need to do that
25 # *before* instantiating this class, because Term holds onto
63 # *before* instantiating this class, because Term holds onto
26 # references to the underlying streams.
64 # references to the underlying streams.
27 import IPython.utils.io
65 import IPython.utils.io
28 Term = IPython.utils.io.IOTerm()
66 Term = IPython.utils.io.IOTerm()
29 IPython.utils.io.Term = Term
67 IPython.utils.io.Term = Term
30
68
31 InteractiveShellABC.register(ZMQInteractiveShell)
69 InteractiveShellABC.register(ZMQInteractiveShell)
70
71
72
General Comments 0
You need to be logged in to leave comments. Login now