##// END OF EJS Templates
Better display of exception: do not display the calling code in the...
gvaroquaux -
Show More
@@ -1,230 +1,230 b''
1 """
1 """
2 Frontend class that uses IPython0 to prefilter the inputs.
2 Frontend class that uses IPython0 to prefilter the inputs.
3
3
4 Using the IPython0 mechanism gives us access to the magics.
4 Using the IPython0 mechanism gives us access to the magics.
5
5
6 This is a transitory class, used here to do the transition between
6 This is a transitory class, used here to do the transition between
7 ipython0 and ipython1. This class is meant to be short-lived as more
7 ipython0 and ipython1. This class is meant to be short-lived as more
8 functionnality is abstracted out of ipython0 in reusable functions and
8 functionnality is abstracted out of ipython0 in reusable functions and
9 is added on the interpreter. This class can be a used to guide this
9 is added on the interpreter. This class can be a used to guide this
10 refactoring.
10 refactoring.
11 """
11 """
12 __docformat__ = "restructuredtext en"
12 __docformat__ = "restructuredtext en"
13
13
14 #-------------------------------------------------------------------------------
14 #-------------------------------------------------------------------------------
15 # Copyright (C) 2008 The IPython Development Team
15 # Copyright (C) 2008 The IPython Development Team
16 #
16 #
17 # Distributed under the terms of the BSD License. The full license is in
17 # Distributed under the terms of the BSD License. The full license is in
18 # the file COPYING, distributed as part of this software.
18 # the file COPYING, distributed as part of this software.
19 #-------------------------------------------------------------------------------
19 #-------------------------------------------------------------------------------
20
20
21 #-------------------------------------------------------------------------------
21 #-------------------------------------------------------------------------------
22 # Imports
22 # Imports
23 #-------------------------------------------------------------------------------
23 #-------------------------------------------------------------------------------
24 import sys
24 import sys
25
25
26 from linefrontendbase import LineFrontEndBase, common_prefix
26 from linefrontendbase import LineFrontEndBase, common_prefix
27 from frontendbase import FrontEndBase
27 from frontendbase import FrontEndBase
28
28
29 from IPython.ipmaker import make_IPython
29 from IPython.ipmaker import make_IPython
30 from IPython.ipapi import IPApi
30 from IPython.ipapi import IPApi
31 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
31 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
32
32
33 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
33 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
34
34
35 from IPython.genutils import Term
35 from IPython.genutils import Term
36 import pydoc
36 import pydoc
37 import os
37 import os
38 import sys
38 import sys
39
39
40
40
41 def mk_system_call(system_call_function, command):
41 def mk_system_call(system_call_function, command):
42 """ given a os.system replacement, and a leading string command,
42 """ given a os.system replacement, and a leading string command,
43 returns a function that will execute the command with the given
43 returns a function that will execute the command with the given
44 argument string.
44 argument string.
45 """
45 """
46 def my_system_call(args):
46 def my_system_call(args):
47 system_call_function("%s %s" % (command, args))
47 system_call_function("%s %s" % (command, args))
48 return my_system_call
48 return my_system_call
49
49
50 #-------------------------------------------------------------------------------
50 #-------------------------------------------------------------------------------
51 # Frontend class using ipython0 to do the prefiltering.
51 # Frontend class using ipython0 to do the prefiltering.
52 #-------------------------------------------------------------------------------
52 #-------------------------------------------------------------------------------
53 class PrefilterFrontEnd(LineFrontEndBase):
53 class PrefilterFrontEnd(LineFrontEndBase):
54 """ Class that uses ipython0 to do prefilter the input, do the
54 """ Class that uses ipython0 to do prefilter the input, do the
55 completion and the magics.
55 completion and the magics.
56
56
57 The core trick is to use an ipython0 instance to prefilter the
57 The core trick is to use an ipython0 instance to prefilter the
58 input, and share the namespace between the interpreter instance used
58 input, and share the namespace between the interpreter instance used
59 to execute the statements and the ipython0 used for code
59 to execute the statements and the ipython0 used for code
60 completion...
60 completion...
61 """
61 """
62
62
63 debug = False
63 debug = False
64
64
65 def __init__(self, ipython0=None, *args, **kwargs):
65 def __init__(self, ipython0=None, *args, **kwargs):
66 """ Parameters:
66 """ Parameters:
67 -----------
67 -----------
68
68
69 ipython0: an optional ipython0 instance to use for command
69 ipython0: an optional ipython0 instance to use for command
70 prefiltering and completion.
70 prefiltering and completion.
71 """
71 """
72 LineFrontEndBase.__init__(self, *args, **kwargs)
72 LineFrontEndBase.__init__(self, *args, **kwargs)
73 self.shell.output_trap = RedirectorOutputTrap(
73 self.shell.output_trap = RedirectorOutputTrap(
74 out_callback=self.write,
74 out_callback=self.write,
75 err_callback=self.write,
75 err_callback=self.write,
76 )
76 )
77 self.shell.traceback_trap = SyncTracebackTrap(
77 self.shell.traceback_trap = SyncTracebackTrap(
78 formatters=self.shell.traceback_trap.formatters,
78 formatters=self.shell.traceback_trap.formatters,
79 )
79 )
80
80
81 # Start the ipython0 instance:
81 # Start the ipython0 instance:
82 self.save_output_hooks()
82 self.save_output_hooks()
83 if ipython0 is None:
83 if ipython0 is None:
84 # Instanciate an IPython0 interpreter to be able to use the
84 # Instanciate an IPython0 interpreter to be able to use the
85 # prefiltering.
85 # prefiltering.
86 # XXX: argv=[] is a bit bold.
86 # XXX: argv=[] is a bit bold.
87 ipython0 = make_IPython(argv=[],
87 ipython0 = make_IPython(argv=[],
88 user_ns=self.shell.user_ns,
88 user_ns=self.shell.user_ns,
89 user_global_ns=self.shell.user_global_ns)
89 user_global_ns=self.shell.user_global_ns)
90 self.ipython0 = ipython0
90 self.ipython0 = ipython0
91 # Set the pager:
91 # Set the pager:
92 self.ipython0.set_hook('show_in_pager',
92 self.ipython0.set_hook('show_in_pager',
93 lambda s, string: self.write("\n" + string))
93 lambda s, string: self.write("\n" + string))
94 self.ipython0.write = self.write
94 self.ipython0.write = self.write
95 self._ip = _ip = IPApi(self.ipython0)
95 self._ip = _ip = IPApi(self.ipython0)
96 # Make sure the raw system call doesn't get called, as we don't
96 # Make sure the raw system call doesn't get called, as we don't
97 # have a stdin accessible.
97 # have a stdin accessible.
98 self._ip.system = self.system_call
98 self._ip.system = self.system_call
99 # XXX: Muck around with magics so that they work better
99 # XXX: Muck around with magics so that they work better
100 # in our environment
100 # in our environment
101 self.ipython0.magic_ls = mk_system_call(self.system_call,
101 self.ipython0.magic_ls = mk_system_call(self.system_call,
102 'ls -CF')
102 'ls -CF')
103 # And now clean up the mess created by ipython0
103 # And now clean up the mess created by ipython0
104 self.release_output()
104 self.release_output()
105
105
106
106
107 if not 'banner' in kwargs and self.banner is None:
107 if not 'banner' in kwargs and self.banner is None:
108 self.banner = self.ipython0.BANNER + """
108 self.banner = self.ipython0.BANNER + """
109 This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
109 This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
110
110
111 self.start()
111 self.start()
112
112
113 #--------------------------------------------------------------------------
113 #--------------------------------------------------------------------------
114 # FrontEndBase interface
114 # FrontEndBase interface
115 #--------------------------------------------------------------------------
115 #--------------------------------------------------------------------------
116
116
117 def show_traceback(self):
117 def show_traceback(self):
118 """ Use ipython0 to capture the last traceback and display it.
118 """ Use ipython0 to capture the last traceback and display it.
119 """
119 """
120 self.capture_output()
120 self.capture_output()
121 self.ipython0.showtraceback()
121 self.ipython0.showtraceback(tb_offset=-1)
122 self.release_output()
122 self.release_output()
123
123
124
124
125 def execute(self, python_string, raw_string=None):
125 def execute(self, python_string, raw_string=None):
126 if self.debug:
126 if self.debug:
127 print 'Executing Python code:', repr(python_string)
127 print 'Executing Python code:', repr(python_string)
128 self.capture_output()
128 self.capture_output()
129 LineFrontEndBase.execute(self, python_string,
129 LineFrontEndBase.execute(self, python_string,
130 raw_string=raw_string)
130 raw_string=raw_string)
131 self.release_output()
131 self.release_output()
132
132
133
133
134 def save_output_hooks(self):
134 def save_output_hooks(self):
135 """ Store all the output hooks we can think of, to be able to
135 """ Store all the output hooks we can think of, to be able to
136 restore them.
136 restore them.
137
137
138 We need to do this early, as starting the ipython0 instance will
138 We need to do this early, as starting the ipython0 instance will
139 screw ouput hooks.
139 screw ouput hooks.
140 """
140 """
141 self.__old_cout_write = Term.cout.write
141 self.__old_cout_write = Term.cout.write
142 self.__old_cerr_write = Term.cerr.write
142 self.__old_cerr_write = Term.cerr.write
143 self.__old_stdout = sys.stdout
143 self.__old_stdout = sys.stdout
144 self.__old_stderr= sys.stderr
144 self.__old_stderr= sys.stderr
145 self.__old_help_output = pydoc.help.output
145 self.__old_help_output = pydoc.help.output
146 self.__old_display_hook = sys.displayhook
146 self.__old_display_hook = sys.displayhook
147
147
148
148
149 def capture_output(self):
149 def capture_output(self):
150 """ Capture all the output mechanisms we can think of.
150 """ Capture all the output mechanisms we can think of.
151 """
151 """
152 self.save_output_hooks()
152 self.save_output_hooks()
153 Term.cout.write = self.write
153 Term.cout.write = self.write
154 Term.cerr.write = self.write
154 Term.cerr.write = self.write
155 sys.stdout = Term.cout
155 sys.stdout = Term.cout
156 sys.stderr = Term.cerr
156 sys.stderr = Term.cerr
157 pydoc.help.output = self.shell.output_trap.out
157 pydoc.help.output = self.shell.output_trap.out
158
158
159
159
160 def release_output(self):
160 def release_output(self):
161 """ Release all the different captures we have made.
161 """ Release all the different captures we have made.
162 """
162 """
163 Term.cout.write = self.__old_cout_write
163 Term.cout.write = self.__old_cout_write
164 Term.cerr.write = self.__old_cerr_write
164 Term.cerr.write = self.__old_cerr_write
165 sys.stdout = self.__old_stdout
165 sys.stdout = self.__old_stdout
166 sys.stderr = self.__old_stderr
166 sys.stderr = self.__old_stderr
167 pydoc.help.output = self.__old_help_output
167 pydoc.help.output = self.__old_help_output
168 sys.displayhook = self.__old_display_hook
168 sys.displayhook = self.__old_display_hook
169
169
170
170
171 def complete(self, line):
171 def complete(self, line):
172 # FIXME: This should be factored out in the linefrontendbase
172 # FIXME: This should be factored out in the linefrontendbase
173 # method.
173 # method.
174 word = line.split('\n')[-1].split(' ')[-1]
174 word = line.split('\n')[-1].split(' ')[-1]
175 completions = self.ipython0.complete(word)
175 completions = self.ipython0.complete(word)
176 # FIXME: The proper sort should be done in the complete method.
176 # FIXME: The proper sort should be done in the complete method.
177 key = lambda x: x.replace('_', '')
177 key = lambda x: x.replace('_', '')
178 completions.sort(key=key)
178 completions.sort(key=key)
179 if completions:
179 if completions:
180 prefix = common_prefix(completions)
180 prefix = common_prefix(completions)
181 line = line[:-len(word)] + prefix
181 line = line[:-len(word)] + prefix
182 return line, completions
182 return line, completions
183
183
184
184
185 #--------------------------------------------------------------------------
185 #--------------------------------------------------------------------------
186 # LineFrontEndBase interface
186 # LineFrontEndBase interface
187 #--------------------------------------------------------------------------
187 #--------------------------------------------------------------------------
188
188
189 def prefilter_input(self, input_string):
189 def prefilter_input(self, input_string):
190 """ Using IPython0 to prefilter the commands to turn them
190 """ Using IPython0 to prefilter the commands to turn them
191 in executable statements that are valid Python strings.
191 in executable statements that are valid Python strings.
192 """
192 """
193 input_string = LineFrontEndBase.prefilter_input(self, input_string)
193 input_string = LineFrontEndBase.prefilter_input(self, input_string)
194 filtered_lines = []
194 filtered_lines = []
195 # The IPython0 prefilters sometime produce output. We need to
195 # The IPython0 prefilters sometime produce output. We need to
196 # capture it.
196 # capture it.
197 self.capture_output()
197 self.capture_output()
198 self.last_result = dict(number=self.prompt_number)
198 self.last_result = dict(number=self.prompt_number)
199 try:
199 try:
200 for line in input_string.split('\n'):
200 for line in input_string.split('\n'):
201 filtered_lines.append(
201 filtered_lines.append(
202 self.ipython0.prefilter(line, False).rstrip())
202 self.ipython0.prefilter(line, False).rstrip())
203 except:
203 except:
204 # XXX: probably not the right thing to do.
204 # XXX: probably not the right thing to do.
205 self.ipython0.showsyntaxerror()
205 self.ipython0.showsyntaxerror()
206 self.after_execute()
206 self.after_execute()
207 finally:
207 finally:
208 self.release_output()
208 self.release_output()
209
209
210 # Clean up the trailing whitespace, to avoid indentation errors
210 # Clean up the trailing whitespace, to avoid indentation errors
211 filtered_string = '\n'.join(filtered_lines)
211 filtered_string = '\n'.join(filtered_lines)
212 return filtered_string
212 return filtered_string
213
213
214
214
215 #--------------------------------------------------------------------------
215 #--------------------------------------------------------------------------
216 # PrefilterFrontEnd interface
216 # PrefilterFrontEnd interface
217 #--------------------------------------------------------------------------
217 #--------------------------------------------------------------------------
218
218
219 def system_call(self, command_string):
219 def system_call(self, command_string):
220 """ Allows for frontend to define their own system call, to be
220 """ Allows for frontend to define their own system call, to be
221 able capture output and redirect input.
221 able capture output and redirect input.
222 """
222 """
223 return os.system(command_string)
223 return os.system(command_string)
224
224
225
225
226 def do_exit(self):
226 def do_exit(self):
227 """ Exit the shell, cleanup and save the history.
227 """ Exit the shell, cleanup and save the history.
228 """
228 """
229 self.ipython0.atexit_operations()
229 self.ipython0.atexit_operations()
230
230
General Comments 0
You need to be logged in to leave comments. Login now