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