##// END OF EJS Templates
Transformers have been added to the prefilter....
Brian Granger -
Show More
@@ -1,836 +1,995 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 Prefiltering components.
4 Prefiltering components.
5
5
6 Prefilters transform user input before it is exec'd by Python. These
7 transforms are used to implement additional syntax such as !ls and %magic.
8
6 Authors:
9 Authors:
7
10
8 * Brian Granger
11 * Brian Granger
9 * Fernando Perez
12 * Fernando Perez
10 * Dan Milstein
13 * Dan Milstein
14 * Ville Vainio
11 """
15 """
12
16
13 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2009 The IPython Development Team
18 # Copyright (C) 2008-2009 The IPython Development Team
15 #
19 #
16 # Distributed under the terms of the BSD License. The full license is in
20 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
21 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
19
23
20 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
21 # Imports
25 # Imports
22 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
23
27
24 import __builtin__
28 import __builtin__
25 import codeop
29 import codeop
26 import keyword
30 import keyword
27 import os
31 import os
28 import re
32 import re
29 import sys
33 import sys
30
34
31 from IPython.core.alias import AliasManager
35 from IPython.core.alias import AliasManager
32 from IPython.core.autocall import IPyAutocall
36 from IPython.core.autocall import IPyAutocall
33 from IPython.core.component import Component
37 from IPython.core.component import Component
34 from IPython.core.splitinput import split_user_input
38 from IPython.core.splitinput import split_user_input
35 from IPython.core.page import page
39 from IPython.core.page import page
36
40
37 from IPython.utils.traitlets import List, Int, Any, Str, CBool
41 from IPython.utils.traitlets import List, Int, Any, Str, CBool, Bool
38 from IPython.utils.genutils import make_quoted_expr
42 from IPython.utils.genutils import make_quoted_expr
39 from IPython.utils.autoattr import auto_attr
43 from IPython.utils.autoattr import auto_attr
40
44
41 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
42 # Global utilities, errors and constants
46 # Global utilities, errors and constants
43 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
44
48
45 # Warning, these cannot be changed unless various regular expressions
49 # Warning, these cannot be changed unless various regular expressions
46 # are updated in a number of places. Not great, but at least we told you.
50 # are updated in a number of places. Not great, but at least we told you.
47 ESC_SHELL = '!'
51 ESC_SHELL = '!'
48 ESC_SH_CAP = '!!'
52 ESC_SH_CAP = '!!'
49 ESC_HELP = '?'
53 ESC_HELP = '?'
50 ESC_MAGIC = '%'
54 ESC_MAGIC = '%'
51 ESC_QUOTE = ','
55 ESC_QUOTE = ','
52 ESC_QUOTE2 = ';'
56 ESC_QUOTE2 = ';'
53 ESC_PAREN = '/'
57 ESC_PAREN = '/'
54
58
55
59
56 class PrefilterError(Exception):
60 class PrefilterError(Exception):
57 pass
61 pass
58
62
59
63
60 # RegExp to identify potential function names
64 # RegExp to identify potential function names
61 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
65 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
62
66
63 # RegExp to exclude strings with this start from autocalling. In
67 # RegExp to exclude strings with this start from autocalling. In
64 # particular, all binary operators should be excluded, so that if foo is
68 # particular, all binary operators should be excluded, so that if foo is
65 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
69 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
66 # characters '!=()' don't need to be checked for, as the checkPythonChars
70 # characters '!=()' don't need to be checked for, as the checkPythonChars
67 # routine explicitely does so, to catch direct calls and rebindings of
71 # routine explicitely does so, to catch direct calls and rebindings of
68 # existing names.
72 # existing names.
69
73
70 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
74 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
71 # it affects the rest of the group in square brackets.
75 # it affects the rest of the group in square brackets.
72 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
76 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
73 r'|^is |^not |^in |^and |^or ')
77 r'|^is |^not |^in |^and |^or ')
74
78
75 # try to catch also methods for stuff in lists/tuples/dicts: off
79 # try to catch also methods for stuff in lists/tuples/dicts: off
76 # (experimental). For this to work, the line_split regexp would need
80 # (experimental). For this to work, the line_split regexp would need
77 # to be modified so it wouldn't break things at '['. That line is
81 # to be modified so it wouldn't break things at '['. That line is
78 # nasty enough that I shouldn't change it until I can test it _well_.
82 # nasty enough that I shouldn't change it until I can test it _well_.
79 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
83 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
80
84
81
85
82 # Handler Check Utilities
86 # Handler Check Utilities
83 def is_shadowed(identifier, ip):
87 def is_shadowed(identifier, ip):
84 """Is the given identifier defined in one of the namespaces which shadow
88 """Is the given identifier defined in one of the namespaces which shadow
85 the alias and magic namespaces? Note that an identifier is different
89 the alias and magic namespaces? Note that an identifier is different
86 than ifun, because it can not contain a '.' character."""
90 than ifun, because it can not contain a '.' character."""
87 # This is much safer than calling ofind, which can change state
91 # This is much safer than calling ofind, which can change state
88 return (identifier in ip.user_ns \
92 return (identifier in ip.user_ns \
89 or identifier in ip.internal_ns \
93 or identifier in ip.internal_ns \
90 or identifier in ip.ns_table['builtin'])
94 or identifier in ip.ns_table['builtin'])
91
95
92
96
93 #-----------------------------------------------------------------------------
97 #-----------------------------------------------------------------------------
94 # The LineInfo class used throughout
98 # The LineInfo class used throughout
95 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
96
100
97
101
98 class LineInfo(object):
102 class LineInfo(object):
99 """A single line of input and associated info.
103 """A single line of input and associated info.
100
104
101 Includes the following as properties:
105 Includes the following as properties:
102
106
103 line
107 line
104 The original, raw line
108 The original, raw line
105
109
106 continue_prompt
110 continue_prompt
107 Is this line a continuation in a sequence of multiline input?
111 Is this line a continuation in a sequence of multiline input?
108
112
109 pre
113 pre
110 The initial esc character or whitespace.
114 The initial esc character or whitespace.
111
115
112 pre_char
116 pre_char
113 The escape character(s) in pre or the empty string if there isn't one.
117 The escape character(s) in pre or the empty string if there isn't one.
114 Note that '!!' is a possible value for pre_char. Otherwise it will
118 Note that '!!' is a possible value for pre_char. Otherwise it will
115 always be a single character.
119 always be a single character.
116
120
117 pre_whitespace
121 pre_whitespace
118 The leading whitespace from pre if it exists. If there is a pre_char,
122 The leading whitespace from pre if it exists. If there is a pre_char,
119 this is just ''.
123 this is just ''.
120
124
121 ifun
125 ifun
122 The 'function part', which is basically the maximal initial sequence
126 The 'function part', which is basically the maximal initial sequence
123 of valid python identifiers and the '.' character. This is what is
127 of valid python identifiers and the '.' character. This is what is
124 checked for alias and magic transformations, used for auto-calling,
128 checked for alias and magic transformations, used for auto-calling,
125 etc.
129 etc.
126
130
127 the_rest
131 the_rest
128 Everything else on the line.
132 Everything else on the line.
129 """
133 """
130 def __init__(self, line, continue_prompt):
134 def __init__(self, line, continue_prompt):
131 self.line = line
135 self.line = line
132 self.continue_prompt = continue_prompt
136 self.continue_prompt = continue_prompt
133 self.pre, self.ifun, self.the_rest = split_user_input(line)
137 self.pre, self.ifun, self.the_rest = split_user_input(line)
134
138
135 self.pre_char = self.pre.strip()
139 self.pre_char = self.pre.strip()
136 if self.pre_char:
140 if self.pre_char:
137 self.pre_whitespace = '' # No whitespace allowd before esc chars
141 self.pre_whitespace = '' # No whitespace allowd before esc chars
138 else:
142 else:
139 self.pre_whitespace = self.pre
143 self.pre_whitespace = self.pre
140
144
141 self._oinfo = None
145 self._oinfo = None
142
146
143 def ofind(self, ip):
147 def ofind(self, ip):
144 """Do a full, attribute-walking lookup of the ifun in the various
148 """Do a full, attribute-walking lookup of the ifun in the various
145 namespaces for the given IPython InteractiveShell instance.
149 namespaces for the given IPython InteractiveShell instance.
146
150
147 Return a dict with keys: found,obj,ospace,ismagic
151 Return a dict with keys: found,obj,ospace,ismagic
148
152
149 Note: can cause state changes because of calling getattr, but should
153 Note: can cause state changes because of calling getattr, but should
150 only be run if autocall is on and if the line hasn't matched any
154 only be run if autocall is on and if the line hasn't matched any
151 other, less dangerous handlers.
155 other, less dangerous handlers.
152
156
153 Does cache the results of the call, so can be called multiple times
157 Does cache the results of the call, so can be called multiple times
154 without worrying about *further* damaging state.
158 without worrying about *further* damaging state.
155 """
159 """
156 if not self._oinfo:
160 if not self._oinfo:
157 self._oinfo = ip._ofind(self.ifun)
161 self._oinfo = ip._ofind(self.ifun)
158 return self._oinfo
162 return self._oinfo
159
163
160 def __str__(self):
164 def __str__(self):
161 return "Lineinfo [%s|%s|%s]" %(self.pre,self.ifun,self.the_rest)
165 return "Lineinfo [%s|%s|%s]" %(self.pre,self.ifun,self.the_rest)
162
166
163
167
164 #-----------------------------------------------------------------------------
168 #-----------------------------------------------------------------------------
165 # Main Prefilter manager
169 # Main Prefilter manager
166 #-----------------------------------------------------------------------------
170 #-----------------------------------------------------------------------------
167
171
168
172
169 class PrefilterManager(Component):
173 class PrefilterManager(Component):
170 """Main prefilter component.
174 """Main prefilter component.
171
175
172 The IPython prefilter is run on all user input before it is run. The
176 The IPython prefilter is run on all user input before it is run. The
173 prefilter consumes lines of input and produces transformed lines of
177 prefilter consumes lines of input and produces transformed lines of
174 input. The implementation consists of checkers and handlers. The
178 input.
175 checkers inspect the input line and select which handler will be used
179
176 to transform the input line.
180 The iplementation consists of two phases:
181
182 1. Transformers
183 2. Checkers and handlers
184
185 Over time, we plan on deprecating the checkers and handlers and doing
186 everything in the transformers.
187
188 The transformers are instances of :class:`PrefilterTransformer` and have
189 a single method :meth:`transform` that takes a line and returns a
190 transformed line. The transformation can be accomplished using any
191 tool, but our current ones use regular expressions for speed. We also
192 ship :mod:`pyparsing` in :mod:`IPython.external` for use in transformers.
193
194 After all the transformers have been run, the line is fed to the checkers,
195 which are instances of :class:`PrefilterChecker`. The line is passed to
196 the :meth:`check` method, which either returns `None` or a
197 :class:`PrefilterHandler` instance. If `None` is returned, the other
198 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
199 the line is passed to the :meth:`handle` method of the returned
200 handler and no further checkers are tried.
201
202 Both transformers and checkers have a `priority` attribute, that determines
203 the order in which they are called. Smaller priorities are tried first.
204
205 Both transformers and checkers also have `enabled` attribute, which is
206 a boolean that determines if the instance is used.
207
208 Users or developers can change the priority or enabled attribute of
209 transformers or checkers, but they must call the :meth:`sort_checkers`
210 or :meth`sort_transformers` method after changing the priority.
177 """
211 """
178
212
179 multi_line_specials = CBool(True, config=True)
213 multi_line_specials = CBool(True, config=True)
180
214
181 def __init__(self, parent, config=None):
215 def __init__(self, parent, config=None):
182 super(PrefilterManager, self).__init__(parent, config=config)
216 super(PrefilterManager, self).__init__(parent, config=config)
217 self.init_transformers()
183 self.init_handlers()
218 self.init_handlers()
184 self.init_checkers()
219 self.init_checkers()
185
220
186 @auto_attr
221 @auto_attr
187 def shell(self):
222 def shell(self):
188 return Component.get_instances(
223 return Component.get_instances(
189 root=self.root,
224 root=self.root,
190 klass='IPython.core.iplib.InteractiveShell')[0]
225 klass='IPython.core.iplib.InteractiveShell')[0]
191
226
227 #-------------------------------------------------------------------------
228 # API for managing transformers
229 #-------------------------------------------------------------------------
230
231 def init_transformers(self):
232 """Create the default transformers."""
233 self._transformers = []
234 for transformer_cls in _default_transformers:
235 transformer_cls(self, config=self.config)
236
237 def sort_transformers(self):
238 """Sort the transformers by priority.
239
240 This must be called after the priority of a transformer is changed.
241 The :meth:`register_transformer` method calls this automatically.
242 """
243 self._transformers.sort(cmp=lambda x,y: x.priority-y.priority)
244
245 @property
246 def transformers(self):
247 """Return a list of checkers, sorted by priority."""
248 return self._transformers
249
250 def register_transformer(self, transformer):
251 """Register a transformer instance."""
252 if transformer not in self._transformers:
253 self._transformers.append(transformer)
254 self.sort_transformers()
255
256 def unregister_transformer(self, transformer):
257 """Unregister a transformer instance."""
258 if transformer in self._transformers:
259 self._transformers.remove(transformer)
260
261 #-------------------------------------------------------------------------
262 # API for managing checkers
263 #-------------------------------------------------------------------------
264
192 def init_checkers(self):
265 def init_checkers(self):
266 """Create the default checkers."""
193 self._checkers = []
267 self._checkers = []
194 for checker in _default_checkers:
268 for checker in _default_checkers:
195 self._checkers.append(checker(self, config=self.config))
269 checker(self, config=self.config)
270
271 def sort_checkers(self):
272 """Sort the checkers by priority.
273
274 This must be called after the priority of a checker is changed.
275 The :meth:`register_checker` method calls this automatically.
276 """
277 self._checkers.sort(cmp=lambda x,y: x.priority-y.priority)
278
279 @property
280 def checkers(self):
281 """Return a list of checkers, sorted by priority."""
282 return self._checkers
283
284 def register_checker(self, checker):
285 """Register a checker instance."""
286 if checker not in self._checkers:
287 self._checkers.append(checker)
288 self.sort_checkers()
289
290 def unregister_checker(self, checker):
291 """Unregister a checker instance."""
292 if checker in self._checkers:
293 self._checkers.remove(checker)
294
295 #-------------------------------------------------------------------------
296 # API for managing checkers
297 #-------------------------------------------------------------------------
196
298
197 def init_handlers(self):
299 def init_handlers(self):
300 """Create the default handlers."""
198 self._handlers = {}
301 self._handlers = {}
199 self._esc_handlers = {}
302 self._esc_handlers = {}
200 for handler in _default_handlers:
303 for handler in _default_handlers:
201 handler(self, config=self.config)
304 handler(self, config=self.config)
202
305
203 @property
306 @property
204 def sorted_checkers(self):
307 def handlers(self):
205 """Return a list of checkers, sorted by priority."""
308 """Return a dict of all the handlers."""
206 return sorted(self._checkers, cmp=lambda x,y: x.priority-y.priority)
309 return self._handlers
207
310
208 def register_handler(self, name, handler, esc_strings):
311 def register_handler(self, name, handler, esc_strings):
209 """Register a handler instance by name with esc_strings."""
312 """Register a handler instance by name with esc_strings."""
210 self._handlers[name] = handler
313 self._handlers[name] = handler
211 for esc_str in esc_strings:
314 for esc_str in esc_strings:
212 self._esc_handlers[esc_str] = handler
315 self._esc_handlers[esc_str] = handler
213
316
214 def unregister_handler(self, name, handler, esc_strings):
317 def unregister_handler(self, name, handler, esc_strings):
215 """Unregister a handler instance by name with esc_strings."""
318 """Unregister a handler instance by name with esc_strings."""
216 try:
319 try:
217 del self._handlers[name]
320 del self._handlers[name]
218 except KeyError:
321 except KeyError:
219 pass
322 pass
220 for esc_str in esc_strings:
323 for esc_str in esc_strings:
221 h = self._esc_handlers.get(esc_str)
324 h = self._esc_handlers.get(esc_str)
222 if h is handler:
325 if h is handler:
223 del self._esc_handlers[esc_str]
326 del self._esc_handlers[esc_str]
224
327
225 def get_handler_by_name(self, name):
328 def get_handler_by_name(self, name):
226 """Get a handler by its name."""
329 """Get a handler by its name."""
227 return self._handlers.get(name)
330 return self._handlers.get(name)
228
331
229 def get_handler_by_esc(self, esc_str):
332 def get_handler_by_esc(self, esc_str):
230 """Get a handler by its escape string."""
333 """Get a handler by its escape string."""
231 return self._esc_handlers.get(esc_str)
334 return self._esc_handlers.get(esc_str)
232
335
336 #-------------------------------------------------------------------------
337 # Main prefiltering API
338 #-------------------------------------------------------------------------
339
233 def prefilter_line_info(self, line_info):
340 def prefilter_line_info(self, line_info):
234 """Prefilter a line that has been converted to a LineInfo object."""
341 """Prefilter a line that has been converted to a LineInfo object.
342
343 This implements the checker/handler part of the prefilter pipe.
344 """
235 # print "prefilter_line_info: ", line_info
345 # print "prefilter_line_info: ", line_info
236 handler = self.find_handler(line_info)
346 handler = self.find_handler(line_info)
237 return handler.handle(line_info)
347 return handler.handle(line_info)
238
348
239 def find_handler(self, line_info):
349 def find_handler(self, line_info):
240 """Find a handler for the line_info by trying checkers."""
350 """Find a handler for the line_info by trying checkers."""
241 for checker in self.sorted_checkers:
351 for checker in self.checkers:
242 handler = checker.check(line_info)
352 if checker.enabled:
243 if handler:
353 handler = checker.check(line_info)
244 # print "Used checker: ", checker
354 if handler:
245 # print "Using handler: ", handler
355 return handler
246 return handler
247 return self.get_handler_by_name('normal')
356 return self.get_handler_by_name('normal')
248
357
358 def transform_line(self, line, continue_prompt):
359 """Calls the enabled transformers in order of increasing priority."""
360 for transformer in self.transformers:
361 if transformer.enabled:
362 line = transformer.transform(line, continue_prompt)
363 return line
364
249 def prefilter_line(self, line, continue_prompt):
365 def prefilter_line(self, line, continue_prompt):
250 """Prefilter a single input line as text."""
366 """Prefilter a single input line as text.
367
368 This method prefilters a single line of text by calling the
369 transformers and then the checkers/handlers.
370 """
251
371
252 # print "prefilter_line: ", line, continue_prompt
372 # print "prefilter_line: ", line, continue_prompt
253 # All handlers *must* return a value, even if it's blank ('').
373 # All handlers *must* return a value, even if it's blank ('').
254
374
255 # Lines are NOT logged here. Handlers should process the line as
375 # Lines are NOT logged here. Handlers should process the line as
256 # needed, update the cache AND log it (so that the input cache array
376 # needed, update the cache AND log it (so that the input cache array
257 # stays synced).
377 # stays synced).
258
378
259 # growl.notify("_prefilter: ", "line = %s\ncontinue_prompt = %s" % (line, continue_prompt))
260
261 # save the line away in case we crash, so the post-mortem handler can
379 # save the line away in case we crash, so the post-mortem handler can
262 # record it
380 # record it
263 self.shell._last_input_line = line
381 self.shell._last_input_line = line
264
382
265 if not line:
383 if not line:
266 # Return immediately on purely empty lines, so that if the user
384 # Return immediately on purely empty lines, so that if the user
267 # previously typed some whitespace that started a continuation
385 # previously typed some whitespace that started a continuation
268 # prompt, he can break out of that loop with just an empty line.
386 # prompt, he can break out of that loop with just an empty line.
269 # This is how the default python prompt works.
387 # This is how the default python prompt works.
270
388
271 # Only return if the accumulated input buffer was just whitespace!
389 # Only return if the accumulated input buffer was just whitespace!
272 if ''.join(self.shell.buffer).isspace():
390 if ''.join(self.shell.buffer).isspace():
273 self.shell.buffer[:] = []
391 self.shell.buffer[:] = []
274 return ''
392 return ''
275
393
394 # At this point, we invoke our transformers.
395 if not continue_prompt or (continue_prompt and self.multi_line_specials):
396 line = self.transform_line(line, continue_prompt)
397
398 # Now we compute line_info for the checkers and handlers
276 line_info = LineInfo(line, continue_prompt)
399 line_info = LineInfo(line, continue_prompt)
277
400
278 # the input history needs to track even empty lines
401 # the input history needs to track even empty lines
279 stripped = line.strip()
402 stripped = line.strip()
280
403
281 normal_handler = self.get_handler_by_name('normal')
404 normal_handler = self.get_handler_by_name('normal')
282 if not stripped:
405 if not stripped:
283 if not continue_prompt:
406 if not continue_prompt:
284 self.shell.outputcache.prompt_count -= 1
407 self.shell.outputcache.prompt_count -= 1
285
408
286 return normal_handler.handle(line_info)
409 return normal_handler.handle(line_info)
287
410
288 # special handlers are only allowed for single line statements
411 # special handlers are only allowed for single line statements
289 if continue_prompt and not self.multi_line_specials:
412 if continue_prompt and not self.multi_line_specials:
290 return normal_handler.handle(line_info)
413 return normal_handler.handle(line_info)
291
414
292 prefiltered = self.prefilter_line_info(line_info)
415 prefiltered = self.prefilter_line_info(line_info)
293 # print "prefiltered line: %r" % prefiltered
416 # print "prefiltered line: %r" % prefiltered
294 return prefiltered
417 return prefiltered
295
418
296 def prefilter_lines(self, lines, continue_prompt):
419 def prefilter_lines(self, lines, continue_prompt):
297 """Prefilter multiple input lines of text.
420 """Prefilter multiple input lines of text.
298
421
299 Covers cases where there are multiple lines in the user entry,
422 This is the main entry point for prefiltering multiple lines of
423 input. This simply calls :meth:`prefilter_line` for each line of
424 input.
425
426 This covers cases where there are multiple lines in the user entry,
300 which is the case when the user goes back to a multiline history
427 which is the case when the user goes back to a multiline history
301 entry and presses enter.
428 entry and presses enter.
302 """
429 """
303 # growl.notify("multiline_prefilter: ", "%s\n%s" % (line, continue_prompt))
304 out = []
430 out = []
305 for line in lines.rstrip('\n').split('\n'):
431 for line in lines.rstrip('\n').split('\n'):
306 out.append(self.prefilter_line(line, continue_prompt))
432 out.append(self.prefilter_line(line, continue_prompt))
307 # growl.notify("multiline_prefilter return: ", '\n'.join(out))
308 return '\n'.join(out)
433 return '\n'.join(out)
309
434
310
435
311 #-----------------------------------------------------------------------------
436 #-----------------------------------------------------------------------------
437 # Prefilter transformers
438 #-----------------------------------------------------------------------------
439
440
441 class PrefilterTransformer(Component):
442 """Transform a line of user input."""
443
444 priority = Int(100, config=True)
445 shell = Any
446 prefilter_manager = Any
447 enabled = Bool(True, config=True)
448
449 def __init__(self, parent, config=None):
450 super(PrefilterTransformer, self).__init__(parent, config=config)
451 self.prefilter_manager.register_transformer(self)
452
453 @auto_attr
454 def shell(self):
455 return Component.get_instances(
456 root=self.root,
457 klass='IPython.core.iplib.InteractiveShell')[0]
458
459 @auto_attr
460 def prefilter_manager(self):
461 return PrefilterManager.get_instances(root=self.root)[0]
462
463 def transform(self, line, continue_prompt):
464 """Transform a line, returning the new one."""
465 return None
466
467 def __repr__(self):
468 return "<%s(priority=%r, enabled=%r)>" % (
469 self.__class__.__name__, self.priority, self.enabled)
470
471
472 _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
473 r'\s*=\s*!(?P<cmd>.*)')
474
475
476 class AssignSystemTransformer(PrefilterTransformer):
477 """Handle the `files = !ls` syntax."""
478
479 priority = Int(100, config=True)
480
481 def transform(self, line, continue_prompt):
482 m = _assign_system_re.match(line)
483 if m is not None:
484 cmd = m.group('cmd')
485 lhs = m.group('lhs')
486 expr = make_quoted_expr("sc -l =%s" % cmd)
487 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
488 return new_line
489 return line
490
491
492 _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
493 r'\s*=\s*%(?P<cmd>.*)')
494
495 class AssignMagicTransformer(PrefilterTransformer):
496 """Handle the `a = %who` syntax."""
497
498 priority = Int(200, config=True)
499
500 def transform(self, line, continue_prompt):
501 m = _assign_magic_re.match(line)
502 if m is not None:
503 cmd = m.group('cmd')
504 lhs = m.group('lhs')
505 expr = make_quoted_expr(cmd)
506 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
507 return new_line
508 return line
509
510
511 #-----------------------------------------------------------------------------
312 # Prefilter checkers
512 # Prefilter checkers
313 #-----------------------------------------------------------------------------
513 #-----------------------------------------------------------------------------
314
514
315
515
316 class PrefilterChecker(Component):
516 class PrefilterChecker(Component):
317 """Inspect an input line and return a handler for that line."""
517 """Inspect an input line and return a handler for that line."""
318
518
319 priority = Int(100, config=True)
519 priority = Int(100, config=True)
320 shell = Any
520 shell = Any
321 prefilter_manager = Any
521 prefilter_manager = Any
522 enabled = Bool(True, config=True)
322
523
323 def __init__(self, parent, config=None):
524 def __init__(self, parent, config=None):
324 super(PrefilterChecker, self).__init__(parent, config=config)
525 super(PrefilterChecker, self).__init__(parent, config=config)
526 self.prefilter_manager.register_checker(self)
325
527
326 @auto_attr
528 @auto_attr
327 def shell(self):
529 def shell(self):
328 return Component.get_instances(
530 return Component.get_instances(
329 root=self.root,
531 root=self.root,
330 klass='IPython.core.iplib.InteractiveShell')[0]
532 klass='IPython.core.iplib.InteractiveShell')[0]
331
533
332 @auto_attr
534 @auto_attr
333 def prefilter_manager(self):
535 def prefilter_manager(self):
334 return PrefilterManager.get_instances(root=self.root)[0]
536 return PrefilterManager.get_instances(root=self.root)[0]
335
537
336 def check(self, line_info):
538 def check(self, line_info):
337 """Inspect line_info and return a handler or None."""
539 """Inspect line_info and return a handler instance or None."""
338 return None
540 return None
339
541
340 def __str__(self):
542 def __repr__(self):
341 return "<%s(priority=%i)>" % (self.__class__.__name__, self.priority)
543 return "<%s(priority=%r, enabled=%r)>" % (
544 self.__class__.__name__, self.priority, self.enabled)
545
342
546
343 class EmacsChecker(PrefilterChecker):
547 class EmacsChecker(PrefilterChecker):
344
548
345 priority = Int(100, config=True)
549 priority = Int(100, config=True)
550 enabled = Bool(False, config=True)
346
551
347 def check(self, line_info):
552 def check(self, line_info):
348 "Emacs ipython-mode tags certain input lines."
553 "Emacs ipython-mode tags certain input lines."
349 if line_info.line.endswith('# PYTHON-MODE'):
554 if line_info.line.endswith('# PYTHON-MODE'):
350 return self.prefilter_manager.get_handler_by_name('emacs')
555 return self.prefilter_manager.get_handler_by_name('emacs')
351 else:
556 else:
352 return None
557 return None
353
558
354
559
355 class ShellEscapeChecker(PrefilterChecker):
560 class ShellEscapeChecker(PrefilterChecker):
356
561
357 priority = Int(200, config=True)
562 priority = Int(200, config=True)
358
563
359 def check(self, line_info):
564 def check(self, line_info):
360 if line_info.line.lstrip().startswith(ESC_SHELL):
565 if line_info.line.lstrip().startswith(ESC_SHELL):
361 return self.prefilter_manager.get_handler_by_name('shell')
566 return self.prefilter_manager.get_handler_by_name('shell')
362
567
363
568
364 class IPyAutocallChecker(PrefilterChecker):
569 class IPyAutocallChecker(PrefilterChecker):
365
570
366 priority = Int(300, config=True)
571 priority = Int(300, config=True)
367
572
368 def check(self, line_info):
573 def check(self, line_info):
369 "Instances of IPyAutocall in user_ns get autocalled immediately"
574 "Instances of IPyAutocall in user_ns get autocalled immediately"
370 obj = self.shell.user_ns.get(line_info.ifun, None)
575 obj = self.shell.user_ns.get(line_info.ifun, None)
371 if isinstance(obj, IPyAutocall):
576 if isinstance(obj, IPyAutocall):
372 obj.set_ip(self.shell)
577 obj.set_ip(self.shell)
373 return self.prefilter_manager.get_handler_by_name('auto')
578 return self.prefilter_manager.get_handler_by_name('auto')
374 else:
579 else:
375 return None
580 return None
376
581
377
582
378 class MultiLineMagicChecker(PrefilterChecker):
583 class MultiLineMagicChecker(PrefilterChecker):
379
584
380 priority = Int(400, config=True)
585 priority = Int(400, config=True)
381
586
382 def check(self, line_info):
587 def check(self, line_info):
383 "Allow ! and !! in multi-line statements if multi_line_specials is on"
588 "Allow ! and !! in multi-line statements if multi_line_specials is on"
384 # Note that this one of the only places we check the first character of
589 # Note that this one of the only places we check the first character of
385 # ifun and *not* the pre_char. Also note that the below test matches
590 # ifun and *not* the pre_char. Also note that the below test matches
386 # both ! and !!.
591 # both ! and !!.
387 if line_info.continue_prompt \
592 if line_info.continue_prompt \
388 and self.prefilter_manager.multi_line_specials:
593 and self.prefilter_manager.multi_line_specials:
389 if line_info.ifun.startswith(ESC_MAGIC):
594 if line_info.ifun.startswith(ESC_MAGIC):
390 return self.prefilter_manager.get_handler_by_name('magic')
595 return self.prefilter_manager.get_handler_by_name('magic')
391 else:
596 else:
392 return None
597 return None
393
598
394
599
395 class EscCharsChecker(PrefilterChecker):
600 class EscCharsChecker(PrefilterChecker):
396
601
397 priority = Int(500, config=True)
602 priority = Int(500, config=True)
398
603
399 def check(self, line_info):
604 def check(self, line_info):
400 """Check for escape character and return either a handler to handle it,
605 """Check for escape character and return either a handler to handle it,
401 or None if there is no escape char."""
606 or None if there is no escape char."""
402 if line_info.line[-1] == ESC_HELP \
607 if line_info.line[-1] == ESC_HELP \
403 and line_info.pre_char != ESC_SHELL \
608 and line_info.pre_char != ESC_SHELL \
404 and line_info.pre_char != ESC_SH_CAP:
609 and line_info.pre_char != ESC_SH_CAP:
405 # the ? can be at the end, but *not* for either kind of shell escape,
610 # the ? can be at the end, but *not* for either kind of shell escape,
406 # because a ? can be a vaild final char in a shell cmd
611 # because a ? can be a vaild final char in a shell cmd
407 return self.prefilter_manager.get_handler_by_name('help')
612 return self.prefilter_manager.get_handler_by_name('help')
408 else:
613 else:
409 # This returns None like it should if no handler exists
614 # This returns None like it should if no handler exists
410 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
615 return self.prefilter_manager.get_handler_by_esc(line_info.pre_char)
411
616
412
617
413 _assign_system_re = re.compile('\s*=\s*!(?P<cmd>.*)')
414 _assign_magic_re = re.compile('\s*=\s*%(?P<cmd>.*)')
415
416
417 class AssignmentChecker(PrefilterChecker):
618 class AssignmentChecker(PrefilterChecker):
418
619
419 priority = Int(600, config=True)
620 priority = Int(600, config=True)
420
621
421 def check(self, line_info):
622 def check(self, line_info):
422 """Check to see if user is assigning to a var for the first time, in
623 """Check to see if user is assigning to a var for the first time, in
423 which case we want to avoid any sort of automagic / autocall games.
624 which case we want to avoid any sort of automagic / autocall games.
424
625
425 This allows users to assign to either alias or magic names true python
626 This allows users to assign to either alias or magic names true python
426 variables (the magic/alias systems always take second seat to true
627 variables (the magic/alias systems always take second seat to true
427 python code). E.g. ls='hi', or ls,that=1,2"""
628 python code). E.g. ls='hi', or ls,that=1,2"""
428 if line_info.the_rest:
629 if line_info.the_rest:
429 if line_info.the_rest[0] in '=,':
630 if line_info.the_rest[0] in '=,':
430 # m = _assign_system_re.match(line_info.the_rest)
431 # if m is not None:
432 # return self.prefilter_manager.get_handler_by_name('assign_system')
433 # m = _assign_magic_re.match(line_info.the_rest)
434 # if m is not None:
435 # return self.prefilter_manager.get_handler_by_name('assign_magic')
436 return self.prefilter_manager.get_handler_by_name('normal')
631 return self.prefilter_manager.get_handler_by_name('normal')
437 else:
632 else:
438 return None
633 return None
439
634
440
635
441 class AutoMagicChecker(PrefilterChecker):
636 class AutoMagicChecker(PrefilterChecker):
442
637
443 priority = Int(700, config=True)
638 priority = Int(700, config=True)
444
639
445 def check(self, line_info):
640 def check(self, line_info):
446 """If the ifun is magic, and automagic is on, run it. Note: normal,
641 """If the ifun is magic, and automagic is on, run it. Note: normal,
447 non-auto magic would already have been triggered via '%' in
642 non-auto magic would already have been triggered via '%' in
448 check_esc_chars. This just checks for automagic. Also, before
643 check_esc_chars. This just checks for automagic. Also, before
449 triggering the magic handler, make sure that there is nothing in the
644 triggering the magic handler, make sure that there is nothing in the
450 user namespace which could shadow it."""
645 user namespace which could shadow it."""
451 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
646 if not self.shell.automagic or not hasattr(self.shell,'magic_'+line_info.ifun):
452 return None
647 return None
453
648
454 # We have a likely magic method. Make sure we should actually call it.
649 # We have a likely magic method. Make sure we should actually call it.
455 if line_info.continue_prompt and not self.shell.multi_line_specials:
650 if line_info.continue_prompt and not self.shell.multi_line_specials:
456 return None
651 return None
457
652
458 head = line_info.ifun.split('.',1)[0]
653 head = line_info.ifun.split('.',1)[0]
459 if is_shadowed(head, self.shell):
654 if is_shadowed(head, self.shell):
460 return None
655 return None
461
656
462 return self.prefilter_manager.get_handler_by_name('magic')
657 return self.prefilter_manager.get_handler_by_name('magic')
463
658
464
659
465 class AliasChecker(PrefilterChecker):
660 class AliasChecker(PrefilterChecker):
466
661
467 priority = Int(800, config=True)
662 priority = Int(800, config=True)
468
663
469 @auto_attr
664 @auto_attr
470 def alias_manager(self):
665 def alias_manager(self):
471 return AliasManager.get_instances(root=self.root)[0]
666 return AliasManager.get_instances(root=self.root)[0]
472
667
473 def check(self, line_info):
668 def check(self, line_info):
474 "Check if the initital identifier on the line is an alias."
669 "Check if the initital identifier on the line is an alias."
475 # Note: aliases can not contain '.'
670 # Note: aliases can not contain '.'
476 head = line_info.ifun.split('.',1)[0]
671 head = line_info.ifun.split('.',1)[0]
477 if line_info.ifun not in self.alias_manager \
672 if line_info.ifun not in self.alias_manager \
478 or head not in self.alias_manager \
673 or head not in self.alias_manager \
479 or is_shadowed(head, self.shell):
674 or is_shadowed(head, self.shell):
480 return None
675 return None
481
676
482 return self.prefilter_manager.get_handler_by_name('alias')
677 return self.prefilter_manager.get_handler_by_name('alias')
483
678
484
679
485 class PythonOpsChecker(PrefilterChecker):
680 class PythonOpsChecker(PrefilterChecker):
486
681
487 priority = Int(900, config=True)
682 priority = Int(900, config=True)
488
683
489 def check(self, line_info):
684 def check(self, line_info):
490 """If the 'rest' of the line begins with a function call or pretty much
685 """If the 'rest' of the line begins with a function call or pretty much
491 any python operator, we should simply execute the line (regardless of
686 any python operator, we should simply execute the line (regardless of
492 whether or not there's a possible autocall expansion). This avoids
687 whether or not there's a possible autocall expansion). This avoids
493 spurious (and very confusing) geattr() accesses."""
688 spurious (and very confusing) geattr() accesses."""
494 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
689 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
495 return self.prefilter_manager.get_handler_by_name('normal')
690 return self.prefilter_manager.get_handler_by_name('normal')
496 else:
691 else:
497 return None
692 return None
498
693
499
694
500 class AutocallChecker(PrefilterChecker):
695 class AutocallChecker(PrefilterChecker):
501
696
502 priority = Int(1000, config=True)
697 priority = Int(1000, config=True)
503
698
504 def check(self, line_info):
699 def check(self, line_info):
505 "Check if the initial word/function is callable and autocall is on."
700 "Check if the initial word/function is callable and autocall is on."
506 if not self.shell.autocall:
701 if not self.shell.autocall:
507 return None
702 return None
508
703
509 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
704 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
510 if not oinfo['found']:
705 if not oinfo['found']:
511 return None
706 return None
512
707
513 if callable(oinfo['obj']) \
708 if callable(oinfo['obj']) \
514 and (not re_exclude_auto.match(line_info.the_rest)) \
709 and (not re_exclude_auto.match(line_info.the_rest)) \
515 and re_fun_name.match(line_info.ifun):
710 and re_fun_name.match(line_info.ifun):
516 return self.prefilter_manager.get_handler_by_name('auto')
711 return self.prefilter_manager.get_handler_by_name('auto')
517 else:
712 else:
518 return None
713 return None
519
714
520
715
521 #-----------------------------------------------------------------------------
716 #-----------------------------------------------------------------------------
522 # Prefilter handlers
717 # Prefilter handlers
523 #-----------------------------------------------------------------------------
718 #-----------------------------------------------------------------------------
524
719
525
720
526 class PrefilterHandler(Component):
721 class PrefilterHandler(Component):
527
722
528 handler_name = Str('normal')
723 handler_name = Str('normal')
529 esc_strings = List([])
724 esc_strings = List([])
530 shell = Any
725 shell = Any
531 prefilter_manager = Any
726 prefilter_manager = Any
532
727
533 def __init__(self, parent, config=None):
728 def __init__(self, parent, config=None):
534 super(PrefilterHandler, self).__init__(parent, config=config)
729 super(PrefilterHandler, self).__init__(parent, config=config)
535 self.prefilter_manager.register_handler(
730 self.prefilter_manager.register_handler(
536 self.handler_name,
731 self.handler_name,
537 self,
732 self,
538 self.esc_strings
733 self.esc_strings
539 )
734 )
540
735
541 @auto_attr
736 @auto_attr
542 def shell(self):
737 def shell(self):
543 return Component.get_instances(
738 return Component.get_instances(
544 root=self.root,
739 root=self.root,
545 klass='IPython.core.iplib.InteractiveShell')[0]
740 klass='IPython.core.iplib.InteractiveShell')[0]
546
741
547 @auto_attr
742 @auto_attr
548 def prefilter_manager(self):
743 def prefilter_manager(self):
549 return PrefilterManager.get_instances(root=self.root)[0]
744 return PrefilterManager.get_instances(root=self.root)[0]
550
745
551 def handle(self, line_info):
746 def handle(self, line_info):
552 # print "normal: ", line_info
747 # print "normal: ", line_info
553 """Handle normal input lines. Use as a template for handlers."""
748 """Handle normal input lines. Use as a template for handlers."""
554
749
555 # With autoindent on, we need some way to exit the input loop, and I
750 # With autoindent on, we need some way to exit the input loop, and I
556 # don't want to force the user to have to backspace all the way to
751 # don't want to force the user to have to backspace all the way to
557 # clear the line. The rule will be in this case, that either two
752 # clear the line. The rule will be in this case, that either two
558 # lines of pure whitespace in a row, or a line of pure whitespace but
753 # lines of pure whitespace in a row, or a line of pure whitespace but
559 # of a size different to the indent level, will exit the input loop.
754 # of a size different to the indent level, will exit the input loop.
560 line = line_info.line
755 line = line_info.line
561 continue_prompt = line_info.continue_prompt
756 continue_prompt = line_info.continue_prompt
562
757
563 if (continue_prompt and self.shell.autoindent and line.isspace() and
758 if (continue_prompt and self.shell.autoindent and line.isspace() and
564 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2 or
759 (0 < abs(len(line) - self.shell.indent_current_nsp) <= 2 or
565 (self.shell.buffer[-1]).isspace() )):
760 (self.shell.buffer[-1]).isspace() )):
566 line = ''
761 line = ''
567
762
568 self.shell.log(line, line, continue_prompt)
763 self.shell.log(line, line, continue_prompt)
569 return line
764 return line
570
765
571 def __str__(self):
766 def __str__(self):
572 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
767 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
573
768
574 class AssignSystemHandler(PrefilterHandler):
575
576 handler_name = Str('assign_system')
577
578 @auto_attr
579 def normal_handler(self):
580 return self.prefilter_manager.get_handler_by_name('normal')
581
582 def handle(self, line_info):
583 new_line = line_info.line
584 m = _assign_system_re.match(line_info.the_rest)
585 if m is not None:
586 cmd = m.group('cmd')
587 expr = make_quoted_expr("sc -l =%s" % cmd)
588 new_line = '%s%s = get_ipython().magic(%s)' % (line_info.pre_whitespace,
589 line_info.ifun, expr)
590 self.shell.log(line_info.line, new_line, line_info.continue_prompt)
591 return new_line
592
593
594 class AssignMagicHandler(PrefilterHandler):
595
596 handler_name = Str('assign_magic')
597
598 @auto_attr
599 def normal_handler(self):
600 return self.prefilter_manager.get_handler_by_name('normal')
601
602 def handle(self, line_info):
603 new_line = line_info.line
604 m = _assign_magic_re.match(line_info.the_rest)
605 if m is not None:
606 cmd = m.group('cmd')
607 expr = make_quoted_expr(cmd)
608 new_line = '%s%s = get_ipython().magic(%s)' % (line_info.pre_whitespace,
609 line_info.ifun, expr)
610 self.shell.log(line_info.line, new_line, line_info.continue_prompt)
611 return new_line
612
613
769
614 class AliasHandler(PrefilterHandler):
770 class AliasHandler(PrefilterHandler):
615
771
616 handler_name = Str('alias')
772 handler_name = Str('alias')
617
773
618 @auto_attr
774 @auto_attr
619 def alias_manager(self):
775 def alias_manager(self):
620 return AliasManager.get_instances(root=self.root)[0]
776 return AliasManager.get_instances(root=self.root)[0]
621
777
622 def handle(self, line_info):
778 def handle(self, line_info):
623 """Handle alias input lines. """
779 """Handle alias input lines. """
624 transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
780 transformed = self.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
625 # pre is needed, because it carries the leading whitespace. Otherwise
781 # pre is needed, because it carries the leading whitespace. Otherwise
626 # aliases won't work in indented sections.
782 # aliases won't work in indented sections.
627 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
783 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
628 make_quoted_expr(transformed))
784 make_quoted_expr(transformed))
629
785
630 self.shell.log(line_info.line, line_out, line_info.continue_prompt)
786 self.shell.log(line_info.line, line_out, line_info.continue_prompt)
631 return line_out
787 return line_out
632
788
633
789
634 class ShellEscapeHandler(PrefilterHandler):
790 class ShellEscapeHandler(PrefilterHandler):
635
791
636 handler_name = Str('shell')
792 handler_name = Str('shell')
637 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
793 esc_strings = List([ESC_SHELL, ESC_SH_CAP])
638
794
639 def handle(self, line_info):
795 def handle(self, line_info):
640 """Execute the line in a shell, empty return value"""
796 """Execute the line in a shell, empty return value"""
641 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
797 magic_handler = self.prefilter_manager.get_handler_by_name('magic')
642
798
643 line = line_info.line
799 line = line_info.line
644 if line.lstrip().startswith(ESC_SH_CAP):
800 if line.lstrip().startswith(ESC_SH_CAP):
645 # rewrite LineInfo's line, ifun and the_rest to properly hold the
801 # rewrite LineInfo's line, ifun and the_rest to properly hold the
646 # call to %sx and the actual command to be executed, so
802 # call to %sx and the actual command to be executed, so
647 # handle_magic can work correctly. Note that this works even if
803 # handle_magic can work correctly. Note that this works even if
648 # the line is indented, so it handles multi_line_specials
804 # the line is indented, so it handles multi_line_specials
649 # properly.
805 # properly.
650 new_rest = line.lstrip()[2:]
806 new_rest = line.lstrip()[2:]
651 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
807 line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest)
652 line_info.ifun = 'sx'
808 line_info.ifun = 'sx'
653 line_info.the_rest = new_rest
809 line_info.the_rest = new_rest
654 return magic_handler.handle(line_info)
810 return magic_handler.handle(line_info)
655 else:
811 else:
656 cmd = line.lstrip().lstrip(ESC_SHELL)
812 cmd = line.lstrip().lstrip(ESC_SHELL)
657 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
813 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
658 make_quoted_expr(cmd))
814 make_quoted_expr(cmd))
659 # update cache/log and return
815 # update cache/log and return
660 self.shell.log(line, line_out, line_info.continue_prompt)
816 self.shell.log(line, line_out, line_info.continue_prompt)
661 return line_out
817 return line_out
662
818
663
819
664 class MagicHandler(PrefilterHandler):
820 class MagicHandler(PrefilterHandler):
665
821
666 handler_name = Str('magic')
822 handler_name = Str('magic')
667 esc_strings = List([ESC_MAGIC])
823 esc_strings = List([ESC_MAGIC])
668
824
669 def handle(self, line_info):
825 def handle(self, line_info):
670 """Execute magic functions."""
826 """Execute magic functions."""
671 ifun = line_info.ifun
827 ifun = line_info.ifun
672 the_rest = line_info.the_rest
828 the_rest = line_info.the_rest
673 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
829 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
674 make_quoted_expr(ifun + " " + the_rest))
830 make_quoted_expr(ifun + " " + the_rest))
675 self.shell.log(line_info.line, cmd, line_info.continue_prompt)
831 self.shell.log(line_info.line, cmd, line_info.continue_prompt)
676 return cmd
832 return cmd
677
833
678
834
679 class AutoHandler(PrefilterHandler):
835 class AutoHandler(PrefilterHandler):
680
836
681 handler_name = Str('auto')
837 handler_name = Str('auto')
682 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
838 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
683
839
684 def handle(self, line_info):
840 def handle(self, line_info):
685 """Hande lines which can be auto-executed, quoting if requested."""
841 """Hande lines which can be auto-executed, quoting if requested."""
686 line = line_info.line
842 line = line_info.line
687 ifun = line_info.ifun
843 ifun = line_info.ifun
688 the_rest = line_info.the_rest
844 the_rest = line_info.the_rest
689 pre = line_info.pre
845 pre = line_info.pre
690 continue_prompt = line_info.continue_prompt
846 continue_prompt = line_info.continue_prompt
691 obj = line_info.ofind(self)['obj']
847 obj = line_info.ofind(self)['obj']
692
848
693 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
849 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
694
850
695 # This should only be active for single-line input!
851 # This should only be active for single-line input!
696 if continue_prompt:
852 if continue_prompt:
697 self.log(line,line,continue_prompt)
853 self.log(line,line,continue_prompt)
698 return line
854 return line
699
855
700 force_auto = isinstance(obj, IPyAutocall)
856 force_auto = isinstance(obj, IPyAutocall)
701 auto_rewrite = True
857 auto_rewrite = True
702
858
703 if pre == ESC_QUOTE:
859 if pre == ESC_QUOTE:
704 # Auto-quote splitting on whitespace
860 # Auto-quote splitting on whitespace
705 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
861 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
706 elif pre == ESC_QUOTE2:
862 elif pre == ESC_QUOTE2:
707 # Auto-quote whole string
863 # Auto-quote whole string
708 newcmd = '%s("%s")' % (ifun,the_rest)
864 newcmd = '%s("%s")' % (ifun,the_rest)
709 elif pre == ESC_PAREN:
865 elif pre == ESC_PAREN:
710 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
866 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
711 else:
867 else:
712 # Auto-paren.
868 # Auto-paren.
713 # We only apply it to argument-less calls if the autocall
869 # We only apply it to argument-less calls if the autocall
714 # parameter is set to 2. We only need to check that autocall is <
870 # parameter is set to 2. We only need to check that autocall is <
715 # 2, since this function isn't called unless it's at least 1.
871 # 2, since this function isn't called unless it's at least 1.
716 if not the_rest and (self.shell.autocall < 2) and not force_auto:
872 if not the_rest and (self.shell.autocall < 2) and not force_auto:
717 newcmd = '%s %s' % (ifun,the_rest)
873 newcmd = '%s %s' % (ifun,the_rest)
718 auto_rewrite = False
874 auto_rewrite = False
719 else:
875 else:
720 if not force_auto and the_rest.startswith('['):
876 if not force_auto and the_rest.startswith('['):
721 if hasattr(obj,'__getitem__'):
877 if hasattr(obj,'__getitem__'):
722 # Don't autocall in this case: item access for an object
878 # Don't autocall in this case: item access for an object
723 # which is BOTH callable and implements __getitem__.
879 # which is BOTH callable and implements __getitem__.
724 newcmd = '%s %s' % (ifun,the_rest)
880 newcmd = '%s %s' % (ifun,the_rest)
725 auto_rewrite = False
881 auto_rewrite = False
726 else:
882 else:
727 # if the object doesn't support [] access, go ahead and
883 # if the object doesn't support [] access, go ahead and
728 # autocall
884 # autocall
729 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
885 newcmd = '%s(%s)' % (ifun.rstrip(),the_rest)
730 elif the_rest.endswith(';'):
886 elif the_rest.endswith(';'):
731 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
887 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
732 else:
888 else:
733 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
889 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
734
890
735 if auto_rewrite:
891 if auto_rewrite:
736 rw = self.shell.outputcache.prompt1.auto_rewrite() + newcmd
892 rw = self.shell.outputcache.prompt1.auto_rewrite() + newcmd
737
893
738 try:
894 try:
739 # plain ascii works better w/ pyreadline, on some machines, so
895 # plain ascii works better w/ pyreadline, on some machines, so
740 # we use it and only print uncolored rewrite if we have unicode
896 # we use it and only print uncolored rewrite if we have unicode
741 rw = str(rw)
897 rw = str(rw)
742 print >>Term.cout, rw
898 print >>Term.cout, rw
743 except UnicodeEncodeError:
899 except UnicodeEncodeError:
744 print "-------------->" + newcmd
900 print "-------------->" + newcmd
745
901
746 # log what is now valid Python, not the actual user input (without the
902 # log what is now valid Python, not the actual user input (without the
747 # final newline)
903 # final newline)
748 self.shell.log(line,newcmd,continue_prompt)
904 self.shell.log(line,newcmd,continue_prompt)
749 return newcmd
905 return newcmd
750
906
751
907
752 class HelpHandler(PrefilterHandler):
908 class HelpHandler(PrefilterHandler):
753
909
754 handler_name = Str('help')
910 handler_name = Str('help')
755 esc_strings = List([ESC_HELP])
911 esc_strings = List([ESC_HELP])
756
912
757 def handle(self, line_info):
913 def handle(self, line_info):
758 """Try to get some help for the object.
914 """Try to get some help for the object.
759
915
760 obj? or ?obj -> basic information.
916 obj? or ?obj -> basic information.
761 obj?? or ??obj -> more details.
917 obj?? or ??obj -> more details.
762 """
918 """
763 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
919 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
764 line = line_info.line
920 line = line_info.line
765 # We need to make sure that we don't process lines which would be
921 # We need to make sure that we don't process lines which would be
766 # otherwise valid python, such as "x=1 # what?"
922 # otherwise valid python, such as "x=1 # what?"
767 try:
923 try:
768 codeop.compile_command(line)
924 codeop.compile_command(line)
769 except SyntaxError:
925 except SyntaxError:
770 # We should only handle as help stuff which is NOT valid syntax
926 # We should only handle as help stuff which is NOT valid syntax
771 if line[0]==ESC_HELP:
927 if line[0]==ESC_HELP:
772 line = line[1:]
928 line = line[1:]
773 elif line[-1]==ESC_HELP:
929 elif line[-1]==ESC_HELP:
774 line = line[:-1]
930 line = line[:-1]
775 self.shell.log(line, '#?'+line, line_info.continue_prompt)
931 self.shell.log(line, '#?'+line, line_info.continue_prompt)
776 if line:
932 if line:
777 #print 'line:<%r>' % line # dbg
933 #print 'line:<%r>' % line # dbg
778 self.shell.magic_pinfo(line)
934 self.shell.magic_pinfo(line)
779 else:
935 else:
780 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
936 page(self.shell.usage, screen_lines=self.shell.usable_screen_length)
781 return '' # Empty string is needed here!
937 return '' # Empty string is needed here!
782 except:
938 except:
783 raise
939 raise
784 # Pass any other exceptions through to the normal handler
940 # Pass any other exceptions through to the normal handler
785 return normal_handler.handle(line_info)
941 return normal_handler.handle(line_info)
786 else:
942 else:
787 raise
943 raise
788 # If the code compiles ok, we should handle it normally
944 # If the code compiles ok, we should handle it normally
789 return normal_handler.handle(line_info)
945 return normal_handler.handle(line_info)
790
946
791
947
792 class EmacsHandler(PrefilterHandler):
948 class EmacsHandler(PrefilterHandler):
793
949
794 handler_name = Str('emacs')
950 handler_name = Str('emacs')
795 esc_strings = List([])
951 esc_strings = List([])
796
952
797 def handle(self, line_info):
953 def handle(self, line_info):
798 """Handle input lines marked by python-mode."""
954 """Handle input lines marked by python-mode."""
799
955
800 # Currently, nothing is done. Later more functionality can be added
956 # Currently, nothing is done. Later more functionality can be added
801 # here if needed.
957 # here if needed.
802
958
803 # The input cache shouldn't be updated
959 # The input cache shouldn't be updated
804 return line_info.line
960 return line_info.line
805
961
806
962
807 #-----------------------------------------------------------------------------
963 #-----------------------------------------------------------------------------
808 # Defaults
964 # Defaults
809 #-----------------------------------------------------------------------------
965 #-----------------------------------------------------------------------------
810
966
811
967
968 _default_transformers = [
969 AssignSystemTransformer,
970 AssignMagicTransformer
971 ]
972
812 _default_checkers = [
973 _default_checkers = [
813 EmacsChecker,
974 EmacsChecker,
814 ShellEscapeChecker,
975 ShellEscapeChecker,
815 IPyAutocallChecker,
976 IPyAutocallChecker,
816 MultiLineMagicChecker,
977 MultiLineMagicChecker,
817 EscCharsChecker,
978 EscCharsChecker,
818 AssignmentChecker,
979 AssignmentChecker,
819 AutoMagicChecker,
980 AutoMagicChecker,
820 AliasChecker,
981 AliasChecker,
821 PythonOpsChecker,
982 PythonOpsChecker,
822 AutocallChecker
983 AutocallChecker
823 ]
984 ]
824
985
825 _default_handlers = [
986 _default_handlers = [
826 PrefilterHandler,
987 PrefilterHandler,
827 AliasHandler,
988 AliasHandler,
828 ShellEscapeHandler,
989 ShellEscapeHandler,
829 MagicHandler,
990 MagicHandler,
830 AutoHandler,
991 AutoHandler,
831 HelpHandler,
992 HelpHandler,
832 EmacsHandler
993 EmacsHandler
833 # AssignSystemHandler,
834 # AssignMagicHandler
835 ]
994 ]
836
995
General Comments 0
You need to be logged in to leave comments. Login now