##// END OF EJS Templates
Remove unused imports that where Python2.4-incompatible.
Gael Varoquaux -
Show More
@@ -1,362 +1,360 b''
1 1 # encoding: utf-8
2 2 # -*- test-case-name: IPython.frontend.tests.test_frontendbase -*-
3 3 """
4 4 frontendbase provides an interface and base class for GUI frontends for
5 5 IPython.kernel/IPython.kernel.core.
6 6
7 7 Frontend implementations will likely want to subclass FrontEndBase.
8 8
9 9 Author: Barry Wark
10 10 """
11 11 __docformat__ = "restructuredtext en"
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import string
24 24 import uuid
25 25 import _ast
26 26
27 27 from IPython.frontend.zopeinterface import (
28 28 Interface,
29 29 Attribute,
30 implements,
31 classProvides
32 30 )
33 31 from IPython.kernel.core.history import FrontEndHistory
34 32 from IPython.kernel.core.util import Bunch
35 33
36 34 ##############################################################################
37 35 # TEMPORARY!!! fake configuration, while we decide whether to use tconfig or
38 36 # not
39 37
40 38 rc = Bunch()
41 39 rc.prompt_in1 = r'In [$number]: '
42 40 rc.prompt_in2 = r'...'
43 41 rc.prompt_out = r'Out [$number]: '
44 42
45 43 ##############################################################################
46 44 # Interface definitions
47 45 ##############################################################################
48 46
49 47 class IFrontEndFactory(Interface):
50 48 """Factory interface for frontends."""
51 49
52 50 def __call__(engine=None, history=None):
53 51 """
54 52 Parameters:
55 53 interpreter : IPython.kernel.engineservice.IEngineCore
56 54 """
57 55
58 56 pass
59 57
60 58
61 59 class IFrontEnd(Interface):
62 60 """Interface for frontends. All methods return t.i.d.Deferred"""
63 61
64 62 Attribute("input_prompt_template", "string.Template instance\
65 63 substituteable with execute result.")
66 64 Attribute("output_prompt_template", "string.Template instance\
67 65 substituteable with execute result.")
68 66 Attribute("continuation_prompt_template", "string.Template instance\
69 67 substituteable with execute result.")
70 68
71 69 def update_cell_prompt(result, blockID=None):
72 70 """Subclass may override to update the input prompt for a block.
73 71
74 72 In asynchronous frontends, this method will be called as a
75 73 twisted.internet.defer.Deferred's callback/errback.
76 74 Implementations should thus return result when finished.
77 75
78 76 Result is a result dict in case of success, and a
79 77 twisted.python.util.failure.Failure in case of an error
80 78 """
81 79
82 80 pass
83 81
84 82 def render_result(result):
85 83 """Render the result of an execute call. Implementors may choose the
86 84 method of rendering.
87 85 For example, a notebook-style frontend might render a Chaco plot
88 86 inline.
89 87
90 88 Parameters:
91 89 result : dict (result of IEngineBase.execute )
92 90 blockID = result['blockID']
93 91
94 92 Result:
95 93 Output of frontend rendering
96 94 """
97 95
98 96 pass
99 97
100 98 def render_error(failure):
101 99 """Subclasses must override to render the failure.
102 100
103 101 In asynchronous frontend, since this method will be called as a
104 102 twisted.internet.defer.Deferred's callback. Implementations
105 103 should thus return result when finished.
106 104
107 105 blockID = failure.blockID
108 106 """
109 107
110 108 pass
111 109
112 110 def input_prompt(number=''):
113 111 """Returns the input prompt by subsituting into
114 112 self.input_prompt_template
115 113 """
116 114 pass
117 115
118 116 def output_prompt(number=''):
119 117 """Returns the output prompt by subsituting into
120 118 self.output_prompt_template
121 119 """
122 120
123 121 pass
124 122
125 123 def continuation_prompt():
126 124 """Returns the continuation prompt by subsituting into
127 125 self.continuation_prompt_template
128 126 """
129 127
130 128 pass
131 129
132 130 def is_complete(block):
133 131 """Returns True if block is complete, False otherwise."""
134 132
135 133 pass
136 134
137 135 def compile_ast(block):
138 136 """Compiles block to an _ast.AST"""
139 137
140 138 pass
141 139
142 140 def get_history_previous(current_block):
143 141 """Returns the block previous in the history. Saves currentBlock if
144 142 the history_cursor is currently at the end of the input history"""
145 143 pass
146 144
147 145 def get_history_next():
148 146 """Returns the next block in the history."""
149 147
150 148 pass
151 149
152 150 def complete(self, line):
153 151 """Returns the list of possible completions, and the completed
154 152 line.
155 153
156 154 The input argument is the full line to be completed. This method
157 155 returns both the line completed as much as possible, and the list
158 156 of further possible completions (full words).
159 157 """
160 158 pass
161 159
162 160
163 161 ##############################################################################
164 162 # Base class for all the frontends.
165 163 ##############################################################################
166 164
167 165 class FrontEndBase(object):
168 166 """
169 167 FrontEndBase manages the state tasks for a CLI frontend:
170 168 - Input and output history management
171 169 - Input/continuation and output prompt generation
172 170
173 171 Some issues (due to possibly unavailable engine):
174 172 - How do we get the current cell number for the engine?
175 173 - How do we handle completions?
176 174 """
177 175
178 176 history_cursor = 0
179 177
180 178 input_prompt_template = string.Template(rc.prompt_in1)
181 179 output_prompt_template = string.Template(rc.prompt_out)
182 180 continuation_prompt_template = string.Template(rc.prompt_in2)
183 181
184 182 def __init__(self, shell=None, history=None):
185 183 self.shell = shell
186 184 if history is None:
187 185 self.history = FrontEndHistory(input_cache=[''])
188 186 else:
189 187 self.history = history
190 188
191 189
192 190 def input_prompt(self, number=''):
193 191 """Returns the current input prompt
194 192
195 193 It would be great to use ipython1.core.prompts.Prompt1 here
196 194 """
197 195 return self.input_prompt_template.safe_substitute({'number':number})
198 196
199 197
200 198 def continuation_prompt(self):
201 199 """Returns the current continuation prompt"""
202 200
203 201 return self.continuation_prompt_template.safe_substitute()
204 202
205 203 def output_prompt(self, number=''):
206 204 """Returns the output prompt for result"""
207 205
208 206 return self.output_prompt_template.safe_substitute({'number':number})
209 207
210 208
211 209 def is_complete(self, block):
212 210 """Determine if block is complete.
213 211
214 212 Parameters
215 213 block : string
216 214
217 215 Result
218 216 True if block can be sent to the engine without compile errors.
219 217 False otherwise.
220 218 """
221 219
222 220 try:
223 221 ast = self.compile_ast(block)
224 222 except:
225 223 return False
226 224
227 225 lines = block.split('\n')
228 226 return (len(lines)==1 or str(lines[-1])=='')
229 227
230 228
231 229 def compile_ast(self, block):
232 230 """Compile block to an AST
233 231
234 232 Parameters:
235 233 block : str
236 234
237 235 Result:
238 236 AST
239 237
240 238 Throws:
241 239 Exception if block cannot be compiled
242 240 """
243 241
244 242 return compile(block, "<string>", "exec", _ast.PyCF_ONLY_AST)
245 243
246 244
247 245 def execute(self, block, blockID=None):
248 246 """Execute the block and return the result.
249 247
250 248 Parameters:
251 249 block : {str, AST}
252 250 blockID : any
253 251 Caller may provide an ID to identify this block.
254 252 result['blockID'] := blockID
255 253
256 254 Result:
257 255 Deferred result of self.interpreter.execute
258 256 """
259 257
260 258 if(not self.is_complete(block)):
261 259 raise Exception("Block is not compilable")
262 260
263 261 if(blockID == None):
264 262 blockID = uuid.uuid4() #random UUID
265 263
266 264 try:
267 265 result = self.shell.execute(block)
268 266 except Exception,e:
269 267 e = self._add_block_id_for_failure(e, blockID=blockID)
270 268 e = self.update_cell_prompt(e, blockID=blockID)
271 269 e = self.render_error(e)
272 270 else:
273 271 result = self._add_block_id_for_result(result, blockID=blockID)
274 272 result = self.update_cell_prompt(result, blockID=blockID)
275 273 result = self.render_result(result)
276 274
277 275 return result
278 276
279 277
280 278 def _add_block_id_for_result(self, result, blockID):
281 279 """Add the blockID to result or failure. Unfortunatley, we have to
282 280 treat failures differently than result dicts.
283 281 """
284 282
285 283 result['blockID'] = blockID
286 284
287 285 return result
288 286
289 287 def _add_block_id_for_failure(self, failure, blockID):
290 288 """_add_block_id_for_failure"""
291 289 failure.blockID = blockID
292 290 return failure
293 291
294 292
295 293 def _add_history(self, result, block=None):
296 294 """Add block to the history"""
297 295
298 296 assert(block != None)
299 297 self.history.add_items([block])
300 298 self.history_cursor += 1
301 299
302 300 return result
303 301
304 302
305 303 def get_history_previous(self, current_block):
306 304 """ Returns previous history string and decrement history cursor.
307 305 """
308 306 command = self.history.get_history_item(self.history_cursor - 1)
309 307
310 308 if command is not None:
311 309 if(self.history_cursor+1 == len(self.history.input_cache)):
312 310 self.history.input_cache[self.history_cursor] = current_block
313 311 self.history_cursor -= 1
314 312 return command
315 313
316 314
317 315 def get_history_next(self):
318 316 """ Returns next history string and increment history cursor.
319 317 """
320 318 command = self.history.get_history_item(self.history_cursor+1)
321 319
322 320 if command is not None:
323 321 self.history_cursor += 1
324 322 return command
325 323
326 324 ###
327 325 # Subclasses probably want to override these methods...
328 326 ###
329 327
330 328 def update_cell_prompt(self, result, blockID=None):
331 329 """Subclass may override to update the input prompt for a block.
332 330
333 331 This method only really makes sens in asyncrhonous frontend.
334 332 Since this method will be called as a
335 333 twisted.internet.defer.Deferred's callback, implementations should
336 334 return result when finished.
337 335 """
338 336
339 337 raise NotImplementedError
340 338
341 339
342 340 def render_result(self, result):
343 341 """Subclasses must override to render result.
344 342
345 343 In asynchronous frontends, this method will be called as a
346 344 twisted.internet.defer.Deferred's callback. Implementations
347 345 should thus return result when finished.
348 346 """
349 347
350 348 raise NotImplementedError
351 349
352 350
353 351 def render_error(self, failure):
354 352 """Subclasses must override to render the failure.
355 353
356 354 In asynchronous frontends, this method will be called as a
357 355 twisted.internet.defer.Deferred's callback. Implementations
358 356 should thus return result when finished.
359 357 """
360 358
361 359 raise NotImplementedError
362 360
@@ -1,34 +1,27 b''
1 1 # encoding: utf-8
2 2 # -*- test-case-name: IPython.frontend.tests.test_frontendbase -*-
3 3 """
4 4 zope.interface mock. If zope is installed, this module provides a zope
5 5 interface classes, if not it provides mocks for them.
6 6
7 7 Classes provided:
8 8 Interface, Attribute, implements, classProvides
9 9 """
10 10 __docformat__ = "restructuredtext en"
11 11
12 12 #-------------------------------------------------------------------------------
13 13 # Copyright (C) 2008 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-------------------------------------------------------------------------------
18 18
19 #-------------------------------------------------------------------------------
20 # Imports
21 #-------------------------------------------------------------------------------
22 import string
23 import uuid
24 import _ast
25
26 19 try:
27 20 from zope.interface import Interface, Attribute, implements, classProvides
28 21 except ImportError:
29 22 #zope.interface is not available
30 23 Interface = object
31 24 def Attribute(name, doc): pass
32 25 def implements(interface): pass
33 26 def classProvides(interface): pass
34 27
General Comments 0
You need to be logged in to leave comments. Login now