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