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