##// END OF EJS Templates
BUG: Remove forgotten debug code
Gael Varoquaux -
Show More
@@ -1,281 +1,280 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 import pydoc
25 import pydoc
26 import os
26 import os
27 import re
27 import re
28 import __builtin__
28 import __builtin__
29
29
30 from IPython.ipmaker import make_IPython
30 from IPython.ipmaker import make_IPython
31 from IPython.ipapi import IPApi
31 from IPython.ipapi import IPApi
32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
33
33
34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
35
35
36 from IPython.genutils import Term
36 from IPython.genutils import Term
37
37
38 from linefrontendbase import LineFrontEndBase, common_prefix
38 from linefrontendbase import LineFrontEndBase, common_prefix
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
48
49 my_system_call.__doc__ = "Calls %s" % command
49 my_system_call.__doc__ = "Calls %s" % command
50 return my_system_call
50 return my_system_call
51
51
52 #-------------------------------------------------------------------------------
52 #-------------------------------------------------------------------------------
53 # Frontend class using ipython0 to do the prefiltering.
53 # Frontend class using ipython0 to do the prefiltering.
54 #-------------------------------------------------------------------------------
54 #-------------------------------------------------------------------------------
55 class PrefilterFrontEnd(LineFrontEndBase):
55 class PrefilterFrontEnd(LineFrontEndBase):
56 """ Class that uses ipython0 to do prefilter the input, do the
56 """ Class that uses ipython0 to do prefilter the input, do the
57 completion and the magics.
57 completion and the magics.
58
58
59 The core trick is to use an ipython0 instance to prefilter the
59 The core trick is to use an ipython0 instance to prefilter the
60 input, and share the namespace between the interpreter instance used
60 input, and share the namespace between the interpreter instance used
61 to execute the statements and the ipython0 used for code
61 to execute the statements and the ipython0 used for code
62 completion...
62 completion...
63 """
63 """
64
64
65 debug = False
65 debug = False
66
66
67 def __init__(self, ipython0=None, *args, **kwargs):
67 def __init__(self, ipython0=None, *args, **kwargs):
68 """ Parameters:
68 """ Parameters:
69 -----------
69 -----------
70
70
71 ipython0: an optional ipython0 instance to use for command
71 ipython0: an optional ipython0 instance to use for command
72 prefiltering and completion.
72 prefiltering and completion.
73 """
73 """
74 # This is a hack to avoid the IPython exception hook to trigger
74 # This is a hack to avoid the IPython exception hook to trigger
75 # on exceptions (https://bugs.launchpad.net/bugs/337105)
75 # on exceptions (https://bugs.launchpad.net/bugs/337105)
76 # XXX: This is horrible: module-leve monkey patching -> side
76 # XXX: This is horrible: module-leve monkey patching -> side
77 # effects.
77 # effects.
78 from IPython import iplib
78 from IPython import iplib
79 iplib.InteractiveShell.isthreaded = True
79 iplib.InteractiveShell.isthreaded = True
80
80
81 LineFrontEndBase.__init__(self, *args, **kwargs)
81 LineFrontEndBase.__init__(self, *args, **kwargs)
82 self.shell.output_trap = RedirectorOutputTrap(
82 self.shell.output_trap = RedirectorOutputTrap(
83 out_callback=self.write,
83 out_callback=self.write,
84 err_callback=self.write,
84 err_callback=self.write,
85 )
85 )
86 self.shell.traceback_trap = SyncTracebackTrap(
86 self.shell.traceback_trap = SyncTracebackTrap(
87 formatters=self.shell.traceback_trap.formatters,
87 formatters=self.shell.traceback_trap.formatters,
88 )
88 )
89
89
90 # Start the ipython0 instance:
90 # Start the ipython0 instance:
91 self.save_output_hooks()
91 self.save_output_hooks()
92 if ipython0 is None:
92 if ipython0 is None:
93 # Instanciate an IPython0 interpreter to be able to use the
93 # Instanciate an IPython0 interpreter to be able to use the
94 # prefiltering.
94 # prefiltering.
95 # Suppress all key input, to avoid waiting
95 # Suppress all key input, to avoid waiting
96 def my_rawinput(x=None):
96 def my_rawinput(x=None):
97 return '\n'
97 return '\n'
98 old_rawinput = __builtin__.raw_input
98 old_rawinput = __builtin__.raw_input
99 __builtin__.raw_input = my_rawinput
99 __builtin__.raw_input = my_rawinput
100 # XXX: argv=[] is a bit bold.
100 # XXX: argv=[] is a bit bold.
101 ipython0 = make_IPython(argv=[],
101 ipython0 = make_IPython(argv=[],
102 user_ns=self.shell.user_ns,
102 user_ns=self.shell.user_ns,
103 user_global_ns=self.shell.user_global_ns)
103 user_global_ns=self.shell.user_global_ns)
104 __builtin__.raw_input = old_rawinput
104 __builtin__.raw_input = old_rawinput
105 self.ipython0 = ipython0
105 self.ipython0 = ipython0
106 # Set the pager:
106 # Set the pager:
107 self.ipython0.set_hook('show_in_pager',
107 self.ipython0.set_hook('show_in_pager',
108 lambda s, string: self.write("\n" + string))
108 lambda s, string: self.write("\n" + string))
109 self.ipython0.write = self.write
109 self.ipython0.write = self.write
110 self._ip = _ip = IPApi(self.ipython0)
110 self._ip = _ip = IPApi(self.ipython0)
111 # Make sure the raw system call doesn't get called, as we don't
111 # Make sure the raw system call doesn't get called, as we don't
112 # have a stdin accessible.
112 # have a stdin accessible.
113 self._ip.system = self.system_call
113 self._ip.system = self.system_call
114 # XXX: Muck around with magics so that they work better
114 # XXX: Muck around with magics so that they work better
115 # in our environment
115 # in our environment
116 if not sys.platform.startswith('win'):
116 if not sys.platform.startswith('win'):
117 self.ipython0.magic_ls = mk_system_call(self.system_call,
117 self.ipython0.magic_ls = mk_system_call(self.system_call,
118 'ls -CF')
118 'ls -CF')
119 # And now clean up the mess created by ipython0
119 # And now clean up the mess created by ipython0
120 self.release_output()
120 self.release_output()
121
121
122
122
123 if not 'banner' in kwargs and self.banner is None:
123 if not 'banner' in kwargs and self.banner is None:
124 self.banner = self.ipython0.BANNER
124 self.banner = self.ipython0.BANNER
125
125
126 # FIXME: __init__ and start should be two different steps
126 # FIXME: __init__ and start should be two different steps
127 self.start()
127 self.start()
128
128
129 #--------------------------------------------------------------------------
129 #--------------------------------------------------------------------------
130 # FrontEndBase interface
130 # FrontEndBase interface
131 #--------------------------------------------------------------------------
131 #--------------------------------------------------------------------------
132
132
133 def show_traceback(self):
133 def show_traceback(self):
134 """ Use ipython0 to capture the last traceback and display it.
134 """ Use ipython0 to capture the last traceback and display it.
135 """
135 """
136 # Don't do the capture; the except_hook has already done some
136 # Don't do the capture; the except_hook has already done some
137 # modifications to the IO streams, if we store them, we'll be
137 # modifications to the IO streams, if we store them, we'll be
138 # storing the wrong ones.
138 # storing the wrong ones.
139 #self.capture_output()
139 #self.capture_output()
140 self.ipython0.showtraceback(tb_offset=-1)
140 self.ipython0.showtraceback(tb_offset=-1)
141 self.release_output()
141 self.release_output()
142
142
143
143
144 def execute(self, python_string, raw_string=None):
144 def execute(self, python_string, raw_string=None):
145 if self.debug:
145 if self.debug:
146 print 'Executing Python code:', repr(python_string)
146 print 'Executing Python code:', repr(python_string)
147 self.capture_output()
147 self.capture_output()
148 LineFrontEndBase.execute(self, python_string,
148 LineFrontEndBase.execute(self, python_string,
149 raw_string=raw_string)
149 raw_string=raw_string)
150 self.release_output()
150 self.release_output()
151
151
152
152
153 def save_output_hooks(self):
153 def save_output_hooks(self):
154 """ Store all the output hooks we can think of, to be able to
154 """ Store all the output hooks we can think of, to be able to
155 restore them.
155 restore them.
156
156
157 We need to do this early, as starting the ipython0 instance will
157 We need to do this early, as starting the ipython0 instance will
158 screw ouput hooks.
158 screw ouput hooks.
159 """
159 """
160 self.__old_cout_write = Term.cout.write
160 self.__old_cout_write = Term.cout.write
161 self.__old_cerr_write = Term.cerr.write
161 self.__old_cerr_write = Term.cerr.write
162 self.__old_stdout = sys.stdout
162 self.__old_stdout = sys.stdout
163 self.__old_stderr= sys.stderr
163 self.__old_stderr= sys.stderr
164 self.__old_help_output = pydoc.help.output
164 self.__old_help_output = pydoc.help.output
165 self.__old_display_hook = sys.displayhook
165 self.__old_display_hook = sys.displayhook
166
166
167
167
168 def capture_output(self):
168 def capture_output(self):
169 """ Capture all the output mechanisms we can think of.
169 """ Capture all the output mechanisms we can think of.
170 """
170 """
171 self.save_output_hooks()
171 self.save_output_hooks()
172 Term.cout.write = self.write
172 Term.cout.write = self.write
173 Term.cerr.write = self.write
173 Term.cerr.write = self.write
174 sys.stdout = Term.cout
174 sys.stdout = Term.cout
175 sys.stderr = Term.cerr
175 sys.stderr = Term.cerr
176 pydoc.help.output = self.shell.output_trap.out
176 pydoc.help.output = self.shell.output_trap.out
177
177
178
178
179 def release_output(self):
179 def release_output(self):
180 """ Release all the different captures we have made.
180 """ Release all the different captures we have made.
181 """
181 """
182 Term.cout.write = self.__old_cout_write
182 Term.cout.write = self.__old_cout_write
183 Term.cerr.write = self.__old_cerr_write
183 Term.cerr.write = self.__old_cerr_write
184 sys.stdout = self.__old_stdout
184 sys.stdout = self.__old_stdout
185 sys.stderr = self.__old_stderr
185 sys.stderr = self.__old_stderr
186 pydoc.help.output = self.__old_help_output
186 pydoc.help.output = self.__old_help_output
187 sys.displayhook = self.__old_display_hook
187 sys.displayhook = self.__old_display_hook
188
188
189
189
190 def complete(self, line):
190 def complete(self, line):
191 # FIXME: This should be factored out in the linefrontendbase
191 # FIXME: This should be factored out in the linefrontendbase
192 # method.
192 # method.
193 word = self._get_completion_text(line)
193 word = self._get_completion_text(line)
194 print 'Completion', word
195 completions = self.ipython0.complete(word)
194 completions = self.ipython0.complete(word)
196 # FIXME: The proper sort should be done in the complete method.
195 # FIXME: The proper sort should be done in the complete method.
197 key = lambda x: x.replace('_', '')
196 key = lambda x: x.replace('_', '')
198 completions.sort(key=key)
197 completions.sort(key=key)
199 if completions:
198 if completions:
200 prefix = common_prefix(completions)
199 prefix = common_prefix(completions)
201 line = line[:-len(word)] + prefix
200 line = line[:-len(word)] + prefix
202 return line, completions
201 return line, completions
203
202
204
203
205 #--------------------------------------------------------------------------
204 #--------------------------------------------------------------------------
206 # LineFrontEndBase interface
205 # LineFrontEndBase interface
207 #--------------------------------------------------------------------------
206 #--------------------------------------------------------------------------
208
207
209 def prefilter_input(self, input_string):
208 def prefilter_input(self, input_string):
210 """ Using IPython0 to prefilter the commands to turn them
209 """ Using IPython0 to prefilter the commands to turn them
211 in executable statements that are valid Python strings.
210 in executable statements that are valid Python strings.
212 """
211 """
213 input_string = LineFrontEndBase.prefilter_input(self, input_string)
212 input_string = LineFrontEndBase.prefilter_input(self, input_string)
214 filtered_lines = []
213 filtered_lines = []
215 # The IPython0 prefilters sometime produce output. We need to
214 # The IPython0 prefilters sometime produce output. We need to
216 # capture it.
215 # capture it.
217 self.capture_output()
216 self.capture_output()
218 self.last_result = dict(number=self.prompt_number)
217 self.last_result = dict(number=self.prompt_number)
219
218
220 ## try:
219 ## try:
221 ## for line in input_string.split('\n'):
220 ## for line in input_string.split('\n'):
222 ## filtered_lines.append(
221 ## filtered_lines.append(
223 ## self.ipython0.prefilter(line, False).rstrip())
222 ## self.ipython0.prefilter(line, False).rstrip())
224 ## except:
223 ## except:
225 ## # XXX: probably not the right thing to do.
224 ## # XXX: probably not the right thing to do.
226 ## self.ipython0.showsyntaxerror()
225 ## self.ipython0.showsyntaxerror()
227 ## self.after_execute()
226 ## self.after_execute()
228 ## finally:
227 ## finally:
229 ## self.release_output()
228 ## self.release_output()
230
229
231
230
232 try:
231 try:
233 try:
232 try:
234 for line in input_string.split('\n'):
233 for line in input_string.split('\n'):
235 filtered_lines.append(
234 filtered_lines.append(
236 self.ipython0.prefilter(line, False).rstrip())
235 self.ipython0.prefilter(line, False).rstrip())
237 except:
236 except:
238 # XXX: probably not the right thing to do.
237 # XXX: probably not the right thing to do.
239 self.ipython0.showsyntaxerror()
238 self.ipython0.showsyntaxerror()
240 self.after_execute()
239 self.after_execute()
241 finally:
240 finally:
242 self.release_output()
241 self.release_output()
243
242
244
243
245
244
246 # Clean up the trailing whitespace, to avoid indentation errors
245 # Clean up the trailing whitespace, to avoid indentation errors
247 filtered_string = '\n'.join(filtered_lines)
246 filtered_string = '\n'.join(filtered_lines)
248 return filtered_string
247 return filtered_string
249
248
250
249
251 #--------------------------------------------------------------------------
250 #--------------------------------------------------------------------------
252 # PrefilterFrontEnd interface
251 # PrefilterFrontEnd interface
253 #--------------------------------------------------------------------------
252 #--------------------------------------------------------------------------
254
253
255 def system_call(self, command_string):
254 def system_call(self, command_string):
256 """ Allows for frontend to define their own system call, to be
255 """ Allows for frontend to define their own system call, to be
257 able capture output and redirect input.
256 able capture output and redirect input.
258 """
257 """
259 return os.system(command_string)
258 return os.system(command_string)
260
259
261
260
262 def do_exit(self):
261 def do_exit(self):
263 """ Exit the shell, cleanup and save the history.
262 """ Exit the shell, cleanup and save the history.
264 """
263 """
265 self.ipython0.atexit_operations()
264 self.ipython0.atexit_operations()
266
265
267
266
268 def _get_completion_text(self, line):
267 def _get_completion_text(self, line):
269 """ Returns the text to be completed by breaking the line at specified
268 """ Returns the text to be completed by breaking the line at specified
270 delimiters.
269 delimiters.
271 """
270 """
272 # Break at: spaces, '=', all parentheses (except if balanced).
271 # Break at: spaces, '=', all parentheses (except if balanced).
273 # FIXME2: In the future, we need to make the implementation similar to
272 # FIXME2: In the future, we need to make the implementation similar to
274 # that in the 'pyreadline' module (modes/basemode.py) where we break at
273 # that in the 'pyreadline' module (modes/basemode.py) where we break at
275 # each delimiter and try to complete the residual line, until we get a
274 # each delimiter and try to complete the residual line, until we get a
276 # successful list of completions.
275 # successful list of completions.
277 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
276 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
278 complete_sep = re.compile(expression)
277 complete_sep = re.compile(expression)
279 text = complete_sep.split(line)[-1]
278 text = complete_sep.split(line)[-1]
280 return text
279 return text
281
280
General Comments 0
You need to be logged in to leave comments. Login now