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