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