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