##// END OF EJS Templates
Add a docstring to magics to fix the broken "%magic" magic.
gvaroquaux -
Show More
@@ -1,230 +1,232 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
49 my_system_call.__doc__ = "Calls %s" % command
48 return my_system_call
50 return my_system_call
49
51
50 #-------------------------------------------------------------------------------
52 #-------------------------------------------------------------------------------
51 # Frontend class using ipython0 to do the prefiltering.
53 # Frontend class using ipython0 to do the prefiltering.
52 #-------------------------------------------------------------------------------
54 #-------------------------------------------------------------------------------
53 class PrefilterFrontEnd(LineFrontEndBase):
55 class PrefilterFrontEnd(LineFrontEndBase):
54 """ Class that uses ipython0 to do prefilter the input, do the
56 """ Class that uses ipython0 to do prefilter the input, do the
55 completion and the magics.
57 completion and the magics.
56
58
57 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
58 input, and share the namespace between the interpreter instance used
60 input, and share the namespace between the interpreter instance used
59 to execute the statements and the ipython0 used for code
61 to execute the statements and the ipython0 used for code
60 completion...
62 completion...
61 """
63 """
62
64
63 debug = False
65 debug = False
64
66
65 def __init__(self, ipython0=None, *args, **kwargs):
67 def __init__(self, ipython0=None, *args, **kwargs):
66 """ Parameters:
68 """ Parameters:
67 -----------
69 -----------
68
70
69 ipython0: an optional ipython0 instance to use for command
71 ipython0: an optional ipython0 instance to use for command
70 prefiltering and completion.
72 prefiltering and completion.
71 """
73 """
72 LineFrontEndBase.__init__(self, *args, **kwargs)
74 LineFrontEndBase.__init__(self, *args, **kwargs)
73 self.shell.output_trap = RedirectorOutputTrap(
75 self.shell.output_trap = RedirectorOutputTrap(
74 out_callback=self.write,
76 out_callback=self.write,
75 err_callback=self.write,
77 err_callback=self.write,
76 )
78 )
77 self.shell.traceback_trap = SyncTracebackTrap(
79 self.shell.traceback_trap = SyncTracebackTrap(
78 formatters=self.shell.traceback_trap.formatters,
80 formatters=self.shell.traceback_trap.formatters,
79 )
81 )
80
82
81 # Start the ipython0 instance:
83 # Start the ipython0 instance:
82 self.save_output_hooks()
84 self.save_output_hooks()
83 if ipython0 is None:
85 if ipython0 is None:
84 # Instanciate an IPython0 interpreter to be able to use the
86 # Instanciate an IPython0 interpreter to be able to use the
85 # prefiltering.
87 # prefiltering.
86 # XXX: argv=[] is a bit bold.
88 # XXX: argv=[] is a bit bold.
87 ipython0 = make_IPython(argv=[],
89 ipython0 = make_IPython(argv=[],
88 user_ns=self.shell.user_ns,
90 user_ns=self.shell.user_ns,
89 user_global_ns=self.shell.user_global_ns)
91 user_global_ns=self.shell.user_global_ns)
90 self.ipython0 = ipython0
92 self.ipython0 = ipython0
91 # Set the pager:
93 # Set the pager:
92 self.ipython0.set_hook('show_in_pager',
94 self.ipython0.set_hook('show_in_pager',
93 lambda s, string: self.write("\n" + string))
95 lambda s, string: self.write("\n" + string))
94 self.ipython0.write = self.write
96 self.ipython0.write = self.write
95 self._ip = _ip = IPApi(self.ipython0)
97 self._ip = _ip = IPApi(self.ipython0)
96 # Make sure the raw system call doesn't get called, as we don't
98 # Make sure the raw system call doesn't get called, as we don't
97 # have a stdin accessible.
99 # have a stdin accessible.
98 self._ip.system = self.system_call
100 self._ip.system = self.system_call
99 # XXX: Muck around with magics so that they work better
101 # XXX: Muck around with magics so that they work better
100 # in our environment
102 # in our environment
101 self.ipython0.magic_ls = mk_system_call(self.system_call,
103 self.ipython0.magic_ls = mk_system_call(self.system_call,
102 'ls -CF')
104 'ls -CF')
103 # And now clean up the mess created by ipython0
105 # And now clean up the mess created by ipython0
104 self.release_output()
106 self.release_output()
105
107
106
108
107 if not 'banner' in kwargs and self.banner is None:
109 if not 'banner' in kwargs and self.banner is None:
108 self.banner = self.ipython0.BANNER + """
110 self.banner = self.ipython0.BANNER + """
109 This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
111 This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
110
112
111 self.start()
113 self.start()
112
114
113 #--------------------------------------------------------------------------
115 #--------------------------------------------------------------------------
114 # FrontEndBase interface
116 # FrontEndBase interface
115 #--------------------------------------------------------------------------
117 #--------------------------------------------------------------------------
116
118
117 def show_traceback(self):
119 def show_traceback(self):
118 """ Use ipython0 to capture the last traceback and display it.
120 """ Use ipython0 to capture the last traceback and display it.
119 """
121 """
120 self.capture_output()
122 self.capture_output()
121 self.ipython0.showtraceback(tb_offset=-1)
123 self.ipython0.showtraceback(tb_offset=-1)
122 self.release_output()
124 self.release_output()
123
125
124
126
125 def execute(self, python_string, raw_string=None):
127 def execute(self, python_string, raw_string=None):
126 if self.debug:
128 if self.debug:
127 print 'Executing Python code:', repr(python_string)
129 print 'Executing Python code:', repr(python_string)
128 self.capture_output()
130 self.capture_output()
129 LineFrontEndBase.execute(self, python_string,
131 LineFrontEndBase.execute(self, python_string,
130 raw_string=raw_string)
132 raw_string=raw_string)
131 self.release_output()
133 self.release_output()
132
134
133
135
134 def save_output_hooks(self):
136 def save_output_hooks(self):
135 """ Store all the output hooks we can think of, to be able to
137 """ Store all the output hooks we can think of, to be able to
136 restore them.
138 restore them.
137
139
138 We need to do this early, as starting the ipython0 instance will
140 We need to do this early, as starting the ipython0 instance will
139 screw ouput hooks.
141 screw ouput hooks.
140 """
142 """
141 self.__old_cout_write = Term.cout.write
143 self.__old_cout_write = Term.cout.write
142 self.__old_cerr_write = Term.cerr.write
144 self.__old_cerr_write = Term.cerr.write
143 self.__old_stdout = sys.stdout
145 self.__old_stdout = sys.stdout
144 self.__old_stderr= sys.stderr
146 self.__old_stderr= sys.stderr
145 self.__old_help_output = pydoc.help.output
147 self.__old_help_output = pydoc.help.output
146 self.__old_display_hook = sys.displayhook
148 self.__old_display_hook = sys.displayhook
147
149
148
150
149 def capture_output(self):
151 def capture_output(self):
150 """ Capture all the output mechanisms we can think of.
152 """ Capture all the output mechanisms we can think of.
151 """
153 """
152 self.save_output_hooks()
154 self.save_output_hooks()
153 Term.cout.write = self.write
155 Term.cout.write = self.write
154 Term.cerr.write = self.write
156 Term.cerr.write = self.write
155 sys.stdout = Term.cout
157 sys.stdout = Term.cout
156 sys.stderr = Term.cerr
158 sys.stderr = Term.cerr
157 pydoc.help.output = self.shell.output_trap.out
159 pydoc.help.output = self.shell.output_trap.out
158
160
159
161
160 def release_output(self):
162 def release_output(self):
161 """ Release all the different captures we have made.
163 """ Release all the different captures we have made.
162 """
164 """
163 Term.cout.write = self.__old_cout_write
165 Term.cout.write = self.__old_cout_write
164 Term.cerr.write = self.__old_cerr_write
166 Term.cerr.write = self.__old_cerr_write
165 sys.stdout = self.__old_stdout
167 sys.stdout = self.__old_stdout
166 sys.stderr = self.__old_stderr
168 sys.stderr = self.__old_stderr
167 pydoc.help.output = self.__old_help_output
169 pydoc.help.output = self.__old_help_output
168 sys.displayhook = self.__old_display_hook
170 sys.displayhook = self.__old_display_hook
169
171
170
172
171 def complete(self, line):
173 def complete(self, line):
172 # FIXME: This should be factored out in the linefrontendbase
174 # FIXME: This should be factored out in the linefrontendbase
173 # method.
175 # method.
174 word = line.split('\n')[-1].split(' ')[-1]
176 word = line.split('\n')[-1].split(' ')[-1]
175 completions = self.ipython0.complete(word)
177 completions = self.ipython0.complete(word)
176 # FIXME: The proper sort should be done in the complete method.
178 # FIXME: The proper sort should be done in the complete method.
177 key = lambda x: x.replace('_', '')
179 key = lambda x: x.replace('_', '')
178 completions.sort(key=key)
180 completions.sort(key=key)
179 if completions:
181 if completions:
180 prefix = common_prefix(completions)
182 prefix = common_prefix(completions)
181 line = line[:-len(word)] + prefix
183 line = line[:-len(word)] + prefix
182 return line, completions
184 return line, completions
183
185
184
186
185 #--------------------------------------------------------------------------
187 #--------------------------------------------------------------------------
186 # LineFrontEndBase interface
188 # LineFrontEndBase interface
187 #--------------------------------------------------------------------------
189 #--------------------------------------------------------------------------
188
190
189 def prefilter_input(self, input_string):
191 def prefilter_input(self, input_string):
190 """ Using IPython0 to prefilter the commands to turn them
192 """ Using IPython0 to prefilter the commands to turn them
191 in executable statements that are valid Python strings.
193 in executable statements that are valid Python strings.
192 """
194 """
193 input_string = LineFrontEndBase.prefilter_input(self, input_string)
195 input_string = LineFrontEndBase.prefilter_input(self, input_string)
194 filtered_lines = []
196 filtered_lines = []
195 # The IPython0 prefilters sometime produce output. We need to
197 # The IPython0 prefilters sometime produce output. We need to
196 # capture it.
198 # capture it.
197 self.capture_output()
199 self.capture_output()
198 self.last_result = dict(number=self.prompt_number)
200 self.last_result = dict(number=self.prompt_number)
199 try:
201 try:
200 for line in input_string.split('\n'):
202 for line in input_string.split('\n'):
201 filtered_lines.append(
203 filtered_lines.append(
202 self.ipython0.prefilter(line, False).rstrip())
204 self.ipython0.prefilter(line, False).rstrip())
203 except:
205 except:
204 # XXX: probably not the right thing to do.
206 # XXX: probably not the right thing to do.
205 self.ipython0.showsyntaxerror()
207 self.ipython0.showsyntaxerror()
206 self.after_execute()
208 self.after_execute()
207 finally:
209 finally:
208 self.release_output()
210 self.release_output()
209
211
210 # Clean up the trailing whitespace, to avoid indentation errors
212 # Clean up the trailing whitespace, to avoid indentation errors
211 filtered_string = '\n'.join(filtered_lines)
213 filtered_string = '\n'.join(filtered_lines)
212 return filtered_string
214 return filtered_string
213
215
214
216
215 #--------------------------------------------------------------------------
217 #--------------------------------------------------------------------------
216 # PrefilterFrontEnd interface
218 # PrefilterFrontEnd interface
217 #--------------------------------------------------------------------------
219 #--------------------------------------------------------------------------
218
220
219 def system_call(self, command_string):
221 def system_call(self, command_string):
220 """ Allows for frontend to define their own system call, to be
222 """ Allows for frontend to define their own system call, to be
221 able capture output and redirect input.
223 able capture output and redirect input.
222 """
224 """
223 return os.system(command_string)
225 return os.system(command_string)
224
226
225
227
226 def do_exit(self):
228 def do_exit(self):
227 """ Exit the shell, cleanup and save the history.
229 """ Exit the shell, cleanup and save the history.
228 """
230 """
229 self.ipython0.atexit_operations()
231 self.ipython0.atexit_operations()
230
232
General Comments 0
You need to be logged in to leave comments. Login now