##// END OF EJS Templates
Merge pull request #4504 from takluyver/inputtransformer-syntaxerror...
Fernando Perez -
r14990:07072a49 merge
parent child Browse files
Show More
@@ -0,0 +1,6 b''
1 * :class:`IPython.core.inputsplitter.IPythonInputSplitter` no longer has a method
2 ``source_raw_reset()``, but gains :meth:`~IPython.core.inputsplitter.IPythonInputSplitter.raw_reset`
3 instead. Use of ``source_raw_reset`` can be replaced with::
4
5 raw = isp.source_raw
6 transformed = isp.source_reset()
@@ -0,0 +1,4 b''
1 * Input transformers (see :doc:`/config/inputtransforms`) may now raise
2 :exc:`SyntaxError` if they determine that input is invalid. The input
3 transformation machinery in IPython will handle displaying the exception to
4 the user and resetting state.
@@ -1,627 +1,638 b''
1 1 """Input handling and transformation machinery.
2 2
3 3 The first class in this module, :class:`InputSplitter`, is designed to tell when
4 4 input from a line-oriented frontend is complete and should be executed, and when
5 5 the user should be prompted for another line of code instead. The name 'input
6 6 splitter' is largely for historical reasons.
7 7
8 8 A companion, :class:`IPythonInputSplitter`, provides the same functionality but
9 9 with full support for the extended IPython syntax (magics, system calls, etc).
10 10 The code to actually do these transformations is in :mod:`IPython.core.inputtransformer`.
11 11 :class:`IPythonInputSplitter` feeds the raw code to the transformers in order
12 12 and stores the results.
13 13
14 14 For more details, see the class docstrings below.
15 15
16 16 Authors
17 17 -------
18 18
19 19 * Fernando Perez
20 20 * Brian Granger
21 21 * Thomas Kluyver
22 22 """
23 23 #-----------------------------------------------------------------------------
24 24 # Copyright (C) 2010 The IPython Development Team
25 25 #
26 26 # Distributed under the terms of the BSD License. The full license is in
27 27 # the file COPYING, distributed as part of this software.
28 28 #-----------------------------------------------------------------------------
29 29
30 30 #-----------------------------------------------------------------------------
31 31 # Imports
32 32 #-----------------------------------------------------------------------------
33 33 # stdlib
34 34 import ast
35 35 import codeop
36 36 import re
37 37 import sys
38 38
39 39 # IPython modules
40 40 from IPython.utils.py3compat import cast_unicode
41 41 from IPython.core.inputtransformer import (leading_indent,
42 42 classic_prompt,
43 43 ipy_prompt,
44 44 strip_encoding_cookie,
45 45 cellmagic,
46 46 assemble_logical_lines,
47 47 help_end,
48 48 escaped_commands,
49 49 assign_from_magic,
50 50 assign_from_system,
51 51 assemble_python_lines,
52 52 )
53 53
54 54 # These are available in this module for backwards compatibility.
55 55 from IPython.core.inputtransformer import (ESC_SHELL, ESC_SH_CAP, ESC_HELP,
56 56 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,
57 57 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN, ESC_SEQUENCES)
58 58
59 59 #-----------------------------------------------------------------------------
60 60 # Utilities
61 61 #-----------------------------------------------------------------------------
62 62
63 63 # FIXME: These are general-purpose utilities that later can be moved to the
64 64 # general ward. Kept here for now because we're being very strict about test
65 65 # coverage with this code, and this lets us ensure that we keep 100% coverage
66 66 # while developing.
67 67
68 68 # compiled regexps for autoindent management
69 69 dedent_re = re.compile('|'.join([
70 70 r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
71 71 r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
72 72 r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
73 73 r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
74 74 r'^\s+pass\s*$', # pass (optionally followed by trailing spaces)
75 75 r'^\s+break\s*$', # break (optionally followed by trailing spaces)
76 76 r'^\s+continue\s*$', # continue (optionally followed by trailing spaces)
77 77 ]))
78 78 ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
79 79
80 80 # regexp to match pure comment lines so we don't accidentally insert 'if 1:'
81 81 # before pure comments
82 82 comment_line_re = re.compile('^\s*\#')
83 83
84 84
85 85 def num_ini_spaces(s):
86 86 """Return the number of initial spaces in a string.
87 87
88 88 Note that tabs are counted as a single space. For now, we do *not* support
89 89 mixing of tabs and spaces in the user's input.
90 90
91 91 Parameters
92 92 ----------
93 93 s : string
94 94
95 95 Returns
96 96 -------
97 97 n : int
98 98 """
99 99
100 100 ini_spaces = ini_spaces_re.match(s)
101 101 if ini_spaces:
102 102 return ini_spaces.end()
103 103 else:
104 104 return 0
105 105
106 106 def last_blank(src):
107 107 """Determine if the input source ends in a blank.
108 108
109 109 A blank is either a newline or a line consisting of whitespace.
110 110
111 111 Parameters
112 112 ----------
113 113 src : string
114 114 A single or multiline string.
115 115 """
116 116 if not src: return False
117 117 ll = src.splitlines()[-1]
118 118 return (ll == '') or ll.isspace()
119 119
120 120
121 121 last_two_blanks_re = re.compile(r'\n\s*\n\s*$', re.MULTILINE)
122 122 last_two_blanks_re2 = re.compile(r'.+\n\s*\n\s+$', re.MULTILINE)
123 123
124 124 def last_two_blanks(src):
125 125 """Determine if the input source ends in two blanks.
126 126
127 127 A blank is either a newline or a line consisting of whitespace.
128 128
129 129 Parameters
130 130 ----------
131 131 src : string
132 132 A single or multiline string.
133 133 """
134 134 if not src: return False
135 135 # The logic here is tricky: I couldn't get a regexp to work and pass all
136 136 # the tests, so I took a different approach: split the source by lines,
137 137 # grab the last two and prepend '###\n' as a stand-in for whatever was in
138 138 # the body before the last two lines. Then, with that structure, it's
139 139 # possible to analyze with two regexps. Not the most elegant solution, but
140 140 # it works. If anyone tries to change this logic, make sure to validate
141 141 # the whole test suite first!
142 142 new_src = '\n'.join(['###\n'] + src.splitlines()[-2:])
143 143 return (bool(last_two_blanks_re.match(new_src)) or
144 144 bool(last_two_blanks_re2.match(new_src)) )
145 145
146 146
147 147 def remove_comments(src):
148 148 """Remove all comments from input source.
149 149
150 150 Note: comments are NOT recognized inside of strings!
151 151
152 152 Parameters
153 153 ----------
154 154 src : string
155 155 A single or multiline input string.
156 156
157 157 Returns
158 158 -------
159 159 String with all Python comments removed.
160 160 """
161 161
162 162 return re.sub('#.*', '', src)
163 163
164 164
165 165 def get_input_encoding():
166 166 """Return the default standard input encoding.
167 167
168 168 If sys.stdin has no encoding, 'ascii' is returned."""
169 169 # There are strange environments for which sys.stdin.encoding is None. We
170 170 # ensure that a valid encoding is returned.
171 171 encoding = getattr(sys.stdin, 'encoding', None)
172 172 if encoding is None:
173 173 encoding = 'ascii'
174 174 return encoding
175 175
176 176 #-----------------------------------------------------------------------------
177 177 # Classes and functions for normal Python syntax handling
178 178 #-----------------------------------------------------------------------------
179 179
180 180 class InputSplitter(object):
181 181 r"""An object that can accumulate lines of Python source before execution.
182 182
183 183 This object is designed to be fed python source line-by-line, using
184 184 :meth:`push`. It will return on each push whether the currently pushed
185 185 code could be executed already. In addition, it provides a method called
186 186 :meth:`push_accepts_more` that can be used to query whether more input
187 187 can be pushed into a single interactive block.
188 188
189 189 This is a simple example of how an interactive terminal-based client can use
190 190 this tool::
191 191
192 192 isp = InputSplitter()
193 193 while isp.push_accepts_more():
194 194 indent = ' '*isp.indent_spaces
195 195 prompt = '>>> ' + indent
196 196 line = indent + raw_input(prompt)
197 197 isp.push(line)
198 198 print 'Input source was:\n', isp.source_reset(),
199 199 """
200 200 # Number of spaces of indentation computed from input that has been pushed
201 201 # so far. This is the attributes callers should query to get the current
202 202 # indentation level, in order to provide auto-indent facilities.
203 203 indent_spaces = 0
204 204 # String, indicating the default input encoding. It is computed by default
205 205 # at initialization time via get_input_encoding(), but it can be reset by a
206 206 # client with specific knowledge of the encoding.
207 207 encoding = ''
208 208 # String where the current full source input is stored, properly encoded.
209 209 # Reading this attribute is the normal way of querying the currently pushed
210 210 # source code, that has been properly encoded.
211 211 source = ''
212 212 # Code object corresponding to the current source. It is automatically
213 213 # synced to the source, so it can be queried at any time to obtain the code
214 214 # object; it will be None if the source doesn't compile to valid Python.
215 215 code = None
216 216
217 217 # Private attributes
218 218
219 219 # List with lines of input accumulated so far
220 220 _buffer = None
221 221 # Command compiler
222 222 _compile = None
223 223 # Mark when input has changed indentation all the way back to flush-left
224 224 _full_dedent = False
225 225 # Boolean indicating whether the current block is complete
226 226 _is_complete = None
227 227
228 228 def __init__(self):
229 229 """Create a new InputSplitter instance.
230 230 """
231 231 self._buffer = []
232 232 self._compile = codeop.CommandCompiler()
233 233 self.encoding = get_input_encoding()
234 234
235 235 def reset(self):
236 236 """Reset the input buffer and associated state."""
237 237 self.indent_spaces = 0
238 238 self._buffer[:] = []
239 239 self.source = ''
240 240 self.code = None
241 241 self._is_complete = False
242 242 self._full_dedent = False
243 243
244 244 def source_reset(self):
245 245 """Return the input source and perform a full reset.
246 246 """
247 247 out = self.source
248 248 self.reset()
249 249 return out
250 250
251 251 def push(self, lines):
252 252 """Push one or more lines of input.
253 253
254 254 This stores the given lines and returns a status code indicating
255 255 whether the code forms a complete Python block or not.
256 256
257 257 Any exceptions generated in compilation are swallowed, but if an
258 258 exception was produced, the method returns True.
259 259
260 260 Parameters
261 261 ----------
262 262 lines : string
263 263 One or more lines of Python input.
264 264
265 265 Returns
266 266 -------
267 267 is_complete : boolean
268 268 True if the current input source (the result of the current input
269 269 plus prior inputs) forms a complete Python execution block. Note that
270 270 this value is also stored as a private attribute (``_is_complete``), so it
271 271 can be queried at any time.
272 272 """
273 273 self._store(lines)
274 274 source = self.source
275 275
276 276 # Before calling _compile(), reset the code object to None so that if an
277 277 # exception is raised in compilation, we don't mislead by having
278 278 # inconsistent code/source attributes.
279 279 self.code, self._is_complete = None, None
280 280
281 281 # Honor termination lines properly
282 282 if source.endswith('\\\n'):
283 283 return False
284 284
285 285 self._update_indent(lines)
286 286 try:
287 287 self.code = self._compile(source, symbol="exec")
288 288 # Invalid syntax can produce any of a number of different errors from
289 289 # inside the compiler, so we have to catch them all. Syntax errors
290 290 # immediately produce a 'ready' block, so the invalid Python can be
291 291 # sent to the kernel for evaluation with possible ipython
292 292 # special-syntax conversion.
293 293 except (SyntaxError, OverflowError, ValueError, TypeError,
294 294 MemoryError):
295 295 self._is_complete = True
296 296 else:
297 297 # Compilation didn't produce any exceptions (though it may not have
298 298 # given a complete code object)
299 299 self._is_complete = self.code is not None
300 300
301 301 return self._is_complete
302 302
303 303 def push_accepts_more(self):
304 304 """Return whether a block of interactive input can accept more input.
305 305
306 306 This method is meant to be used by line-oriented frontends, who need to
307 307 guess whether a block is complete or not based solely on prior and
308 308 current input lines. The InputSplitter considers it has a complete
309 309 interactive block and will not accept more input when either:
310 310
311 311 * A SyntaxError is raised
312 312
313 313 * The code is complete and consists of a single line or a single
314 314 non-compound statement
315 315
316 316 * The code is complete and has a blank line at the end
317 317
318 318 If the current input produces a syntax error, this method immediately
319 319 returns False but does *not* raise the syntax error exception, as
320 320 typically clients will want to send invalid syntax to an execution
321 321 backend which might convert the invalid syntax into valid Python via
322 322 one of the dynamic IPython mechanisms.
323 323 """
324 324
325 325 # With incomplete input, unconditionally accept more
326 326 # A syntax error also sets _is_complete to True - see push()
327 327 if not self._is_complete:
328 328 #print("Not complete") # debug
329 329 return True
330 330
331 331 # The user can make any (complete) input execute by leaving a blank line
332 332 last_line = self.source.splitlines()[-1]
333 333 if (not last_line) or last_line.isspace():
334 334 #print("Blank line") # debug
335 335 return False
336 336
337 337 # If there's just a single line or AST node, and we're flush left, as is
338 338 # the case after a simple statement such as 'a=1', we want to execute it
339 339 # straight away.
340 340 if self.indent_spaces==0:
341 341 if len(self.source.splitlines()) <= 1:
342 342 return False
343 343
344 344 try:
345 345 code_ast = ast.parse(u''.join(self._buffer))
346 346 except Exception:
347 347 #print("Can't parse AST") # debug
348 348 return False
349 349 else:
350 350 if len(code_ast.body) == 1 and \
351 351 not hasattr(code_ast.body[0], 'body'):
352 352 #print("Simple statement") # debug
353 353 return False
354 354
355 355 # General fallback - accept more code
356 356 return True
357 357
358 358 #------------------------------------------------------------------------
359 359 # Private interface
360 360 #------------------------------------------------------------------------
361 361
362 362 def _find_indent(self, line):
363 363 """Compute the new indentation level for a single line.
364 364
365 365 Parameters
366 366 ----------
367 367 line : str
368 368 A single new line of non-whitespace, non-comment Python input.
369 369
370 370 Returns
371 371 -------
372 372 indent_spaces : int
373 373 New value for the indent level (it may be equal to self.indent_spaces
374 374 if indentation doesn't change.
375 375
376 376 full_dedent : boolean
377 377 Whether the new line causes a full flush-left dedent.
378 378 """
379 379 indent_spaces = self.indent_spaces
380 380 full_dedent = self._full_dedent
381 381
382 382 inisp = num_ini_spaces(line)
383 383 if inisp < indent_spaces:
384 384 indent_spaces = inisp
385 385 if indent_spaces <= 0:
386 386 #print 'Full dedent in text',self.source # dbg
387 387 full_dedent = True
388 388
389 389 if line.rstrip()[-1] == ':':
390 390 indent_spaces += 4
391 391 elif dedent_re.match(line):
392 392 indent_spaces -= 4
393 393 if indent_spaces <= 0:
394 394 full_dedent = True
395 395
396 396 # Safety
397 397 if indent_spaces < 0:
398 398 indent_spaces = 0
399 399 #print 'safety' # dbg
400 400
401 401 return indent_spaces, full_dedent
402 402
403 403 def _update_indent(self, lines):
404 404 for line in remove_comments(lines).splitlines():
405 405 if line and not line.isspace():
406 406 self.indent_spaces, self._full_dedent = self._find_indent(line)
407 407
408 408 def _store(self, lines, buffer=None, store='source'):
409 409 """Store one or more lines of input.
410 410
411 411 If input lines are not newline-terminated, a newline is automatically
412 412 appended."""
413 413
414 414 if buffer is None:
415 415 buffer = self._buffer
416 416
417 417 if lines.endswith('\n'):
418 418 buffer.append(lines)
419 419 else:
420 420 buffer.append(lines+'\n')
421 421 setattr(self, store, self._set_source(buffer))
422 422
423 423 def _set_source(self, buffer):
424 424 return u''.join(buffer)
425 425
426 426
427 427 class IPythonInputSplitter(InputSplitter):
428 428 """An input splitter that recognizes all of IPython's special syntax."""
429 429
430 430 # String with raw, untransformed input.
431 431 source_raw = ''
432 432
433 433 # Flag to track when a transformer has stored input that it hasn't given
434 434 # back yet.
435 435 transformer_accumulating = False
436 436
437 437 # Flag to track when assemble_python_lines has stored input that it hasn't
438 438 # given back yet.
439 439 within_python_line = False
440 440
441 441 # Private attributes
442 442
443 443 # List with lines of raw input accumulated so far.
444 444 _buffer_raw = None
445 445
446 446 def __init__(self, line_input_checker=True, physical_line_transforms=None,
447 447 logical_line_transforms=None, python_line_transforms=None):
448 448 super(IPythonInputSplitter, self).__init__()
449 449 self._buffer_raw = []
450 450 self._validate = True
451 451
452 452 if physical_line_transforms is not None:
453 453 self.physical_line_transforms = physical_line_transforms
454 454 else:
455 455 self.physical_line_transforms = [
456 456 leading_indent(),
457 457 classic_prompt(),
458 458 ipy_prompt(),
459 459 strip_encoding_cookie(),
460 460 cellmagic(end_on_blank_line=line_input_checker),
461 461 ]
462 462
463 463 self.assemble_logical_lines = assemble_logical_lines()
464 464 if logical_line_transforms is not None:
465 465 self.logical_line_transforms = logical_line_transforms
466 466 else:
467 467 self.logical_line_transforms = [
468 468 help_end(),
469 469 escaped_commands(),
470 470 assign_from_magic(),
471 471 assign_from_system(),
472 472 ]
473 473
474 474 self.assemble_python_lines = assemble_python_lines()
475 475 if python_line_transforms is not None:
476 476 self.python_line_transforms = python_line_transforms
477 477 else:
478 478 # We don't use any of these at present
479 479 self.python_line_transforms = []
480 480
481 481 @property
482 482 def transforms(self):
483 483 "Quick access to all transformers."
484 484 return self.physical_line_transforms + \
485 485 [self.assemble_logical_lines] + self.logical_line_transforms + \
486 486 [self.assemble_python_lines] + self.python_line_transforms
487 487
488 488 @property
489 489 def transforms_in_use(self):
490 490 """Transformers, excluding logical line transformers if we're in a
491 491 Python line."""
492 492 t = self.physical_line_transforms[:]
493 493 if not self.within_python_line:
494 494 t += [self.assemble_logical_lines] + self.logical_line_transforms
495 495 return t + [self.assemble_python_lines] + self.python_line_transforms
496 496
497 497 def reset(self):
498 498 """Reset the input buffer and associated state."""
499 499 super(IPythonInputSplitter, self).reset()
500 500 self._buffer_raw[:] = []
501 501 self.source_raw = ''
502 502 self.transformer_accumulating = False
503 503 self.within_python_line = False
504
504 505 for t in self.transforms:
505 t.reset()
506 try:
507 t.reset()
508 except SyntaxError:
509 # Nothing that calls reset() expects to handle transformer
510 # errors
511 pass
506 512
507 513 def flush_transformers(self):
508 514 def _flush(transform, out):
509 515 if out is not None:
510 516 tmp = transform.push(out)
511 517 return tmp or transform.reset() or None
512 518 else:
513 519 return transform.reset() or None
514 520
515 521 out = None
516 522 for t in self.transforms_in_use:
517 523 out = _flush(t, out)
518 524
519 525 if out is not None:
520 526 self._store(out)
521 527
522 def source_raw_reset(self):
523 """Return input and raw source and perform a full reset.
528 def raw_reset(self):
529 """Return raw input only and perform a full reset.
524 530 """
525 self.flush_transformers()
526 out = self.source
527 out_r = self.source_raw
531 out = self.source_raw
528 532 self.reset()
529 return out, out_r
533 return out
530 534
531 535 def source_reset(self):
532 self.flush_transformers()
533 return super(IPythonInputSplitter, self).source_reset()
536 try:
537 self.flush_transformers()
538 return self.source
539 finally:
540 self.reset()
534 541
535 542 def push_accepts_more(self):
536 543 if self.transformer_accumulating:
537 544 return True
538 545 else:
539 546 return super(IPythonInputSplitter, self).push_accepts_more()
540 547
541 548 def transform_cell(self, cell):
542 549 """Process and translate a cell of input.
543 550 """
544 551 self.reset()
545 self.push(cell)
546 return self.source_reset()
552 try:
553 self.push(cell)
554 self.flush_transformers()
555 return self.source
556 finally:
557 self.reset()
547 558
548 559 def push(self, lines):
549 560 """Push one or more lines of IPython input.
550 561
551 562 This stores the given lines and returns a status code indicating
552 563 whether the code forms a complete Python block or not, after processing
553 564 all input lines for special IPython syntax.
554 565
555 566 Any exceptions generated in compilation are swallowed, but if an
556 567 exception was produced, the method returns True.
557 568
558 569 Parameters
559 570 ----------
560 571 lines : string
561 572 One or more lines of Python input.
562 573
563 574 Returns
564 575 -------
565 576 is_complete : boolean
566 577 True if the current input source (the result of the current input
567 578 plus prior inputs) forms a complete Python execution block. Note that
568 579 this value is also stored as a private attribute (_is_complete), so it
569 580 can be queried at any time.
570 581 """
571 582
572 583 # We must ensure all input is pure unicode
573 584 lines = cast_unicode(lines, self.encoding)
574 585
575 586 # ''.splitlines() --> [], but we need to push the empty line to transformers
576 587 lines_list = lines.splitlines()
577 588 if not lines_list:
578 589 lines_list = ['']
579 590
580 591 # Store raw source before applying any transformations to it. Note
581 592 # that this must be done *after* the reset() call that would otherwise
582 593 # flush the buffer.
583 594 self._store(lines, self._buffer_raw, 'source_raw')
584 595
585 596 for line in lines_list:
586 597 out = self.push_line(line)
587 598
588 599 return out
589 600
590 601 def push_line(self, line):
591 602 buf = self._buffer
592 603
593 604 def _accumulating(dbg):
594 605 #print(dbg)
595 606 self.transformer_accumulating = True
596 607 return False
597 608
598 609 for transformer in self.physical_line_transforms:
599 610 line = transformer.push(line)
600 611 if line is None:
601 612 return _accumulating(transformer)
602 613
603 614 if not self.within_python_line:
604 615 line = self.assemble_logical_lines.push(line)
605 616 if line is None:
606 617 return _accumulating('acc logical line')
607 618
608 619 for transformer in self.logical_line_transforms:
609 620 line = transformer.push(line)
610 621 if line is None:
611 622 return _accumulating(transformer)
612 623
613 624 line = self.assemble_python_lines.push(line)
614 625 if line is None:
615 626 self.within_python_line = True
616 627 return _accumulating('acc python line')
617 628 else:
618 629 self.within_python_line = False
619 630
620 631 for transformer in self.python_line_transforms:
621 632 line = transformer.push(line)
622 633 if line is None:
623 634 return _accumulating(transformer)
624 635
625 636 #print("transformers clear") #debug
626 637 self.transformer_accumulating = False
627 638 return super(IPythonInputSplitter, self).push(line)
@@ -1,539 +1,542 b''
1 1 """Input transformer classes to support IPython special syntax.
2 2
3 3 This includes the machinery to recognise and transform ``%magic`` commands,
4 4 ``!system`` commands, ``help?`` querying, prompt stripping, and so forth.
5 5 """
6 6 import abc
7 7 import functools
8 8 import re
9 9
10 10 from IPython.core.splitinput import LineInfo
11 11 from IPython.utils import tokenize2
12 12 from IPython.utils.openpy import cookie_comment_re
13 13 from IPython.utils.py3compat import with_metaclass, PY3
14 14 from IPython.utils.tokenize2 import generate_tokens, untokenize, TokenError
15 15
16 16 if PY3:
17 17 from io import StringIO
18 18 else:
19 19 from StringIO import StringIO
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Globals
23 23 #-----------------------------------------------------------------------------
24 24
25 25 # The escape sequences that define the syntax transformations IPython will
26 26 # apply to user input. These can NOT be just changed here: many regular
27 27 # expressions and other parts of the code may use their hardcoded values, and
28 28 # for all intents and purposes they constitute the 'IPython syntax', so they
29 29 # should be considered fixed.
30 30
31 31 ESC_SHELL = '!' # Send line to underlying system shell
32 32 ESC_SH_CAP = '!!' # Send line to system shell and capture output
33 33 ESC_HELP = '?' # Find information about object
34 34 ESC_HELP2 = '??' # Find extra-detailed information about object
35 35 ESC_MAGIC = '%' # Call magic function
36 36 ESC_MAGIC2 = '%%' # Call cell-magic function
37 37 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
38 38 ESC_QUOTE2 = ';' # Quote all args as a single string, call
39 39 ESC_PAREN = '/' # Call first argument with rest of line as arguments
40 40
41 41 ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
42 42 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
43 43 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
44 44
45 45
46 46 class InputTransformer(with_metaclass(abc.ABCMeta, object)):
47 47 """Abstract base class for line-based input transformers."""
48 48
49 49 @abc.abstractmethod
50 50 def push(self, line):
51 51 """Send a line of input to the transformer, returning the transformed
52 52 input or None if the transformer is waiting for more input.
53 53
54 54 Must be overridden by subclasses.
55
56 Implementations may raise ``SyntaxError`` if the input is invalid. No
57 other exceptions may be raised.
55 58 """
56 59 pass
57 60
58 61 @abc.abstractmethod
59 62 def reset(self):
60 63 """Return, transformed any lines that the transformer has accumulated,
61 64 and reset its internal state.
62 65
63 66 Must be overridden by subclasses.
64 67 """
65 68 pass
66 69
67 70 @classmethod
68 71 def wrap(cls, func):
69 72 """Can be used by subclasses as a decorator, to return a factory that
70 73 will allow instantiation with the decorated object.
71 74 """
72 75 @functools.wraps(func)
73 76 def transformer_factory(**kwargs):
74 77 return cls(func, **kwargs)
75 78
76 79 return transformer_factory
77 80
78 81 class StatelessInputTransformer(InputTransformer):
79 82 """Wrapper for a stateless input transformer implemented as a function."""
80 83 def __init__(self, func):
81 84 self.func = func
82 85
83 86 def __repr__(self):
84 87 return "StatelessInputTransformer(func={0!r})".format(self.func)
85 88
86 89 def push(self, line):
87 90 """Send a line of input to the transformer, returning the
88 91 transformed input."""
89 92 return self.func(line)
90 93
91 94 def reset(self):
92 95 """No-op - exists for compatibility."""
93 96 pass
94 97
95 98 class CoroutineInputTransformer(InputTransformer):
96 99 """Wrapper for an input transformer implemented as a coroutine."""
97 100 def __init__(self, coro, **kwargs):
98 101 # Prime it
99 102 self.coro = coro(**kwargs)
100 103 next(self.coro)
101 104
102 105 def __repr__(self):
103 106 return "CoroutineInputTransformer(coro={0!r})".format(self.coro)
104 107
105 108 def push(self, line):
106 109 """Send a line of input to the transformer, returning the
107 110 transformed input or None if the transformer is waiting for more
108 111 input.
109 112 """
110 113 return self.coro.send(line)
111 114
112 115 def reset(self):
113 116 """Return, transformed any lines that the transformer has
114 117 accumulated, and reset its internal state.
115 118 """
116 119 return self.coro.send(None)
117 120
118 121 class TokenInputTransformer(InputTransformer):
119 122 """Wrapper for a token-based input transformer.
120 123
121 124 func should accept a list of tokens (5-tuples, see tokenize docs), and
122 125 return an iterable which can be passed to tokenize.untokenize().
123 126 """
124 127 def __init__(self, func):
125 128 self.func = func
126 129 self.current_line = ""
127 130 self.line_used = False
128 131 self.reset_tokenizer()
129 132
130 133 def reset_tokenizer(self):
131 134 self.tokenizer = generate_tokens(self.get_line)
132 135
133 136 def get_line(self):
134 137 if self.line_used:
135 138 raise TokenError
136 139 self.line_used = True
137 140 return self.current_line
138 141
139 142 def push(self, line):
140 143 self.current_line += line + "\n"
141 144 if self.current_line.isspace():
142 145 return self.reset()
143 146
144 147 self.line_used = False
145 148 tokens = []
146 149 stop_at_NL = False
147 150 try:
148 151 for intok in self.tokenizer:
149 152 tokens.append(intok)
150 153 t = intok[0]
151 154 if t == tokenize2.NEWLINE or (stop_at_NL and t == tokenize2.NL):
152 155 # Stop before we try to pull a line we don't have yet
153 156 break
154 157 elif t == tokenize2.ERRORTOKEN:
155 158 stop_at_NL = True
156 159 except TokenError:
157 160 # Multi-line statement - stop and try again with the next line
158 161 self.reset_tokenizer()
159 162 return None
160 163
161 164 return self.output(tokens)
162 165
163 166 def output(self, tokens):
164 167 self.current_line = ""
165 168 self.reset_tokenizer()
166 169 return untokenize(self.func(tokens)).rstrip('\n')
167 170
168 171 def reset(self):
169 172 l = self.current_line
170 173 self.current_line = ""
171 174 self.reset_tokenizer()
172 175 if l:
173 176 return l.rstrip('\n')
174 177
175 178 class assemble_python_lines(TokenInputTransformer):
176 179 def __init__(self):
177 180 super(assemble_python_lines, self).__init__(None)
178 181
179 182 def output(self, tokens):
180 183 return self.reset()
181 184
182 185 @CoroutineInputTransformer.wrap
183 186 def assemble_logical_lines():
184 187 """Join lines following explicit line continuations (\)"""
185 188 line = ''
186 189 while True:
187 190 line = (yield line)
188 191 if not line or line.isspace():
189 192 continue
190 193
191 194 parts = []
192 195 while line is not None:
193 196 if line.endswith('\\') and (not has_comment(line)):
194 197 parts.append(line[:-1])
195 198 line = (yield None) # Get another line
196 199 else:
197 200 parts.append(line)
198 201 break
199 202
200 203 # Output
201 204 line = ''.join(parts)
202 205
203 206 # Utilities
204 207 def _make_help_call(target, esc, lspace, next_input=None):
205 208 """Prepares a pinfo(2)/psearch call from a target name and the escape
206 209 (i.e. ? or ??)"""
207 210 method = 'pinfo2' if esc == '??' \
208 211 else 'psearch' if '*' in target \
209 212 else 'pinfo'
210 213 arg = " ".join([method, target])
211 214 if next_input is None:
212 215 return '%sget_ipython().magic(%r)' % (lspace, arg)
213 216 else:
214 217 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
215 218 (lspace, next_input, arg)
216 219
217 220 # These define the transformations for the different escape characters.
218 221 def _tr_system(line_info):
219 222 "Translate lines escaped with: !"
220 223 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
221 224 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
222 225
223 226 def _tr_system2(line_info):
224 227 "Translate lines escaped with: !!"
225 228 cmd = line_info.line.lstrip()[2:]
226 229 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
227 230
228 231 def _tr_help(line_info):
229 232 "Translate lines escaped with: ?/??"
230 233 # A naked help line should just fire the intro help screen
231 234 if not line_info.line[1:]:
232 235 return 'get_ipython().show_usage()'
233 236
234 237 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
235 238
236 239 def _tr_magic(line_info):
237 240 "Translate lines escaped with: %"
238 241 tpl = '%sget_ipython().magic(%r)'
239 242 if line_info.line.startswith(ESC_MAGIC2):
240 243 return line_info.line
241 244 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
242 245 return tpl % (line_info.pre, cmd)
243 246
244 247 def _tr_quote(line_info):
245 248 "Translate lines escaped with: ,"
246 249 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
247 250 '", "'.join(line_info.the_rest.split()) )
248 251
249 252 def _tr_quote2(line_info):
250 253 "Translate lines escaped with: ;"
251 254 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
252 255 line_info.the_rest)
253 256
254 257 def _tr_paren(line_info):
255 258 "Translate lines escaped with: /"
256 259 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
257 260 ", ".join(line_info.the_rest.split()))
258 261
259 262 tr = { ESC_SHELL : _tr_system,
260 263 ESC_SH_CAP : _tr_system2,
261 264 ESC_HELP : _tr_help,
262 265 ESC_HELP2 : _tr_help,
263 266 ESC_MAGIC : _tr_magic,
264 267 ESC_QUOTE : _tr_quote,
265 268 ESC_QUOTE2 : _tr_quote2,
266 269 ESC_PAREN : _tr_paren }
267 270
268 271 @StatelessInputTransformer.wrap
269 272 def escaped_commands(line):
270 273 """Transform escaped commands - %magic, !system, ?help + various autocalls.
271 274 """
272 275 if not line or line.isspace():
273 276 return line
274 277 lineinf = LineInfo(line)
275 278 if lineinf.esc not in tr:
276 279 return line
277 280
278 281 return tr[lineinf.esc](lineinf)
279 282
280 283 _initial_space_re = re.compile(r'\s*')
281 284
282 285 _help_end_re = re.compile(r"""(%{0,2}
283 286 [a-zA-Z_*][\w*]* # Variable name
284 287 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
285 288 )
286 289 (\?\??)$ # ? or ??
287 290 """,
288 291 re.VERBOSE)
289 292
290 293 # Extra pseudotokens for multiline strings and data structures
291 294 _MULTILINE_STRING = object()
292 295 _MULTILINE_STRUCTURE = object()
293 296
294 297 def _line_tokens(line):
295 298 """Helper for has_comment and ends_in_comment_or_string."""
296 299 readline = StringIO(line).readline
297 300 toktypes = set()
298 301 try:
299 302 for t in generate_tokens(readline):
300 303 toktypes.add(t[0])
301 304 except TokenError as e:
302 305 # There are only two cases where a TokenError is raised.
303 306 if 'multi-line string' in e.args[0]:
304 307 toktypes.add(_MULTILINE_STRING)
305 308 else:
306 309 toktypes.add(_MULTILINE_STRUCTURE)
307 310 return toktypes
308 311
309 312 def has_comment(src):
310 313 """Indicate whether an input line has (i.e. ends in, or is) a comment.
311 314
312 315 This uses tokenize, so it can distinguish comments from # inside strings.
313 316
314 317 Parameters
315 318 ----------
316 319 src : string
317 320 A single line input string.
318 321
319 322 Returns
320 323 -------
321 324 comment : bool
322 325 True if source has a comment.
323 326 """
324 327 return (tokenize2.COMMENT in _line_tokens(src))
325 328
326 329 def ends_in_comment_or_string(src):
327 330 """Indicates whether or not an input line ends in a comment or within
328 331 a multiline string.
329 332
330 333 Parameters
331 334 ----------
332 335 src : string
333 336 A single line input string.
334 337
335 338 Returns
336 339 -------
337 340 comment : bool
338 341 True if source ends in a comment or multiline string.
339 342 """
340 343 toktypes = _line_tokens(src)
341 344 return (tokenize2.COMMENT in toktypes) or (_MULTILINE_STRING in toktypes)
342 345
343 346
344 347 @StatelessInputTransformer.wrap
345 348 def help_end(line):
346 349 """Translate lines with ?/?? at the end"""
347 350 m = _help_end_re.search(line)
348 351 if m is None or ends_in_comment_or_string(line):
349 352 return line
350 353 target = m.group(1)
351 354 esc = m.group(3)
352 355 lspace = _initial_space_re.match(line).group(0)
353 356
354 357 # If we're mid-command, put it back on the next prompt for the user.
355 358 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
356 359
357 360 return _make_help_call(target, esc, lspace, next_input)
358 361
359 362
360 363 @CoroutineInputTransformer.wrap
361 364 def cellmagic(end_on_blank_line=False):
362 365 """Captures & transforms cell magics.
363 366
364 367 After a cell magic is started, this stores up any lines it gets until it is
365 368 reset (sent None).
366 369 """
367 370 tpl = 'get_ipython().run_cell_magic(%r, %r, %r)'
368 371 cellmagic_help_re = re.compile('%%\w+\?')
369 372 line = ''
370 373 while True:
371 374 line = (yield line)
372 375 # consume leading empty lines
373 376 while not line:
374 377 line = (yield line)
375 378
376 379 if not line.startswith(ESC_MAGIC2):
377 380 # This isn't a cell magic, idle waiting for reset then start over
378 381 while line is not None:
379 382 line = (yield line)
380 383 continue
381 384
382 385 if cellmagic_help_re.match(line):
383 386 # This case will be handled by help_end
384 387 continue
385 388
386 389 first = line
387 390 body = []
388 391 line = (yield None)
389 392 while (line is not None) and \
390 393 ((line.strip() != '') or not end_on_blank_line):
391 394 body.append(line)
392 395 line = (yield None)
393 396
394 397 # Output
395 398 magic_name, _, first = first.partition(' ')
396 399 magic_name = magic_name.lstrip(ESC_MAGIC2)
397 400 line = tpl % (magic_name, first, u'\n'.join(body))
398 401
399 402
400 403 def _strip_prompts(prompt_re, initial_re=None):
401 404 """Remove matching input prompts from a block of input.
402 405
403 406 Parameters
404 407 ----------
405 408 prompt_re : regular expression
406 409 A regular expression matching any input prompt (including continuation)
407 410 initial_re : regular expression, optional
408 411 A regular expression matching only the initial prompt, but not continuation.
409 412 If no initial expression is given, prompt_re will be used everywhere.
410 413 Used mainly for plain Python prompts, where the continuation prompt
411 414 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
412 415
413 416 If initial_re and prompt_re differ,
414 417 only initial_re will be tested against the first line.
415 418 If any prompt is found on the first two lines,
416 419 prompts will be stripped from the rest of the block.
417 420 """
418 421 if initial_re is None:
419 422 initial_re = prompt_re
420 423 line = ''
421 424 while True:
422 425 line = (yield line)
423 426
424 427 # First line of cell
425 428 if line is None:
426 429 continue
427 430 out, n1 = initial_re.subn('', line, count=1)
428 431 line = (yield out)
429 432
430 433 if line is None:
431 434 continue
432 435 # check for any prompt on the second line of the cell,
433 436 # because people often copy from just after the first prompt,
434 437 # so we might not see it in the first line.
435 438 out, n2 = prompt_re.subn('', line, count=1)
436 439 line = (yield out)
437 440
438 441 if n1 or n2:
439 442 # Found a prompt in the first two lines - check for it in
440 443 # the rest of the cell as well.
441 444 while line is not None:
442 445 line = (yield prompt_re.sub('', line, count=1))
443 446
444 447 else:
445 448 # Prompts not in input - wait for reset
446 449 while line is not None:
447 450 line = (yield line)
448 451
449 452 @CoroutineInputTransformer.wrap
450 453 def classic_prompt():
451 454 """Strip the >>>/... prompts of the Python interactive shell."""
452 455 # FIXME: non-capturing version (?:...) usable?
453 456 prompt_re = re.compile(r'^(>>> ?|\.\.\. ?)')
454 457 initial_re = re.compile(r'^(>>> ?)')
455 458 return _strip_prompts(prompt_re, initial_re)
456 459
457 460 @CoroutineInputTransformer.wrap
458 461 def ipy_prompt():
459 462 """Strip IPython's In [1]:/...: prompts."""
460 463 # FIXME: non-capturing version (?:...) usable?
461 464 prompt_re = re.compile(r'^(In \[\d+\]: |\ {3,}\.{3,}: )')
462 465 return _strip_prompts(prompt_re)
463 466
464 467
465 468 @CoroutineInputTransformer.wrap
466 469 def leading_indent():
467 470 """Remove leading indentation.
468 471
469 472 If the first line starts with a spaces or tabs, the same whitespace will be
470 473 removed from each following line until it is reset.
471 474 """
472 475 space_re = re.compile(r'^[ \t]+')
473 476 line = ''
474 477 while True:
475 478 line = (yield line)
476 479
477 480 if line is None:
478 481 continue
479 482
480 483 m = space_re.match(line)
481 484 if m:
482 485 space = m.group(0)
483 486 while line is not None:
484 487 if line.startswith(space):
485 488 line = line[len(space):]
486 489 line = (yield line)
487 490 else:
488 491 # No leading spaces - wait for reset
489 492 while line is not None:
490 493 line = (yield line)
491 494
492 495
493 496 @CoroutineInputTransformer.wrap
494 497 def strip_encoding_cookie():
495 498 """Remove encoding comment if found in first two lines
496 499
497 500 If the first or second line has the `# coding: utf-8` comment,
498 501 it will be removed.
499 502 """
500 503 line = ''
501 504 while True:
502 505 line = (yield line)
503 506 # check comment on first two lines
504 507 for i in range(2):
505 508 if line is None:
506 509 break
507 510 if cookie_comment_re.match(line):
508 511 line = (yield "")
509 512 else:
510 513 line = (yield line)
511 514
512 515 # no-op on the rest of the cell
513 516 while line is not None:
514 517 line = (yield line)
515 518
516 519
517 520 assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
518 521 r'\s*=\s*!\s*(?P<cmd>.*)')
519 522 assign_system_template = '%s = get_ipython().getoutput(%r)'
520 523 @StatelessInputTransformer.wrap
521 524 def assign_from_system(line):
522 525 """Transform assignment from system commands (e.g. files = !ls)"""
523 526 m = assign_system_re.match(line)
524 527 if m is None:
525 528 return line
526 529
527 530 return assign_system_template % m.group('lhs', 'cmd')
528 531
529 532 assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))'
530 533 r'\s*=\s*%\s*(?P<cmd>.*)')
531 534 assign_magic_template = '%s = get_ipython().magic(%r)'
532 535 @StatelessInputTransformer.wrap
533 536 def assign_from_magic(line):
534 537 """Transform assignment from magic commands (e.g. a = %who_ls)"""
535 538 m = assign_magic_re.match(line)
536 539 if m is None:
537 540 return line
538 541
539 542 return assign_magic_template % m.group('lhs', 'cmd')
@@ -1,3199 +1,3213 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Main IPython class."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from __future__ import absolute_import
18 18 from __future__ import print_function
19 19
20 20 import __future__
21 21 import abc
22 22 import ast
23 23 import atexit
24 24 import functools
25 25 import os
26 26 import re
27 27 import runpy
28 28 import sys
29 29 import tempfile
30 30 import types
31 31 import subprocess
32 32 from io import open as io_open
33 33
34 34 from IPython.config.configurable import SingletonConfigurable
35 35 from IPython.core import debugger, oinspect
36 36 from IPython.core import magic
37 37 from IPython.core import page
38 38 from IPython.core import prefilter
39 39 from IPython.core import shadowns
40 40 from IPython.core import ultratb
41 41 from IPython.core.alias import AliasManager, AliasError
42 42 from IPython.core.autocall import ExitAutocall
43 43 from IPython.core.builtin_trap import BuiltinTrap
44 44 from IPython.core.compilerop import CachingCompiler, check_linecache_ipython
45 45 from IPython.core.display_trap import DisplayTrap
46 46 from IPython.core.displayhook import DisplayHook
47 47 from IPython.core.displaypub import DisplayPublisher
48 48 from IPython.core.error import UsageError
49 49 from IPython.core.extensions import ExtensionManager
50 50 from IPython.core.formatters import DisplayFormatter
51 51 from IPython.core.history import HistoryManager
52 52 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
53 53 from IPython.core.logger import Logger
54 54 from IPython.core.macro import Macro
55 55 from IPython.core.payload import PayloadManager
56 56 from IPython.core.prefilter import PrefilterManager
57 57 from IPython.core.profiledir import ProfileDir
58 58 from IPython.core.prompts import PromptManager
59 59 from IPython.lib.latextools import LaTeXTool
60 60 from IPython.testing.skipdoctest import skip_doctest
61 61 from IPython.utils import PyColorize
62 62 from IPython.utils import io
63 63 from IPython.utils import py3compat
64 64 from IPython.utils import openpy
65 65 from IPython.utils.decorators import undoc
66 66 from IPython.utils.io import ask_yes_no
67 67 from IPython.utils.ipstruct import Struct
68 68 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename
69 69 from IPython.utils.pickleshare import PickleShareDB
70 70 from IPython.utils.process import system, getoutput
71 71 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
72 72 with_metaclass, iteritems)
73 73 from IPython.utils.strdispatch import StrDispatch
74 74 from IPython.utils.syspathcontext import prepended_to_syspath
75 75 from IPython.utils.text import (format_screen, LSString, SList,
76 76 DollarFormatter)
77 77 from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
78 78 List, Unicode, Instance, Type)
79 79 from IPython.utils.warn import warn, error
80 80 import IPython.core.hooks
81 81
82 82 #-----------------------------------------------------------------------------
83 83 # Globals
84 84 #-----------------------------------------------------------------------------
85 85
86 86 # compiled regexps for autoindent management
87 87 dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
88 88
89 89 #-----------------------------------------------------------------------------
90 90 # Utilities
91 91 #-----------------------------------------------------------------------------
92 92
93 93 @undoc
94 94 def softspace(file, newvalue):
95 95 """Copied from code.py, to remove the dependency"""
96 96
97 97 oldvalue = 0
98 98 try:
99 99 oldvalue = file.softspace
100 100 except AttributeError:
101 101 pass
102 102 try:
103 103 file.softspace = newvalue
104 104 except (AttributeError, TypeError):
105 105 # "attribute-less object" or "read-only attributes"
106 106 pass
107 107 return oldvalue
108 108
109 109 @undoc
110 110 def no_op(*a, **kw): pass
111 111
112 112 @undoc
113 113 class NoOpContext(object):
114 114 def __enter__(self): pass
115 115 def __exit__(self, type, value, traceback): pass
116 116 no_op_context = NoOpContext()
117 117
118 118 class SpaceInInput(Exception): pass
119 119
120 120 @undoc
121 121 class Bunch: pass
122 122
123 123
124 124 def get_default_colors():
125 125 if sys.platform=='darwin':
126 126 return "LightBG"
127 127 elif os.name=='nt':
128 128 return 'Linux'
129 129 else:
130 130 return 'Linux'
131 131
132 132
133 133 class SeparateUnicode(Unicode):
134 134 r"""A Unicode subclass to validate separate_in, separate_out, etc.
135 135
136 136 This is a Unicode based trait that converts '0'->'' and ``'\\n'->'\n'``.
137 137 """
138 138
139 139 def validate(self, obj, value):
140 140 if value == '0': value = ''
141 141 value = value.replace('\\n','\n')
142 142 return super(SeparateUnicode, self).validate(obj, value)
143 143
144 144
145 145 class ReadlineNoRecord(object):
146 146 """Context manager to execute some code, then reload readline history
147 147 so that interactive input to the code doesn't appear when pressing up."""
148 148 def __init__(self, shell):
149 149 self.shell = shell
150 150 self._nested_level = 0
151 151
152 152 def __enter__(self):
153 153 if self._nested_level == 0:
154 154 try:
155 155 self.orig_length = self.current_length()
156 156 self.readline_tail = self.get_readline_tail()
157 157 except (AttributeError, IndexError): # Can fail with pyreadline
158 158 self.orig_length, self.readline_tail = 999999, []
159 159 self._nested_level += 1
160 160
161 161 def __exit__(self, type, value, traceback):
162 162 self._nested_level -= 1
163 163 if self._nested_level == 0:
164 164 # Try clipping the end if it's got longer
165 165 try:
166 166 e = self.current_length() - self.orig_length
167 167 if e > 0:
168 168 for _ in range(e):
169 169 self.shell.readline.remove_history_item(self.orig_length)
170 170
171 171 # If it still doesn't match, just reload readline history.
172 172 if self.current_length() != self.orig_length \
173 173 or self.get_readline_tail() != self.readline_tail:
174 174 self.shell.refill_readline_hist()
175 175 except (AttributeError, IndexError):
176 176 pass
177 177 # Returning False will cause exceptions to propagate
178 178 return False
179 179
180 180 def current_length(self):
181 181 return self.shell.readline.get_current_history_length()
182 182
183 183 def get_readline_tail(self, n=10):
184 184 """Get the last n items in readline history."""
185 185 end = self.shell.readline.get_current_history_length() + 1
186 186 start = max(end-n, 1)
187 187 ghi = self.shell.readline.get_history_item
188 188 return [ghi(x) for x in range(start, end)]
189 189
190 190
191 191 @undoc
192 192 class DummyMod(object):
193 193 """A dummy module used for IPython's interactive module when
194 194 a namespace must be assigned to the module's __dict__."""
195 195 pass
196 196
197 197 #-----------------------------------------------------------------------------
198 198 # Main IPython class
199 199 #-----------------------------------------------------------------------------
200 200
201 201 class InteractiveShell(SingletonConfigurable):
202 202 """An enhanced, interactive shell for Python."""
203 203
204 204 _instance = None
205 205
206 206 ast_transformers = List([], config=True, help=
207 207 """
208 208 A list of ast.NodeTransformer subclass instances, which will be applied
209 209 to user input before code is run.
210 210 """
211 211 )
212 212
213 213 autocall = Enum((0,1,2), default_value=0, config=True, help=
214 214 """
215 215 Make IPython automatically call any callable object even if you didn't
216 216 type explicit parentheses. For example, 'str 43' becomes 'str(43)'
217 217 automatically. The value can be '0' to disable the feature, '1' for
218 218 'smart' autocall, where it is not applied if there are no more
219 219 arguments on the line, and '2' for 'full' autocall, where all callable
220 220 objects are automatically called (even if no arguments are present).
221 221 """
222 222 )
223 223 # TODO: remove all autoindent logic and put into frontends.
224 224 # We can't do this yet because even runlines uses the autoindent.
225 225 autoindent = CBool(True, config=True, help=
226 226 """
227 227 Autoindent IPython code entered interactively.
228 228 """
229 229 )
230 230 automagic = CBool(True, config=True, help=
231 231 """
232 232 Enable magic commands to be called without the leading %.
233 233 """
234 234 )
235 235 cache_size = Integer(1000, config=True, help=
236 236 """
237 237 Set the size of the output cache. The default is 1000, you can
238 238 change it permanently in your config file. Setting it to 0 completely
239 239 disables the caching system, and the minimum value accepted is 20 (if
240 240 you provide a value less than 20, it is reset to 0 and a warning is
241 241 issued). This limit is defined because otherwise you'll spend more
242 242 time re-flushing a too small cache than working
243 243 """
244 244 )
245 245 color_info = CBool(True, config=True, help=
246 246 """
247 247 Use colors for displaying information about objects. Because this
248 248 information is passed through a pager (like 'less'), and some pagers
249 249 get confused with color codes, this capability can be turned off.
250 250 """
251 251 )
252 252 colors = CaselessStrEnum(('NoColor','LightBG','Linux'),
253 253 default_value=get_default_colors(), config=True,
254 254 help="Set the color scheme (NoColor, Linux, or LightBG)."
255 255 )
256 256 colors_force = CBool(False, help=
257 257 """
258 258 Force use of ANSI color codes, regardless of OS and readline
259 259 availability.
260 260 """
261 261 # FIXME: This is essentially a hack to allow ZMQShell to show colors
262 262 # without readline on Win32. When the ZMQ formatting system is
263 263 # refactored, this should be removed.
264 264 )
265 265 debug = CBool(False, config=True)
266 266 deep_reload = CBool(False, config=True, help=
267 267 """
268 268 Enable deep (recursive) reloading by default. IPython can use the
269 269 deep_reload module which reloads changes in modules recursively (it
270 270 replaces the reload() function, so you don't need to change anything to
271 271 use it). deep_reload() forces a full reload of modules whose code may
272 272 have changed, which the default reload() function does not. When
273 273 deep_reload is off, IPython will use the normal reload(), but
274 274 deep_reload will still be available as dreload().
275 275 """
276 276 )
277 277 disable_failing_post_execute = CBool(False, config=True,
278 278 help="Don't call post-execute functions that have failed in the past."
279 279 )
280 280 display_formatter = Instance(DisplayFormatter)
281 281 displayhook_class = Type(DisplayHook)
282 282 display_pub_class = Type(DisplayPublisher)
283 283 data_pub_class = None
284 284
285 285 exit_now = CBool(False)
286 286 exiter = Instance(ExitAutocall)
287 287 def _exiter_default(self):
288 288 return ExitAutocall(self)
289 289 # Monotonically increasing execution counter
290 290 execution_count = Integer(1)
291 291 filename = Unicode("<ipython console>")
292 292 ipython_dir= Unicode('', config=True) # Set to get_ipython_dir() in __init__
293 293
294 294 # Input splitter, to transform input line by line and detect when a block
295 295 # is ready to be executed.
296 296 input_splitter = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
297 297 (), {'line_input_checker': True})
298 298
299 299 # This InputSplitter instance is used to transform completed cells before
300 300 # running them. It allows cell magics to contain blank lines.
301 301 input_transformer_manager = Instance('IPython.core.inputsplitter.IPythonInputSplitter',
302 302 (), {'line_input_checker': False})
303 303
304 304 logstart = CBool(False, config=True, help=
305 305 """
306 306 Start logging to the default log file.
307 307 """
308 308 )
309 309 logfile = Unicode('', config=True, help=
310 310 """
311 311 The name of the logfile to use.
312 312 """
313 313 )
314 314 logappend = Unicode('', config=True, help=
315 315 """
316 316 Start logging to the given file in append mode.
317 317 """
318 318 )
319 319 object_info_string_level = Enum((0,1,2), default_value=0,
320 320 config=True)
321 321 pdb = CBool(False, config=True, help=
322 322 """
323 323 Automatically call the pdb debugger after every exception.
324 324 """
325 325 )
326 326 multiline_history = CBool(sys.platform != 'win32', config=True,
327 327 help="Save multi-line entries as one entry in readline history"
328 328 )
329 329
330 330 # deprecated prompt traits:
331 331
332 332 prompt_in1 = Unicode('In [\\#]: ', config=True,
333 333 help="Deprecated, use PromptManager.in_template")
334 334 prompt_in2 = Unicode(' .\\D.: ', config=True,
335 335 help="Deprecated, use PromptManager.in2_template")
336 336 prompt_out = Unicode('Out[\\#]: ', config=True,
337 337 help="Deprecated, use PromptManager.out_template")
338 338 prompts_pad_left = CBool(True, config=True,
339 339 help="Deprecated, use PromptManager.justify")
340 340
341 341 def _prompt_trait_changed(self, name, old, new):
342 342 table = {
343 343 'prompt_in1' : 'in_template',
344 344 'prompt_in2' : 'in2_template',
345 345 'prompt_out' : 'out_template',
346 346 'prompts_pad_left' : 'justify',
347 347 }
348 348 warn("InteractiveShell.{name} is deprecated, use PromptManager.{newname}".format(
349 349 name=name, newname=table[name])
350 350 )
351 351 # protect against weird cases where self.config may not exist:
352 352 if self.config is not None:
353 353 # propagate to corresponding PromptManager trait
354 354 setattr(self.config.PromptManager, table[name], new)
355 355
356 356 _prompt_in1_changed = _prompt_trait_changed
357 357 _prompt_in2_changed = _prompt_trait_changed
358 358 _prompt_out_changed = _prompt_trait_changed
359 359 _prompt_pad_left_changed = _prompt_trait_changed
360 360
361 361 show_rewritten_input = CBool(True, config=True,
362 362 help="Show rewritten input, e.g. for autocall."
363 363 )
364 364
365 365 quiet = CBool(False, config=True)
366 366
367 367 history_length = Integer(10000, config=True)
368 368
369 369 # The readline stuff will eventually be moved to the terminal subclass
370 370 # but for now, we can't do that as readline is welded in everywhere.
371 371 readline_use = CBool(True, config=True)
372 372 readline_remove_delims = Unicode('-/~', config=True)
373 373 readline_delims = Unicode() # set by init_readline()
374 374 # don't use \M- bindings by default, because they
375 375 # conflict with 8-bit encodings. See gh-58,gh-88
376 376 readline_parse_and_bind = List([
377 377 'tab: complete',
378 378 '"\C-l": clear-screen',
379 379 'set show-all-if-ambiguous on',
380 380 '"\C-o": tab-insert',
381 381 '"\C-r": reverse-search-history',
382 382 '"\C-s": forward-search-history',
383 383 '"\C-p": history-search-backward',
384 384 '"\C-n": history-search-forward',
385 385 '"\e[A": history-search-backward',
386 386 '"\e[B": history-search-forward',
387 387 '"\C-k": kill-line',
388 388 '"\C-u": unix-line-discard',
389 389 ], allow_none=False, config=True)
390 390
391 391 ast_node_interactivity = Enum(['all', 'last', 'last_expr', 'none'],
392 392 default_value='last_expr', config=True,
393 393 help="""
394 394 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
395 395 run interactively (displaying output from expressions).""")
396 396
397 397 # TODO: this part of prompt management should be moved to the frontends.
398 398 # Use custom TraitTypes that convert '0'->'' and '\\n'->'\n'
399 399 separate_in = SeparateUnicode('\n', config=True)
400 400 separate_out = SeparateUnicode('', config=True)
401 401 separate_out2 = SeparateUnicode('', config=True)
402 402 wildcards_case_sensitive = CBool(True, config=True)
403 403 xmode = CaselessStrEnum(('Context','Plain', 'Verbose'),
404 404 default_value='Context', config=True)
405 405
406 406 # Subcomponents of InteractiveShell
407 407 alias_manager = Instance('IPython.core.alias.AliasManager')
408 408 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
409 409 builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap')
410 410 display_trap = Instance('IPython.core.display_trap.DisplayTrap')
411 411 extension_manager = Instance('IPython.core.extensions.ExtensionManager')
412 412 payload_manager = Instance('IPython.core.payload.PayloadManager')
413 413 history_manager = Instance('IPython.core.history.HistoryManager')
414 414 magics_manager = Instance('IPython.core.magic.MagicsManager')
415 415
416 416 profile_dir = Instance('IPython.core.application.ProfileDir')
417 417 @property
418 418 def profile(self):
419 419 if self.profile_dir is not None:
420 420 name = os.path.basename(self.profile_dir.location)
421 421 return name.replace('profile_','')
422 422
423 423
424 424 # Private interface
425 425 _post_execute = Instance(dict)
426 426
427 427 # Tracks any GUI loop loaded for pylab
428 428 pylab_gui_select = None
429 429
430 430 def __init__(self, ipython_dir=None, profile_dir=None,
431 431 user_module=None, user_ns=None,
432 432 custom_exceptions=((), None), **kwargs):
433 433
434 434 # This is where traits with a config_key argument are updated
435 435 # from the values on config.
436 436 super(InteractiveShell, self).__init__(**kwargs)
437 437 self.configurables = [self]
438 438
439 439 # These are relatively independent and stateless
440 440 self.init_ipython_dir(ipython_dir)
441 441 self.init_profile_dir(profile_dir)
442 442 self.init_instance_attrs()
443 443 self.init_environment()
444 444
445 445 # Check if we're in a virtualenv, and set up sys.path.
446 446 self.init_virtualenv()
447 447
448 448 # Create namespaces (user_ns, user_global_ns, etc.)
449 449 self.init_create_namespaces(user_module, user_ns)
450 450 # This has to be done after init_create_namespaces because it uses
451 451 # something in self.user_ns, but before init_sys_modules, which
452 452 # is the first thing to modify sys.
453 453 # TODO: When we override sys.stdout and sys.stderr before this class
454 454 # is created, we are saving the overridden ones here. Not sure if this
455 455 # is what we want to do.
456 456 self.save_sys_module_state()
457 457 self.init_sys_modules()
458 458
459 459 # While we're trying to have each part of the code directly access what
460 460 # it needs without keeping redundant references to objects, we have too
461 461 # much legacy code that expects ip.db to exist.
462 462 self.db = PickleShareDB(os.path.join(self.profile_dir.location, 'db'))
463 463
464 464 self.init_history()
465 465 self.init_encoding()
466 466 self.init_prefilter()
467 467
468 468 self.init_syntax_highlighting()
469 469 self.init_hooks()
470 470 self.init_pushd_popd_magic()
471 471 # self.init_traceback_handlers use to be here, but we moved it below
472 472 # because it and init_io have to come after init_readline.
473 473 self.init_user_ns()
474 474 self.init_logger()
475 475 self.init_builtins()
476 476
477 477 # The following was in post_config_initialization
478 478 self.init_inspector()
479 479 # init_readline() must come before init_io(), because init_io uses
480 480 # readline related things.
481 481 self.init_readline()
482 482 # We save this here in case user code replaces raw_input, but it needs
483 483 # to be after init_readline(), because PyPy's readline works by replacing
484 484 # raw_input.
485 485 if py3compat.PY3:
486 486 self.raw_input_original = input
487 487 else:
488 488 self.raw_input_original = raw_input
489 489 # init_completer must come after init_readline, because it needs to
490 490 # know whether readline is present or not system-wide to configure the
491 491 # completers, since the completion machinery can now operate
492 492 # independently of readline (e.g. over the network)
493 493 self.init_completer()
494 494 # TODO: init_io() needs to happen before init_traceback handlers
495 495 # because the traceback handlers hardcode the stdout/stderr streams.
496 496 # This logic in in debugger.Pdb and should eventually be changed.
497 497 self.init_io()
498 498 self.init_traceback_handlers(custom_exceptions)
499 499 self.init_prompts()
500 500 self.init_display_formatter()
501 501 self.init_display_pub()
502 502 self.init_data_pub()
503 503 self.init_displayhook()
504 504 self.init_latextool()
505 505 self.init_magics()
506 506 self.init_alias()
507 507 self.init_logstart()
508 508 self.init_pdb()
509 509 self.init_extension_manager()
510 510 self.init_payload()
511 511 self.init_comms()
512 512 self.hooks.late_startup_hook()
513 513 atexit.register(self.atexit_operations)
514 514
515 515 def get_ipython(self):
516 516 """Return the currently running IPython instance."""
517 517 return self
518 518
519 519 #-------------------------------------------------------------------------
520 520 # Trait changed handlers
521 521 #-------------------------------------------------------------------------
522 522
523 523 def _ipython_dir_changed(self, name, new):
524 524 if not os.path.isdir(new):
525 525 os.makedirs(new, mode = 0o777)
526 526
527 527 def set_autoindent(self,value=None):
528 528 """Set the autoindent flag, checking for readline support.
529 529
530 530 If called with no arguments, it acts as a toggle."""
531 531
532 532 if value != 0 and not self.has_readline:
533 533 if os.name == 'posix':
534 534 warn("The auto-indent feature requires the readline library")
535 535 self.autoindent = 0
536 536 return
537 537 if value is None:
538 538 self.autoindent = not self.autoindent
539 539 else:
540 540 self.autoindent = value
541 541
542 542 #-------------------------------------------------------------------------
543 543 # init_* methods called by __init__
544 544 #-------------------------------------------------------------------------
545 545
546 546 def init_ipython_dir(self, ipython_dir):
547 547 if ipython_dir is not None:
548 548 self.ipython_dir = ipython_dir
549 549 return
550 550
551 551 self.ipython_dir = get_ipython_dir()
552 552
553 553 def init_profile_dir(self, profile_dir):
554 554 if profile_dir is not None:
555 555 self.profile_dir = profile_dir
556 556 return
557 557 self.profile_dir =\
558 558 ProfileDir.create_profile_dir_by_name(self.ipython_dir, 'default')
559 559
560 560 def init_instance_attrs(self):
561 561 self.more = False
562 562
563 563 # command compiler
564 564 self.compile = CachingCompiler()
565 565
566 566 # Make an empty namespace, which extension writers can rely on both
567 567 # existing and NEVER being used by ipython itself. This gives them a
568 568 # convenient location for storing additional information and state
569 569 # their extensions may require, without fear of collisions with other
570 570 # ipython names that may develop later.
571 571 self.meta = Struct()
572 572
573 573 # Temporary files used for various purposes. Deleted at exit.
574 574 self.tempfiles = []
575 575 self.tempdirs = []
576 576
577 577 # Keep track of readline usage (later set by init_readline)
578 578 self.has_readline = False
579 579
580 580 # keep track of where we started running (mainly for crash post-mortem)
581 581 # This is not being used anywhere currently.
582 582 self.starting_dir = py3compat.getcwd()
583 583
584 584 # Indentation management
585 585 self.indent_current_nsp = 0
586 586
587 587 # Dict to track post-execution functions that have been registered
588 588 self._post_execute = {}
589 589
590 590 def init_environment(self):
591 591 """Any changes we need to make to the user's environment."""
592 592 pass
593 593
594 594 def init_encoding(self):
595 595 # Get system encoding at startup time. Certain terminals (like Emacs
596 596 # under Win32 have it set to None, and we need to have a known valid
597 597 # encoding to use in the raw_input() method
598 598 try:
599 599 self.stdin_encoding = sys.stdin.encoding or 'ascii'
600 600 except AttributeError:
601 601 self.stdin_encoding = 'ascii'
602 602
603 603 def init_syntax_highlighting(self):
604 604 # Python source parser/formatter for syntax highlighting
605 605 pyformat = PyColorize.Parser().format
606 606 self.pycolorize = lambda src: pyformat(src,'str',self.colors)
607 607
608 608 def init_pushd_popd_magic(self):
609 609 # for pushd/popd management
610 610 self.home_dir = get_home_dir()
611 611
612 612 self.dir_stack = []
613 613
614 614 def init_logger(self):
615 615 self.logger = Logger(self.home_dir, logfname='ipython_log.py',
616 616 logmode='rotate')
617 617
618 618 def init_logstart(self):
619 619 """Initialize logging in case it was requested at the command line.
620 620 """
621 621 if self.logappend:
622 622 self.magic('logstart %s append' % self.logappend)
623 623 elif self.logfile:
624 624 self.magic('logstart %s' % self.logfile)
625 625 elif self.logstart:
626 626 self.magic('logstart')
627 627
628 628 def init_builtins(self):
629 629 # A single, static flag that we set to True. Its presence indicates
630 630 # that an IPython shell has been created, and we make no attempts at
631 631 # removing on exit or representing the existence of more than one
632 632 # IPython at a time.
633 633 builtin_mod.__dict__['__IPYTHON__'] = True
634 634
635 635 # In 0.11 we introduced '__IPYTHON__active' as an integer we'd try to
636 636 # manage on enter/exit, but with all our shells it's virtually
637 637 # impossible to get all the cases right. We're leaving the name in for
638 638 # those who adapted their codes to check for this flag, but will
639 639 # eventually remove it after a few more releases.
640 640 builtin_mod.__dict__['__IPYTHON__active'] = \
641 641 'Deprecated, check for __IPYTHON__'
642 642
643 643 self.builtin_trap = BuiltinTrap(shell=self)
644 644
645 645 def init_inspector(self):
646 646 # Object inspector
647 647 self.inspector = oinspect.Inspector(oinspect.InspectColors,
648 648 PyColorize.ANSICodeColors,
649 649 'NoColor',
650 650 self.object_info_string_level)
651 651
652 652 def init_io(self):
653 653 # This will just use sys.stdout and sys.stderr. If you want to
654 654 # override sys.stdout and sys.stderr themselves, you need to do that
655 655 # *before* instantiating this class, because io holds onto
656 656 # references to the underlying streams.
657 657 if (sys.platform == 'win32' or sys.platform == 'cli') and self.has_readline:
658 658 io.stdout = io.stderr = io.IOStream(self.readline._outputfile)
659 659 else:
660 660 io.stdout = io.IOStream(sys.stdout)
661 661 io.stderr = io.IOStream(sys.stderr)
662 662
663 663 def init_prompts(self):
664 664 self.prompt_manager = PromptManager(shell=self, parent=self)
665 665 self.configurables.append(self.prompt_manager)
666 666 # Set system prompts, so that scripts can decide if they are running
667 667 # interactively.
668 668 sys.ps1 = 'In : '
669 669 sys.ps2 = '...: '
670 670 sys.ps3 = 'Out: '
671 671
672 672 def init_display_formatter(self):
673 673 self.display_formatter = DisplayFormatter(parent=self)
674 674 self.configurables.append(self.display_formatter)
675 675
676 676 def init_display_pub(self):
677 677 self.display_pub = self.display_pub_class(parent=self)
678 678 self.configurables.append(self.display_pub)
679 679
680 680 def init_data_pub(self):
681 681 if not self.data_pub_class:
682 682 self.data_pub = None
683 683 return
684 684 self.data_pub = self.data_pub_class(parent=self)
685 685 self.configurables.append(self.data_pub)
686 686
687 687 def init_displayhook(self):
688 688 # Initialize displayhook, set in/out prompts and printing system
689 689 self.displayhook = self.displayhook_class(
690 690 parent=self,
691 691 shell=self,
692 692 cache_size=self.cache_size,
693 693 )
694 694 self.configurables.append(self.displayhook)
695 695 # This is a context manager that installs/revmoes the displayhook at
696 696 # the appropriate time.
697 697 self.display_trap = DisplayTrap(hook=self.displayhook)
698 698
699 699 def init_latextool(self):
700 700 """Configure LaTeXTool."""
701 701 cfg = LaTeXTool.instance(parent=self)
702 702 if cfg not in self.configurables:
703 703 self.configurables.append(cfg)
704 704
705 705 def init_virtualenv(self):
706 706 """Add a virtualenv to sys.path so the user can import modules from it.
707 707 This isn't perfect: it doesn't use the Python interpreter with which the
708 708 virtualenv was built, and it ignores the --no-site-packages option. A
709 709 warning will appear suggesting the user installs IPython in the
710 710 virtualenv, but for many cases, it probably works well enough.
711 711
712 712 Adapted from code snippets online.
713 713
714 714 http://blog.ufsoft.org/2009/1/29/ipython-and-virtualenv
715 715 """
716 716 if 'VIRTUAL_ENV' not in os.environ:
717 717 # Not in a virtualenv
718 718 return
719 719
720 720 # venv detection:
721 721 # stdlib venv may symlink sys.executable, so we can't use realpath.
722 722 # but others can symlink *to* the venv Python, so we can't just use sys.executable.
723 723 # So we just check every item in the symlink tree (generally <= 3)
724 724 p = sys.executable
725 725 paths = [p]
726 726 while os.path.islink(p):
727 727 p = os.path.join(os.path.dirname(p), os.readlink(p))
728 728 paths.append(p)
729 729 if any(p.startswith(os.environ['VIRTUAL_ENV']) for p in paths):
730 730 # Running properly in the virtualenv, don't need to do anything
731 731 return
732 732
733 733 warn("Attempting to work in a virtualenv. If you encounter problems, please "
734 734 "install IPython inside the virtualenv.")
735 735 if sys.platform == "win32":
736 736 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'Lib', 'site-packages')
737 737 else:
738 738 virtual_env = os.path.join(os.environ['VIRTUAL_ENV'], 'lib',
739 739 'python%d.%d' % sys.version_info[:2], 'site-packages')
740 740
741 741 import site
742 742 sys.path.insert(0, virtual_env)
743 743 site.addsitedir(virtual_env)
744 744
745 745 #-------------------------------------------------------------------------
746 746 # Things related to injections into the sys module
747 747 #-------------------------------------------------------------------------
748 748
749 749 def save_sys_module_state(self):
750 750 """Save the state of hooks in the sys module.
751 751
752 752 This has to be called after self.user_module is created.
753 753 """
754 754 self._orig_sys_module_state = {}
755 755 self._orig_sys_module_state['stdin'] = sys.stdin
756 756 self._orig_sys_module_state['stdout'] = sys.stdout
757 757 self._orig_sys_module_state['stderr'] = sys.stderr
758 758 self._orig_sys_module_state['excepthook'] = sys.excepthook
759 759 self._orig_sys_modules_main_name = self.user_module.__name__
760 760 self._orig_sys_modules_main_mod = sys.modules.get(self.user_module.__name__)
761 761
762 762 def restore_sys_module_state(self):
763 763 """Restore the state of the sys module."""
764 764 try:
765 765 for k, v in iteritems(self._orig_sys_module_state):
766 766 setattr(sys, k, v)
767 767 except AttributeError:
768 768 pass
769 769 # Reset what what done in self.init_sys_modules
770 770 if self._orig_sys_modules_main_mod is not None:
771 771 sys.modules[self._orig_sys_modules_main_name] = self._orig_sys_modules_main_mod
772 772
773 773 #-------------------------------------------------------------------------
774 774 # Things related to hooks
775 775 #-------------------------------------------------------------------------
776 776
777 777 def init_hooks(self):
778 778 # hooks holds pointers used for user-side customizations
779 779 self.hooks = Struct()
780 780
781 781 self.strdispatchers = {}
782 782
783 783 # Set all default hooks, defined in the IPython.hooks module.
784 784 hooks = IPython.core.hooks
785 785 for hook_name in hooks.__all__:
786 786 # default hooks have priority 100, i.e. low; user hooks should have
787 787 # 0-100 priority
788 788 self.set_hook(hook_name,getattr(hooks,hook_name), 100)
789 789
790 790 def set_hook(self,name,hook, priority = 50, str_key = None, re_key = None):
791 791 """set_hook(name,hook) -> sets an internal IPython hook.
792 792
793 793 IPython exposes some of its internal API as user-modifiable hooks. By
794 794 adding your function to one of these hooks, you can modify IPython's
795 795 behavior to call at runtime your own routines."""
796 796
797 797 # At some point in the future, this should validate the hook before it
798 798 # accepts it. Probably at least check that the hook takes the number
799 799 # of args it's supposed to.
800 800
801 801 f = types.MethodType(hook,self)
802 802
803 803 # check if the hook is for strdispatcher first
804 804 if str_key is not None:
805 805 sdp = self.strdispatchers.get(name, StrDispatch())
806 806 sdp.add_s(str_key, f, priority )
807 807 self.strdispatchers[name] = sdp
808 808 return
809 809 if re_key is not None:
810 810 sdp = self.strdispatchers.get(name, StrDispatch())
811 811 sdp.add_re(re.compile(re_key), f, priority )
812 812 self.strdispatchers[name] = sdp
813 813 return
814 814
815 815 dp = getattr(self.hooks, name, None)
816 816 if name not in IPython.core.hooks.__all__:
817 817 print("Warning! Hook '%s' is not one of %s" % \
818 818 (name, IPython.core.hooks.__all__ ))
819 819 if not dp:
820 820 dp = IPython.core.hooks.CommandChainDispatcher()
821 821
822 822 try:
823 823 dp.add(f,priority)
824 824 except AttributeError:
825 825 # it was not commandchain, plain old func - replace
826 826 dp = f
827 827
828 828 setattr(self.hooks,name, dp)
829 829
830 830 def register_post_execute(self, func):
831 831 """Register a function for calling after code execution.
832 832 """
833 833 if not callable(func):
834 834 raise ValueError('argument %s must be callable' % func)
835 835 self._post_execute[func] = True
836 836
837 837 #-------------------------------------------------------------------------
838 838 # Things related to the "main" module
839 839 #-------------------------------------------------------------------------
840 840
841 841 def new_main_mod(self, filename, modname):
842 842 """Return a new 'main' module object for user code execution.
843 843
844 844 ``filename`` should be the path of the script which will be run in the
845 845 module. Requests with the same filename will get the same module, with
846 846 its namespace cleared.
847 847
848 848 ``modname`` should be the module name - normally either '__main__' or
849 849 the basename of the file without the extension.
850 850
851 851 When scripts are executed via %run, we must keep a reference to their
852 852 __main__ module around so that Python doesn't
853 853 clear it, rendering references to module globals useless.
854 854
855 855 This method keeps said reference in a private dict, keyed by the
856 856 absolute path of the script. This way, for multiple executions of the
857 857 same script we only keep one copy of the namespace (the last one),
858 858 thus preventing memory leaks from old references while allowing the
859 859 objects from the last execution to be accessible.
860 860 """
861 861 filename = os.path.abspath(filename)
862 862 try:
863 863 main_mod = self._main_mod_cache[filename]
864 864 except KeyError:
865 865 main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
866 866 doc="Module created for script run in IPython")
867 867 else:
868 868 main_mod.__dict__.clear()
869 869 main_mod.__name__ = modname
870 870
871 871 main_mod.__file__ = filename
872 872 # It seems pydoc (and perhaps others) needs any module instance to
873 873 # implement a __nonzero__ method
874 874 main_mod.__nonzero__ = lambda : True
875 875
876 876 return main_mod
877 877
878 878 def clear_main_mod_cache(self):
879 879 """Clear the cache of main modules.
880 880
881 881 Mainly for use by utilities like %reset.
882 882
883 883 Examples
884 884 --------
885 885
886 886 In [15]: import IPython
887 887
888 888 In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
889 889
890 890 In [17]: len(_ip._main_mod_cache) > 0
891 891 Out[17]: True
892 892
893 893 In [18]: _ip.clear_main_mod_cache()
894 894
895 895 In [19]: len(_ip._main_mod_cache) == 0
896 896 Out[19]: True
897 897 """
898 898 self._main_mod_cache.clear()
899 899
900 900 #-------------------------------------------------------------------------
901 901 # Things related to debugging
902 902 #-------------------------------------------------------------------------
903 903
904 904 def init_pdb(self):
905 905 # Set calling of pdb on exceptions
906 906 # self.call_pdb is a property
907 907 self.call_pdb = self.pdb
908 908
909 909 def _get_call_pdb(self):
910 910 return self._call_pdb
911 911
912 912 def _set_call_pdb(self,val):
913 913
914 914 if val not in (0,1,False,True):
915 915 raise ValueError('new call_pdb value must be boolean')
916 916
917 917 # store value in instance
918 918 self._call_pdb = val
919 919
920 920 # notify the actual exception handlers
921 921 self.InteractiveTB.call_pdb = val
922 922
923 923 call_pdb = property(_get_call_pdb,_set_call_pdb,None,
924 924 'Control auto-activation of pdb at exceptions')
925 925
926 926 def debugger(self,force=False):
927 927 """Call the pydb/pdb debugger.
928 928
929 929 Keywords:
930 930
931 931 - force(False): by default, this routine checks the instance call_pdb
932 932 flag and does not actually invoke the debugger if the flag is false.
933 933 The 'force' option forces the debugger to activate even if the flag
934 934 is false.
935 935 """
936 936
937 937 if not (force or self.call_pdb):
938 938 return
939 939
940 940 if not hasattr(sys,'last_traceback'):
941 941 error('No traceback has been produced, nothing to debug.')
942 942 return
943 943
944 944 # use pydb if available
945 945 if debugger.has_pydb:
946 946 from pydb import pm
947 947 else:
948 948 # fallback to our internal debugger
949 949 pm = lambda : self.InteractiveTB.debugger(force=True)
950 950
951 951 with self.readline_no_record:
952 952 pm()
953 953
954 954 #-------------------------------------------------------------------------
955 955 # Things related to IPython's various namespaces
956 956 #-------------------------------------------------------------------------
957 957 default_user_namespaces = True
958 958
959 959 def init_create_namespaces(self, user_module=None, user_ns=None):
960 960 # Create the namespace where the user will operate. user_ns is
961 961 # normally the only one used, and it is passed to the exec calls as
962 962 # the locals argument. But we do carry a user_global_ns namespace
963 963 # given as the exec 'globals' argument, This is useful in embedding
964 964 # situations where the ipython shell opens in a context where the
965 965 # distinction between locals and globals is meaningful. For
966 966 # non-embedded contexts, it is just the same object as the user_ns dict.
967 967
968 968 # FIXME. For some strange reason, __builtins__ is showing up at user
969 969 # level as a dict instead of a module. This is a manual fix, but I
970 970 # should really track down where the problem is coming from. Alex
971 971 # Schmolck reported this problem first.
972 972
973 973 # A useful post by Alex Martelli on this topic:
974 974 # Re: inconsistent value from __builtins__
975 975 # Von: Alex Martelli <aleaxit@yahoo.com>
976 976 # Datum: Freitag 01 Oktober 2004 04:45:34 nachmittags/abends
977 977 # Gruppen: comp.lang.python
978 978
979 979 # Michael Hohn <hohn@hooknose.lbl.gov> wrote:
980 980 # > >>> print type(builtin_check.get_global_binding('__builtins__'))
981 981 # > <type 'dict'>
982 982 # > >>> print type(__builtins__)
983 983 # > <type 'module'>
984 984 # > Is this difference in return value intentional?
985 985
986 986 # Well, it's documented that '__builtins__' can be either a dictionary
987 987 # or a module, and it's been that way for a long time. Whether it's
988 988 # intentional (or sensible), I don't know. In any case, the idea is
989 989 # that if you need to access the built-in namespace directly, you
990 990 # should start with "import __builtin__" (note, no 's') which will
991 991 # definitely give you a module. Yeah, it's somewhat confusing:-(.
992 992
993 993 # These routines return a properly built module and dict as needed by
994 994 # the rest of the code, and can also be used by extension writers to
995 995 # generate properly initialized namespaces.
996 996 if (user_ns is not None) or (user_module is not None):
997 997 self.default_user_namespaces = False
998 998 self.user_module, self.user_ns = self.prepare_user_module(user_module, user_ns)
999 999
1000 1000 # A record of hidden variables we have added to the user namespace, so
1001 1001 # we can list later only variables defined in actual interactive use.
1002 1002 self.user_ns_hidden = {}
1003 1003
1004 1004 # Now that FakeModule produces a real module, we've run into a nasty
1005 1005 # problem: after script execution (via %run), the module where the user
1006 1006 # code ran is deleted. Now that this object is a true module (needed
1007 1007 # so docetst and other tools work correctly), the Python module
1008 1008 # teardown mechanism runs over it, and sets to None every variable
1009 1009 # present in that module. Top-level references to objects from the
1010 1010 # script survive, because the user_ns is updated with them. However,
1011 1011 # calling functions defined in the script that use other things from
1012 1012 # the script will fail, because the function's closure had references
1013 1013 # to the original objects, which are now all None. So we must protect
1014 1014 # these modules from deletion by keeping a cache.
1015 1015 #
1016 1016 # To avoid keeping stale modules around (we only need the one from the
1017 1017 # last run), we use a dict keyed with the full path to the script, so
1018 1018 # only the last version of the module is held in the cache. Note,
1019 1019 # however, that we must cache the module *namespace contents* (their
1020 1020 # __dict__). Because if we try to cache the actual modules, old ones
1021 1021 # (uncached) could be destroyed while still holding references (such as
1022 1022 # those held by GUI objects that tend to be long-lived)>
1023 1023 #
1024 1024 # The %reset command will flush this cache. See the cache_main_mod()
1025 1025 # and clear_main_mod_cache() methods for details on use.
1026 1026
1027 1027 # This is the cache used for 'main' namespaces
1028 1028 self._main_mod_cache = {}
1029 1029
1030 1030 # A table holding all the namespaces IPython deals with, so that
1031 1031 # introspection facilities can search easily.
1032 1032 self.ns_table = {'user_global':self.user_module.__dict__,
1033 1033 'user_local':self.user_ns,
1034 1034 'builtin':builtin_mod.__dict__
1035 1035 }
1036 1036
1037 1037 @property
1038 1038 def user_global_ns(self):
1039 1039 return self.user_module.__dict__
1040 1040
1041 1041 def prepare_user_module(self, user_module=None, user_ns=None):
1042 1042 """Prepare the module and namespace in which user code will be run.
1043 1043
1044 1044 When IPython is started normally, both parameters are None: a new module
1045 1045 is created automatically, and its __dict__ used as the namespace.
1046 1046
1047 1047 If only user_module is provided, its __dict__ is used as the namespace.
1048 1048 If only user_ns is provided, a dummy module is created, and user_ns
1049 1049 becomes the global namespace. If both are provided (as they may be
1050 1050 when embedding), user_ns is the local namespace, and user_module
1051 1051 provides the global namespace.
1052 1052
1053 1053 Parameters
1054 1054 ----------
1055 1055 user_module : module, optional
1056 1056 The current user module in which IPython is being run. If None,
1057 1057 a clean module will be created.
1058 1058 user_ns : dict, optional
1059 1059 A namespace in which to run interactive commands.
1060 1060
1061 1061 Returns
1062 1062 -------
1063 1063 A tuple of user_module and user_ns, each properly initialised.
1064 1064 """
1065 1065 if user_module is None and user_ns is not None:
1066 1066 user_ns.setdefault("__name__", "__main__")
1067 1067 user_module = DummyMod()
1068 1068 user_module.__dict__ = user_ns
1069 1069
1070 1070 if user_module is None:
1071 1071 user_module = types.ModuleType("__main__",
1072 1072 doc="Automatically created module for IPython interactive environment")
1073 1073
1074 1074 # We must ensure that __builtin__ (without the final 's') is always
1075 1075 # available and pointing to the __builtin__ *module*. For more details:
1076 1076 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1077 1077 user_module.__dict__.setdefault('__builtin__', builtin_mod)
1078 1078 user_module.__dict__.setdefault('__builtins__', builtin_mod)
1079 1079
1080 1080 if user_ns is None:
1081 1081 user_ns = user_module.__dict__
1082 1082
1083 1083 return user_module, user_ns
1084 1084
1085 1085 def init_sys_modules(self):
1086 1086 # We need to insert into sys.modules something that looks like a
1087 1087 # module but which accesses the IPython namespace, for shelve and
1088 1088 # pickle to work interactively. Normally they rely on getting
1089 1089 # everything out of __main__, but for embedding purposes each IPython
1090 1090 # instance has its own private namespace, so we can't go shoving
1091 1091 # everything into __main__.
1092 1092
1093 1093 # note, however, that we should only do this for non-embedded
1094 1094 # ipythons, which really mimic the __main__.__dict__ with their own
1095 1095 # namespace. Embedded instances, on the other hand, should not do
1096 1096 # this because they need to manage the user local/global namespaces
1097 1097 # only, but they live within a 'normal' __main__ (meaning, they
1098 1098 # shouldn't overtake the execution environment of the script they're
1099 1099 # embedded in).
1100 1100
1101 1101 # This is overridden in the InteractiveShellEmbed subclass to a no-op.
1102 1102 main_name = self.user_module.__name__
1103 1103 sys.modules[main_name] = self.user_module
1104 1104
1105 1105 def init_user_ns(self):
1106 1106 """Initialize all user-visible namespaces to their minimum defaults.
1107 1107
1108 1108 Certain history lists are also initialized here, as they effectively
1109 1109 act as user namespaces.
1110 1110
1111 1111 Notes
1112 1112 -----
1113 1113 All data structures here are only filled in, they are NOT reset by this
1114 1114 method. If they were not empty before, data will simply be added to
1115 1115 therm.
1116 1116 """
1117 1117 # This function works in two parts: first we put a few things in
1118 1118 # user_ns, and we sync that contents into user_ns_hidden so that these
1119 1119 # initial variables aren't shown by %who. After the sync, we add the
1120 1120 # rest of what we *do* want the user to see with %who even on a new
1121 1121 # session (probably nothing, so theye really only see their own stuff)
1122 1122
1123 1123 # The user dict must *always* have a __builtin__ reference to the
1124 1124 # Python standard __builtin__ namespace, which must be imported.
1125 1125 # This is so that certain operations in prompt evaluation can be
1126 1126 # reliably executed with builtins. Note that we can NOT use
1127 1127 # __builtins__ (note the 's'), because that can either be a dict or a
1128 1128 # module, and can even mutate at runtime, depending on the context
1129 1129 # (Python makes no guarantees on it). In contrast, __builtin__ is
1130 1130 # always a module object, though it must be explicitly imported.
1131 1131
1132 1132 # For more details:
1133 1133 # http://mail.python.org/pipermail/python-dev/2001-April/014068.html
1134 1134 ns = dict()
1135 1135
1136 1136 # make global variables for user access to the histories
1137 1137 ns['_ih'] = self.history_manager.input_hist_parsed
1138 1138 ns['_oh'] = self.history_manager.output_hist
1139 1139 ns['_dh'] = self.history_manager.dir_hist
1140 1140
1141 1141 ns['_sh'] = shadowns
1142 1142
1143 1143 # user aliases to input and output histories. These shouldn't show up
1144 1144 # in %who, as they can have very large reprs.
1145 1145 ns['In'] = self.history_manager.input_hist_parsed
1146 1146 ns['Out'] = self.history_manager.output_hist
1147 1147
1148 1148 # Store myself as the public api!!!
1149 1149 ns['get_ipython'] = self.get_ipython
1150 1150
1151 1151 ns['exit'] = self.exiter
1152 1152 ns['quit'] = self.exiter
1153 1153
1154 1154 # Sync what we've added so far to user_ns_hidden so these aren't seen
1155 1155 # by %who
1156 1156 self.user_ns_hidden.update(ns)
1157 1157
1158 1158 # Anything put into ns now would show up in %who. Think twice before
1159 1159 # putting anything here, as we really want %who to show the user their
1160 1160 # stuff, not our variables.
1161 1161
1162 1162 # Finally, update the real user's namespace
1163 1163 self.user_ns.update(ns)
1164 1164
1165 1165 @property
1166 1166 def all_ns_refs(self):
1167 1167 """Get a list of references to all the namespace dictionaries in which
1168 1168 IPython might store a user-created object.
1169 1169
1170 1170 Note that this does not include the displayhook, which also caches
1171 1171 objects from the output."""
1172 1172 return [self.user_ns, self.user_global_ns, self.user_ns_hidden] + \
1173 1173 [m.__dict__ for m in self._main_mod_cache.values()]
1174 1174
1175 1175 def reset(self, new_session=True):
1176 1176 """Clear all internal namespaces, and attempt to release references to
1177 1177 user objects.
1178 1178
1179 1179 If new_session is True, a new history session will be opened.
1180 1180 """
1181 1181 # Clear histories
1182 1182 self.history_manager.reset(new_session)
1183 1183 # Reset counter used to index all histories
1184 1184 if new_session:
1185 1185 self.execution_count = 1
1186 1186
1187 1187 # Flush cached output items
1188 1188 if self.displayhook.do_full_cache:
1189 1189 self.displayhook.flush()
1190 1190
1191 1191 # The main execution namespaces must be cleared very carefully,
1192 1192 # skipping the deletion of the builtin-related keys, because doing so
1193 1193 # would cause errors in many object's __del__ methods.
1194 1194 if self.user_ns is not self.user_global_ns:
1195 1195 self.user_ns.clear()
1196 1196 ns = self.user_global_ns
1197 1197 drop_keys = set(ns.keys())
1198 1198 drop_keys.discard('__builtin__')
1199 1199 drop_keys.discard('__builtins__')
1200 1200 drop_keys.discard('__name__')
1201 1201 for k in drop_keys:
1202 1202 del ns[k]
1203 1203
1204 1204 self.user_ns_hidden.clear()
1205 1205
1206 1206 # Restore the user namespaces to minimal usability
1207 1207 self.init_user_ns()
1208 1208
1209 1209 # Restore the default and user aliases
1210 1210 self.alias_manager.clear_aliases()
1211 1211 self.alias_manager.init_aliases()
1212 1212
1213 1213 # Flush the private list of module references kept for script
1214 1214 # execution protection
1215 1215 self.clear_main_mod_cache()
1216 1216
1217 1217 def del_var(self, varname, by_name=False):
1218 1218 """Delete a variable from the various namespaces, so that, as
1219 1219 far as possible, we're not keeping any hidden references to it.
1220 1220
1221 1221 Parameters
1222 1222 ----------
1223 1223 varname : str
1224 1224 The name of the variable to delete.
1225 1225 by_name : bool
1226 1226 If True, delete variables with the given name in each
1227 1227 namespace. If False (default), find the variable in the user
1228 1228 namespace, and delete references to it.
1229 1229 """
1230 1230 if varname in ('__builtin__', '__builtins__'):
1231 1231 raise ValueError("Refusing to delete %s" % varname)
1232 1232
1233 1233 ns_refs = self.all_ns_refs
1234 1234
1235 1235 if by_name: # Delete by name
1236 1236 for ns in ns_refs:
1237 1237 try:
1238 1238 del ns[varname]
1239 1239 except KeyError:
1240 1240 pass
1241 1241 else: # Delete by object
1242 1242 try:
1243 1243 obj = self.user_ns[varname]
1244 1244 except KeyError:
1245 1245 raise NameError("name '%s' is not defined" % varname)
1246 1246 # Also check in output history
1247 1247 ns_refs.append(self.history_manager.output_hist)
1248 1248 for ns in ns_refs:
1249 1249 to_delete = [n for n, o in iteritems(ns) if o is obj]
1250 1250 for name in to_delete:
1251 1251 del ns[name]
1252 1252
1253 1253 # displayhook keeps extra references, but not in a dictionary
1254 1254 for name in ('_', '__', '___'):
1255 1255 if getattr(self.displayhook, name) is obj:
1256 1256 setattr(self.displayhook, name, None)
1257 1257
1258 1258 def reset_selective(self, regex=None):
1259 1259 """Clear selective variables from internal namespaces based on a
1260 1260 specified regular expression.
1261 1261
1262 1262 Parameters
1263 1263 ----------
1264 1264 regex : string or compiled pattern, optional
1265 1265 A regular expression pattern that will be used in searching
1266 1266 variable names in the users namespaces.
1267 1267 """
1268 1268 if regex is not None:
1269 1269 try:
1270 1270 m = re.compile(regex)
1271 1271 except TypeError:
1272 1272 raise TypeError('regex must be a string or compiled pattern')
1273 1273 # Search for keys in each namespace that match the given regex
1274 1274 # If a match is found, delete the key/value pair.
1275 1275 for ns in self.all_ns_refs:
1276 1276 for var in ns:
1277 1277 if m.search(var):
1278 1278 del ns[var]
1279 1279
1280 1280 def push(self, variables, interactive=True):
1281 1281 """Inject a group of variables into the IPython user namespace.
1282 1282
1283 1283 Parameters
1284 1284 ----------
1285 1285 variables : dict, str or list/tuple of str
1286 1286 The variables to inject into the user's namespace. If a dict, a
1287 1287 simple update is done. If a str, the string is assumed to have
1288 1288 variable names separated by spaces. A list/tuple of str can also
1289 1289 be used to give the variable names. If just the variable names are
1290 1290 give (list/tuple/str) then the variable values looked up in the
1291 1291 callers frame.
1292 1292 interactive : bool
1293 1293 If True (default), the variables will be listed with the ``who``
1294 1294 magic.
1295 1295 """
1296 1296 vdict = None
1297 1297
1298 1298 # We need a dict of name/value pairs to do namespace updates.
1299 1299 if isinstance(variables, dict):
1300 1300 vdict = variables
1301 1301 elif isinstance(variables, string_types+(list, tuple)):
1302 1302 if isinstance(variables, string_types):
1303 1303 vlist = variables.split()
1304 1304 else:
1305 1305 vlist = variables
1306 1306 vdict = {}
1307 1307 cf = sys._getframe(1)
1308 1308 for name in vlist:
1309 1309 try:
1310 1310 vdict[name] = eval(name, cf.f_globals, cf.f_locals)
1311 1311 except:
1312 1312 print('Could not get variable %s from %s' %
1313 1313 (name,cf.f_code.co_name))
1314 1314 else:
1315 1315 raise ValueError('variables must be a dict/str/list/tuple')
1316 1316
1317 1317 # Propagate variables to user namespace
1318 1318 self.user_ns.update(vdict)
1319 1319
1320 1320 # And configure interactive visibility
1321 1321 user_ns_hidden = self.user_ns_hidden
1322 1322 if interactive:
1323 1323 for name in vdict:
1324 1324 user_ns_hidden.pop(name, None)
1325 1325 else:
1326 1326 user_ns_hidden.update(vdict)
1327 1327
1328 1328 def drop_by_id(self, variables):
1329 1329 """Remove a dict of variables from the user namespace, if they are the
1330 1330 same as the values in the dictionary.
1331 1331
1332 1332 This is intended for use by extensions: variables that they've added can
1333 1333 be taken back out if they are unloaded, without removing any that the
1334 1334 user has overwritten.
1335 1335
1336 1336 Parameters
1337 1337 ----------
1338 1338 variables : dict
1339 1339 A dictionary mapping object names (as strings) to the objects.
1340 1340 """
1341 1341 for name, obj in iteritems(variables):
1342 1342 if name in self.user_ns and self.user_ns[name] is obj:
1343 1343 del self.user_ns[name]
1344 1344 self.user_ns_hidden.pop(name, None)
1345 1345
1346 1346 #-------------------------------------------------------------------------
1347 1347 # Things related to object introspection
1348 1348 #-------------------------------------------------------------------------
1349 1349
1350 1350 def _ofind(self, oname, namespaces=None):
1351 1351 """Find an object in the available namespaces.
1352 1352
1353 1353 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
1354 1354
1355 1355 Has special code to detect magic functions.
1356 1356 """
1357 1357 oname = oname.strip()
1358 1358 #print '1- oname: <%r>' % oname # dbg
1359 1359 if not oname.startswith(ESC_MAGIC) and \
1360 1360 not oname.startswith(ESC_MAGIC2) and \
1361 1361 not py3compat.isidentifier(oname, dotted=True):
1362 1362 return dict(found=False)
1363 1363
1364 1364 alias_ns = None
1365 1365 if namespaces is None:
1366 1366 # Namespaces to search in:
1367 1367 # Put them in a list. The order is important so that we
1368 1368 # find things in the same order that Python finds them.
1369 1369 namespaces = [ ('Interactive', self.user_ns),
1370 1370 ('Interactive (global)', self.user_global_ns),
1371 1371 ('Python builtin', builtin_mod.__dict__),
1372 1372 ]
1373 1373
1374 1374 # initialize results to 'null'
1375 1375 found = False; obj = None; ospace = None; ds = None;
1376 1376 ismagic = False; isalias = False; parent = None
1377 1377
1378 1378 # We need to special-case 'print', which as of python2.6 registers as a
1379 1379 # function but should only be treated as one if print_function was
1380 1380 # loaded with a future import. In this case, just bail.
1381 1381 if (oname == 'print' and not py3compat.PY3 and not \
1382 1382 (self.compile.compiler_flags & __future__.CO_FUTURE_PRINT_FUNCTION)):
1383 1383 return {'found':found, 'obj':obj, 'namespace':ospace,
1384 1384 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1385 1385
1386 1386 # Look for the given name by splitting it in parts. If the head is
1387 1387 # found, then we look for all the remaining parts as members, and only
1388 1388 # declare success if we can find them all.
1389 1389 oname_parts = oname.split('.')
1390 1390 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
1391 1391 for nsname,ns in namespaces:
1392 1392 try:
1393 1393 obj = ns[oname_head]
1394 1394 except KeyError:
1395 1395 continue
1396 1396 else:
1397 1397 #print 'oname_rest:', oname_rest # dbg
1398 1398 for part in oname_rest:
1399 1399 try:
1400 1400 parent = obj
1401 1401 obj = getattr(obj,part)
1402 1402 except:
1403 1403 # Blanket except b/c some badly implemented objects
1404 1404 # allow __getattr__ to raise exceptions other than
1405 1405 # AttributeError, which then crashes IPython.
1406 1406 break
1407 1407 else:
1408 1408 # If we finish the for loop (no break), we got all members
1409 1409 found = True
1410 1410 ospace = nsname
1411 1411 break # namespace loop
1412 1412
1413 1413 # Try to see if it's magic
1414 1414 if not found:
1415 1415 obj = None
1416 1416 if oname.startswith(ESC_MAGIC2):
1417 1417 oname = oname.lstrip(ESC_MAGIC2)
1418 1418 obj = self.find_cell_magic(oname)
1419 1419 elif oname.startswith(ESC_MAGIC):
1420 1420 oname = oname.lstrip(ESC_MAGIC)
1421 1421 obj = self.find_line_magic(oname)
1422 1422 else:
1423 1423 # search without prefix, so run? will find %run?
1424 1424 obj = self.find_line_magic(oname)
1425 1425 if obj is None:
1426 1426 obj = self.find_cell_magic(oname)
1427 1427 if obj is not None:
1428 1428 found = True
1429 1429 ospace = 'IPython internal'
1430 1430 ismagic = True
1431 1431
1432 1432 # Last try: special-case some literals like '', [], {}, etc:
1433 1433 if not found and oname_head in ["''",'""','[]','{}','()']:
1434 1434 obj = eval(oname_head)
1435 1435 found = True
1436 1436 ospace = 'Interactive'
1437 1437
1438 1438 return {'found':found, 'obj':obj, 'namespace':ospace,
1439 1439 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
1440 1440
1441 1441 def _ofind_property(self, oname, info):
1442 1442 """Second part of object finding, to look for property details."""
1443 1443 if info.found:
1444 1444 # Get the docstring of the class property if it exists.
1445 1445 path = oname.split('.')
1446 1446 root = '.'.join(path[:-1])
1447 1447 if info.parent is not None:
1448 1448 try:
1449 1449 target = getattr(info.parent, '__class__')
1450 1450 # The object belongs to a class instance.
1451 1451 try:
1452 1452 target = getattr(target, path[-1])
1453 1453 # The class defines the object.
1454 1454 if isinstance(target, property):
1455 1455 oname = root + '.__class__.' + path[-1]
1456 1456 info = Struct(self._ofind(oname))
1457 1457 except AttributeError: pass
1458 1458 except AttributeError: pass
1459 1459
1460 1460 # We return either the new info or the unmodified input if the object
1461 1461 # hadn't been found
1462 1462 return info
1463 1463
1464 1464 def _object_find(self, oname, namespaces=None):
1465 1465 """Find an object and return a struct with info about it."""
1466 1466 inf = Struct(self._ofind(oname, namespaces))
1467 1467 return Struct(self._ofind_property(oname, inf))
1468 1468
1469 1469 def _inspect(self, meth, oname, namespaces=None, **kw):
1470 1470 """Generic interface to the inspector system.
1471 1471
1472 1472 This function is meant to be called by pdef, pdoc & friends."""
1473 1473 info = self._object_find(oname, namespaces)
1474 1474 if info.found:
1475 1475 pmethod = getattr(self.inspector, meth)
1476 1476 formatter = format_screen if info.ismagic else None
1477 1477 if meth == 'pdoc':
1478 1478 pmethod(info.obj, oname, formatter)
1479 1479 elif meth == 'pinfo':
1480 1480 pmethod(info.obj, oname, formatter, info, **kw)
1481 1481 else:
1482 1482 pmethod(info.obj, oname)
1483 1483 else:
1484 1484 print('Object `%s` not found.' % oname)
1485 1485 return 'not found' # so callers can take other action
1486 1486
1487 1487 def object_inspect(self, oname, detail_level=0):
1488 1488 with self.builtin_trap:
1489 1489 info = self._object_find(oname)
1490 1490 if info.found:
1491 1491 return self.inspector.info(info.obj, oname, info=info,
1492 1492 detail_level=detail_level
1493 1493 )
1494 1494 else:
1495 1495 return oinspect.object_info(name=oname, found=False)
1496 1496
1497 1497 #-------------------------------------------------------------------------
1498 1498 # Things related to history management
1499 1499 #-------------------------------------------------------------------------
1500 1500
1501 1501 def init_history(self):
1502 1502 """Sets up the command history, and starts regular autosaves."""
1503 1503 self.history_manager = HistoryManager(shell=self, parent=self)
1504 1504 self.configurables.append(self.history_manager)
1505 1505
1506 1506 #-------------------------------------------------------------------------
1507 1507 # Things related to exception handling and tracebacks (not debugging)
1508 1508 #-------------------------------------------------------------------------
1509 1509
1510 1510 def init_traceback_handlers(self, custom_exceptions):
1511 1511 # Syntax error handler.
1512 1512 self.SyntaxTB = ultratb.SyntaxTB(color_scheme='NoColor')
1513 1513
1514 1514 # The interactive one is initialized with an offset, meaning we always
1515 1515 # want to remove the topmost item in the traceback, which is our own
1516 1516 # internal code. Valid modes: ['Plain','Context','Verbose']
1517 1517 self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain',
1518 1518 color_scheme='NoColor',
1519 1519 tb_offset = 1,
1520 1520 check_cache=check_linecache_ipython)
1521 1521
1522 1522 # The instance will store a pointer to the system-wide exception hook,
1523 1523 # so that runtime code (such as magics) can access it. This is because
1524 1524 # during the read-eval loop, it may get temporarily overwritten.
1525 1525 self.sys_excepthook = sys.excepthook
1526 1526
1527 1527 # and add any custom exception handlers the user may have specified
1528 1528 self.set_custom_exc(*custom_exceptions)
1529 1529
1530 1530 # Set the exception mode
1531 1531 self.InteractiveTB.set_mode(mode=self.xmode)
1532 1532
1533 1533 def set_custom_exc(self, exc_tuple, handler):
1534 1534 """set_custom_exc(exc_tuple,handler)
1535 1535
1536 1536 Set a custom exception handler, which will be called if any of the
1537 1537 exceptions in exc_tuple occur in the mainloop (specifically, in the
1538 1538 run_code() method).
1539 1539
1540 1540 Parameters
1541 1541 ----------
1542 1542
1543 1543 exc_tuple : tuple of exception classes
1544 1544 A *tuple* of exception classes, for which to call the defined
1545 1545 handler. It is very important that you use a tuple, and NOT A
1546 1546 LIST here, because of the way Python's except statement works. If
1547 1547 you only want to trap a single exception, use a singleton tuple::
1548 1548
1549 1549 exc_tuple == (MyCustomException,)
1550 1550
1551 1551 handler : callable
1552 1552 handler must have the following signature::
1553 1553
1554 1554 def my_handler(self, etype, value, tb, tb_offset=None):
1555 1555 ...
1556 1556 return structured_traceback
1557 1557
1558 1558 Your handler must return a structured traceback (a list of strings),
1559 1559 or None.
1560 1560
1561 1561 This will be made into an instance method (via types.MethodType)
1562 1562 of IPython itself, and it will be called if any of the exceptions
1563 1563 listed in the exc_tuple are caught. If the handler is None, an
1564 1564 internal basic one is used, which just prints basic info.
1565 1565
1566 1566 To protect IPython from crashes, if your handler ever raises an
1567 1567 exception or returns an invalid result, it will be immediately
1568 1568 disabled.
1569 1569
1570 1570 WARNING: by putting in your own exception handler into IPython's main
1571 1571 execution loop, you run a very good chance of nasty crashes. This
1572 1572 facility should only be used if you really know what you are doing."""
1573 1573
1574 1574 assert type(exc_tuple)==type(()) , \
1575 1575 "The custom exceptions must be given AS A TUPLE."
1576 1576
1577 1577 def dummy_handler(self,etype,value,tb,tb_offset=None):
1578 1578 print('*** Simple custom exception handler ***')
1579 1579 print('Exception type :',etype)
1580 1580 print('Exception value:',value)
1581 1581 print('Traceback :',tb)
1582 1582 #print 'Source code :','\n'.join(self.buffer)
1583 1583
1584 1584 def validate_stb(stb):
1585 1585 """validate structured traceback return type
1586 1586
1587 1587 return type of CustomTB *should* be a list of strings, but allow
1588 1588 single strings or None, which are harmless.
1589 1589
1590 1590 This function will *always* return a list of strings,
1591 1591 and will raise a TypeError if stb is inappropriate.
1592 1592 """
1593 1593 msg = "CustomTB must return list of strings, not %r" % stb
1594 1594 if stb is None:
1595 1595 return []
1596 1596 elif isinstance(stb, string_types):
1597 1597 return [stb]
1598 1598 elif not isinstance(stb, list):
1599 1599 raise TypeError(msg)
1600 1600 # it's a list
1601 1601 for line in stb:
1602 1602 # check every element
1603 1603 if not isinstance(line, string_types):
1604 1604 raise TypeError(msg)
1605 1605 return stb
1606 1606
1607 1607 if handler is None:
1608 1608 wrapped = dummy_handler
1609 1609 else:
1610 1610 def wrapped(self,etype,value,tb,tb_offset=None):
1611 1611 """wrap CustomTB handler, to protect IPython from user code
1612 1612
1613 1613 This makes it harder (but not impossible) for custom exception
1614 1614 handlers to crash IPython.
1615 1615 """
1616 1616 try:
1617 1617 stb = handler(self,etype,value,tb,tb_offset=tb_offset)
1618 1618 return validate_stb(stb)
1619 1619 except:
1620 1620 # clear custom handler immediately
1621 1621 self.set_custom_exc((), None)
1622 1622 print("Custom TB Handler failed, unregistering", file=io.stderr)
1623 1623 # show the exception in handler first
1624 1624 stb = self.InteractiveTB.structured_traceback(*sys.exc_info())
1625 1625 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1626 1626 print("The original exception:", file=io.stdout)
1627 1627 stb = self.InteractiveTB.structured_traceback(
1628 1628 (etype,value,tb), tb_offset=tb_offset
1629 1629 )
1630 1630 return stb
1631 1631
1632 1632 self.CustomTB = types.MethodType(wrapped,self)
1633 1633 self.custom_exceptions = exc_tuple
1634 1634
1635 1635 def excepthook(self, etype, value, tb):
1636 1636 """One more defense for GUI apps that call sys.excepthook.
1637 1637
1638 1638 GUI frameworks like wxPython trap exceptions and call
1639 1639 sys.excepthook themselves. I guess this is a feature that
1640 1640 enables them to keep running after exceptions that would
1641 1641 otherwise kill their mainloop. This is a bother for IPython
1642 1642 which excepts to catch all of the program exceptions with a try:
1643 1643 except: statement.
1644 1644
1645 1645 Normally, IPython sets sys.excepthook to a CrashHandler instance, so if
1646 1646 any app directly invokes sys.excepthook, it will look to the user like
1647 1647 IPython crashed. In order to work around this, we can disable the
1648 1648 CrashHandler and replace it with this excepthook instead, which prints a
1649 1649 regular traceback using our InteractiveTB. In this fashion, apps which
1650 1650 call sys.excepthook will generate a regular-looking exception from
1651 1651 IPython, and the CrashHandler will only be triggered by real IPython
1652 1652 crashes.
1653 1653
1654 1654 This hook should be used sparingly, only in places which are not likely
1655 1655 to be true IPython errors.
1656 1656 """
1657 1657 self.showtraceback((etype,value,tb),tb_offset=0)
1658 1658
1659 1659 def _get_exc_info(self, exc_tuple=None):
1660 1660 """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc.
1661 1661
1662 1662 Ensures sys.last_type,value,traceback hold the exc_info we found,
1663 1663 from whichever source.
1664 1664
1665 1665 raises ValueError if none of these contain any information
1666 1666 """
1667 1667 if exc_tuple is None:
1668 1668 etype, value, tb = sys.exc_info()
1669 1669 else:
1670 1670 etype, value, tb = exc_tuple
1671 1671
1672 1672 if etype is None:
1673 1673 if hasattr(sys, 'last_type'):
1674 1674 etype, value, tb = sys.last_type, sys.last_value, \
1675 1675 sys.last_traceback
1676 1676
1677 1677 if etype is None:
1678 1678 raise ValueError("No exception to find")
1679 1679
1680 1680 # Now store the exception info in sys.last_type etc.
1681 1681 # WARNING: these variables are somewhat deprecated and not
1682 1682 # necessarily safe to use in a threaded environment, but tools
1683 1683 # like pdb depend on their existence, so let's set them. If we
1684 1684 # find problems in the field, we'll need to revisit their use.
1685 1685 sys.last_type = etype
1686 1686 sys.last_value = value
1687 1687 sys.last_traceback = tb
1688 1688
1689 1689 return etype, value, tb
1690 1690
1691 1691 def show_usage_error(self, exc):
1692 1692 """Show a short message for UsageErrors
1693 1693
1694 1694 These are special exceptions that shouldn't show a traceback.
1695 1695 """
1696 1696 self.write_err("UsageError: %s" % exc)
1697 1697
1698 1698 def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None,
1699 1699 exception_only=False):
1700 1700 """Display the exception that just occurred.
1701 1701
1702 1702 If nothing is known about the exception, this is the method which
1703 1703 should be used throughout the code for presenting user tracebacks,
1704 1704 rather than directly invoking the InteractiveTB object.
1705 1705
1706 1706 A specific showsyntaxerror() also exists, but this method can take
1707 1707 care of calling it if needed, so unless you are explicitly catching a
1708 1708 SyntaxError exception, don't try to analyze the stack manually and
1709 1709 simply call this method."""
1710 1710
1711 1711 try:
1712 1712 try:
1713 1713 etype, value, tb = self._get_exc_info(exc_tuple)
1714 1714 except ValueError:
1715 1715 self.write_err('No traceback available to show.\n')
1716 1716 return
1717 1717
1718 1718 if issubclass(etype, SyntaxError):
1719 1719 # Though this won't be called by syntax errors in the input
1720 1720 # line, there may be SyntaxError cases with imported code.
1721 1721 self.showsyntaxerror(filename)
1722 1722 elif etype is UsageError:
1723 1723 self.show_usage_error(value)
1724 1724 else:
1725 1725 if exception_only:
1726 1726 stb = ['An exception has occurred, use %tb to see '
1727 1727 'the full traceback.\n']
1728 1728 stb.extend(self.InteractiveTB.get_exception_only(etype,
1729 1729 value))
1730 1730 else:
1731 1731 try:
1732 1732 # Exception classes can customise their traceback - we
1733 1733 # use this in IPython.parallel for exceptions occurring
1734 1734 # in the engines. This should return a list of strings.
1735 1735 stb = value._render_traceback_()
1736 1736 except Exception:
1737 1737 stb = self.InteractiveTB.structured_traceback(etype,
1738 1738 value, tb, tb_offset=tb_offset)
1739 1739
1740 1740 self._showtraceback(etype, value, stb)
1741 1741 if self.call_pdb:
1742 1742 # drop into debugger
1743 1743 self.debugger(force=True)
1744 1744 return
1745 1745
1746 1746 # Actually show the traceback
1747 1747 self._showtraceback(etype, value, stb)
1748 1748
1749 1749 except KeyboardInterrupt:
1750 1750 self.write_err("\nKeyboardInterrupt\n")
1751 1751
1752 1752 def _showtraceback(self, etype, evalue, stb):
1753 1753 """Actually show a traceback.
1754 1754
1755 1755 Subclasses may override this method to put the traceback on a different
1756 1756 place, like a side channel.
1757 1757 """
1758 1758 print(self.InteractiveTB.stb2text(stb), file=io.stdout)
1759 1759
1760 1760 def showsyntaxerror(self, filename=None):
1761 1761 """Display the syntax error that just occurred.
1762 1762
1763 1763 This doesn't display a stack trace because there isn't one.
1764 1764
1765 1765 If a filename is given, it is stuffed in the exception instead
1766 1766 of what was there before (because Python's parser always uses
1767 1767 "<string>" when reading from a string).
1768 1768 """
1769 1769 etype, value, last_traceback = self._get_exc_info()
1770 1770
1771 1771 if filename and issubclass(etype, SyntaxError):
1772 1772 try:
1773 1773 value.filename = filename
1774 1774 except:
1775 1775 # Not the format we expect; leave it alone
1776 1776 pass
1777 1777
1778 1778 stb = self.SyntaxTB.structured_traceback(etype, value, [])
1779 1779 self._showtraceback(etype, value, stb)
1780 1780
1781 1781 # This is overridden in TerminalInteractiveShell to show a message about
1782 1782 # the %paste magic.
1783 1783 def showindentationerror(self):
1784 1784 """Called by run_cell when there's an IndentationError in code entered
1785 1785 at the prompt.
1786 1786
1787 1787 This is overridden in TerminalInteractiveShell to show a message about
1788 1788 the %paste magic."""
1789 1789 self.showsyntaxerror()
1790 1790
1791 1791 #-------------------------------------------------------------------------
1792 1792 # Things related to readline
1793 1793 #-------------------------------------------------------------------------
1794 1794
1795 1795 def init_readline(self):
1796 1796 """Command history completion/saving/reloading."""
1797 1797
1798 1798 if self.readline_use:
1799 1799 import IPython.utils.rlineimpl as readline
1800 1800
1801 1801 self.rl_next_input = None
1802 1802 self.rl_do_indent = False
1803 1803
1804 1804 if not self.readline_use or not readline.have_readline:
1805 1805 self.has_readline = False
1806 1806 self.readline = None
1807 1807 # Set a number of methods that depend on readline to be no-op
1808 1808 self.readline_no_record = no_op_context
1809 1809 self.set_readline_completer = no_op
1810 1810 self.set_custom_completer = no_op
1811 1811 if self.readline_use:
1812 1812 warn('Readline services not available or not loaded.')
1813 1813 else:
1814 1814 self.has_readline = True
1815 1815 self.readline = readline
1816 1816 sys.modules['readline'] = readline
1817 1817
1818 1818 # Platform-specific configuration
1819 1819 if os.name == 'nt':
1820 1820 # FIXME - check with Frederick to see if we can harmonize
1821 1821 # naming conventions with pyreadline to avoid this
1822 1822 # platform-dependent check
1823 1823 self.readline_startup_hook = readline.set_pre_input_hook
1824 1824 else:
1825 1825 self.readline_startup_hook = readline.set_startup_hook
1826 1826
1827 1827 # Load user's initrc file (readline config)
1828 1828 # Or if libedit is used, load editrc.
1829 1829 inputrc_name = os.environ.get('INPUTRC')
1830 1830 if inputrc_name is None:
1831 1831 inputrc_name = '.inputrc'
1832 1832 if readline.uses_libedit:
1833 1833 inputrc_name = '.editrc'
1834 1834 inputrc_name = os.path.join(self.home_dir, inputrc_name)
1835 1835 if os.path.isfile(inputrc_name):
1836 1836 try:
1837 1837 readline.read_init_file(inputrc_name)
1838 1838 except:
1839 1839 warn('Problems reading readline initialization file <%s>'
1840 1840 % inputrc_name)
1841 1841
1842 1842 # Configure readline according to user's prefs
1843 1843 # This is only done if GNU readline is being used. If libedit
1844 1844 # is being used (as on Leopard) the readline config is
1845 1845 # not run as the syntax for libedit is different.
1846 1846 if not readline.uses_libedit:
1847 1847 for rlcommand in self.readline_parse_and_bind:
1848 1848 #print "loading rl:",rlcommand # dbg
1849 1849 readline.parse_and_bind(rlcommand)
1850 1850
1851 1851 # Remove some chars from the delimiters list. If we encounter
1852 1852 # unicode chars, discard them.
1853 1853 delims = readline.get_completer_delims()
1854 1854 if not py3compat.PY3:
1855 1855 delims = delims.encode("ascii", "ignore")
1856 1856 for d in self.readline_remove_delims:
1857 1857 delims = delims.replace(d, "")
1858 1858 delims = delims.replace(ESC_MAGIC, '')
1859 1859 readline.set_completer_delims(delims)
1860 1860 # Store these so we can restore them if something like rpy2 modifies
1861 1861 # them.
1862 1862 self.readline_delims = delims
1863 1863 # otherwise we end up with a monster history after a while:
1864 1864 readline.set_history_length(self.history_length)
1865 1865
1866 1866 self.refill_readline_hist()
1867 1867 self.readline_no_record = ReadlineNoRecord(self)
1868 1868
1869 1869 # Configure auto-indent for all platforms
1870 1870 self.set_autoindent(self.autoindent)
1871 1871
1872 1872 def refill_readline_hist(self):
1873 1873 # Load the last 1000 lines from history
1874 1874 self.readline.clear_history()
1875 1875 stdin_encoding = sys.stdin.encoding or "utf-8"
1876 1876 last_cell = u""
1877 1877 for _, _, cell in self.history_manager.get_tail(1000,
1878 1878 include_latest=True):
1879 1879 # Ignore blank lines and consecutive duplicates
1880 1880 cell = cell.rstrip()
1881 1881 if cell and (cell != last_cell):
1882 1882 try:
1883 1883 if self.multiline_history:
1884 1884 self.readline.add_history(py3compat.unicode_to_str(cell,
1885 1885 stdin_encoding))
1886 1886 else:
1887 1887 for line in cell.splitlines():
1888 1888 self.readline.add_history(py3compat.unicode_to_str(line,
1889 1889 stdin_encoding))
1890 1890 last_cell = cell
1891 1891
1892 1892 except TypeError:
1893 1893 # The history DB can get corrupted so it returns strings
1894 1894 # containing null bytes, which readline objects to.
1895 1895 continue
1896 1896
1897 1897 @skip_doctest
1898 1898 def set_next_input(self, s):
1899 1899 """ Sets the 'default' input string for the next command line.
1900 1900
1901 1901 Requires readline.
1902 1902
1903 1903 Example::
1904 1904
1905 1905 In [1]: _ip.set_next_input("Hello Word")
1906 1906 In [2]: Hello Word_ # cursor is here
1907 1907 """
1908 1908 self.rl_next_input = py3compat.cast_bytes_py2(s)
1909 1909
1910 1910 # Maybe move this to the terminal subclass?
1911 1911 def pre_readline(self):
1912 1912 """readline hook to be used at the start of each line.
1913 1913
1914 1914 Currently it handles auto-indent only."""
1915 1915
1916 1916 if self.rl_do_indent:
1917 1917 self.readline.insert_text(self._indent_current_str())
1918 1918 if self.rl_next_input is not None:
1919 1919 self.readline.insert_text(self.rl_next_input)
1920 1920 self.rl_next_input = None
1921 1921
1922 1922 def _indent_current_str(self):
1923 1923 """return the current level of indentation as a string"""
1924 1924 return self.input_splitter.indent_spaces * ' '
1925 1925
1926 1926 #-------------------------------------------------------------------------
1927 1927 # Things related to text completion
1928 1928 #-------------------------------------------------------------------------
1929 1929
1930 1930 def init_completer(self):
1931 1931 """Initialize the completion machinery.
1932 1932
1933 1933 This creates completion machinery that can be used by client code,
1934 1934 either interactively in-process (typically triggered by the readline
1935 1935 library), programatically (such as in test suites) or out-of-prcess
1936 1936 (typically over the network by remote frontends).
1937 1937 """
1938 1938 from IPython.core.completer import IPCompleter
1939 1939 from IPython.core.completerlib import (module_completer,
1940 1940 magic_run_completer, cd_completer, reset_completer)
1941 1941
1942 1942 self.Completer = IPCompleter(shell=self,
1943 1943 namespace=self.user_ns,
1944 1944 global_namespace=self.user_global_ns,
1945 1945 use_readline=self.has_readline,
1946 1946 parent=self,
1947 1947 )
1948 1948 self.configurables.append(self.Completer)
1949 1949
1950 1950 # Add custom completers to the basic ones built into IPCompleter
1951 1951 sdisp = self.strdispatchers.get('complete_command', StrDispatch())
1952 1952 self.strdispatchers['complete_command'] = sdisp
1953 1953 self.Completer.custom_completers = sdisp
1954 1954
1955 1955 self.set_hook('complete_command', module_completer, str_key = 'import')
1956 1956 self.set_hook('complete_command', module_completer, str_key = 'from')
1957 1957 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
1958 1958 self.set_hook('complete_command', cd_completer, str_key = '%cd')
1959 1959 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1960 1960
1961 1961 # Only configure readline if we truly are using readline. IPython can
1962 1962 # do tab-completion over the network, in GUIs, etc, where readline
1963 1963 # itself may be absent
1964 1964 if self.has_readline:
1965 1965 self.set_readline_completer()
1966 1966
1967 1967 def complete(self, text, line=None, cursor_pos=None):
1968 1968 """Return the completed text and a list of completions.
1969 1969
1970 1970 Parameters
1971 1971 ----------
1972 1972
1973 1973 text : string
1974 1974 A string of text to be completed on. It can be given as empty and
1975 1975 instead a line/position pair are given. In this case, the
1976 1976 completer itself will split the line like readline does.
1977 1977
1978 1978 line : string, optional
1979 1979 The complete line that text is part of.
1980 1980
1981 1981 cursor_pos : int, optional
1982 1982 The position of the cursor on the input line.
1983 1983
1984 1984 Returns
1985 1985 -------
1986 1986 text : string
1987 1987 The actual text that was completed.
1988 1988
1989 1989 matches : list
1990 1990 A sorted list with all possible completions.
1991 1991
1992 1992 The optional arguments allow the completion to take more context into
1993 1993 account, and are part of the low-level completion API.
1994 1994
1995 1995 This is a wrapper around the completion mechanism, similar to what
1996 1996 readline does at the command line when the TAB key is hit. By
1997 1997 exposing it as a method, it can be used by other non-readline
1998 1998 environments (such as GUIs) for text completion.
1999 1999
2000 2000 Simple usage example:
2001 2001
2002 2002 In [1]: x = 'hello'
2003 2003
2004 2004 In [2]: _ip.complete('x.l')
2005 2005 Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip'])
2006 2006 """
2007 2007
2008 2008 # Inject names into __builtin__ so we can complete on the added names.
2009 2009 with self.builtin_trap:
2010 2010 return self.Completer.complete(text, line, cursor_pos)
2011 2011
2012 2012 def set_custom_completer(self, completer, pos=0):
2013 2013 """Adds a new custom completer function.
2014 2014
2015 2015 The position argument (defaults to 0) is the index in the completers
2016 2016 list where you want the completer to be inserted."""
2017 2017
2018 2018 newcomp = types.MethodType(completer,self.Completer)
2019 2019 self.Completer.matchers.insert(pos,newcomp)
2020 2020
2021 2021 def set_readline_completer(self):
2022 2022 """Reset readline's completer to be our own."""
2023 2023 self.readline.set_completer(self.Completer.rlcomplete)
2024 2024
2025 2025 def set_completer_frame(self, frame=None):
2026 2026 """Set the frame of the completer."""
2027 2027 if frame:
2028 2028 self.Completer.namespace = frame.f_locals
2029 2029 self.Completer.global_namespace = frame.f_globals
2030 2030 else:
2031 2031 self.Completer.namespace = self.user_ns
2032 2032 self.Completer.global_namespace = self.user_global_ns
2033 2033
2034 2034 #-------------------------------------------------------------------------
2035 2035 # Things related to magics
2036 2036 #-------------------------------------------------------------------------
2037 2037
2038 2038 def init_magics(self):
2039 2039 from IPython.core import magics as m
2040 2040 self.magics_manager = magic.MagicsManager(shell=self,
2041 2041 parent=self,
2042 2042 user_magics=m.UserMagics(self))
2043 2043 self.configurables.append(self.magics_manager)
2044 2044
2045 2045 # Expose as public API from the magics manager
2046 2046 self.register_magics = self.magics_manager.register
2047 2047 self.define_magic = self.magics_manager.define_magic
2048 2048
2049 2049 self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics,
2050 2050 m.ConfigMagics, m.DeprecatedMagics, m.DisplayMagics, m.ExecutionMagics,
2051 2051 m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics,
2052 2052 m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics,
2053 2053 )
2054 2054
2055 2055 # Register Magic Aliases
2056 2056 mman = self.magics_manager
2057 2057 # FIXME: magic aliases should be defined by the Magics classes
2058 2058 # or in MagicsManager, not here
2059 2059 mman.register_alias('ed', 'edit')
2060 2060 mman.register_alias('hist', 'history')
2061 2061 mman.register_alias('rep', 'recall')
2062 2062 mman.register_alias('SVG', 'svg', 'cell')
2063 2063 mman.register_alias('HTML', 'html', 'cell')
2064 2064 mman.register_alias('file', 'writefile', 'cell')
2065 2065
2066 2066 # FIXME: Move the color initialization to the DisplayHook, which
2067 2067 # should be split into a prompt manager and displayhook. We probably
2068 2068 # even need a centralize colors management object.
2069 2069 self.magic('colors %s' % self.colors)
2070 2070
2071 2071 # Defined here so that it's included in the documentation
2072 2072 @functools.wraps(magic.MagicsManager.register_function)
2073 2073 def register_magic_function(self, func, magic_kind='line', magic_name=None):
2074 2074 self.magics_manager.register_function(func,
2075 2075 magic_kind=magic_kind, magic_name=magic_name)
2076 2076
2077 2077 def run_line_magic(self, magic_name, line):
2078 2078 """Execute the given line magic.
2079 2079
2080 2080 Parameters
2081 2081 ----------
2082 2082 magic_name : str
2083 2083 Name of the desired magic function, without '%' prefix.
2084 2084
2085 2085 line : str
2086 2086 The rest of the input line as a single string.
2087 2087 """
2088 2088 fn = self.find_line_magic(magic_name)
2089 2089 if fn is None:
2090 2090 cm = self.find_cell_magic(magic_name)
2091 2091 etpl = "Line magic function `%%%s` not found%s."
2092 2092 extra = '' if cm is None else (' (But cell magic `%%%%%s` exists, '
2093 2093 'did you mean that instead?)' % magic_name )
2094 2094 error(etpl % (magic_name, extra))
2095 2095 else:
2096 2096 # Note: this is the distance in the stack to the user's frame.
2097 2097 # This will need to be updated if the internal calling logic gets
2098 2098 # refactored, or else we'll be expanding the wrong variables.
2099 2099 stack_depth = 2
2100 2100 magic_arg_s = self.var_expand(line, stack_depth)
2101 2101 # Put magic args in a list so we can call with f(*a) syntax
2102 2102 args = [magic_arg_s]
2103 2103 kwargs = {}
2104 2104 # Grab local namespace if we need it:
2105 2105 if getattr(fn, "needs_local_scope", False):
2106 2106 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2107 2107 with self.builtin_trap:
2108 2108 result = fn(*args,**kwargs)
2109 2109 return result
2110 2110
2111 2111 def run_cell_magic(self, magic_name, line, cell):
2112 2112 """Execute the given cell magic.
2113 2113
2114 2114 Parameters
2115 2115 ----------
2116 2116 magic_name : str
2117 2117 Name of the desired magic function, without '%' prefix.
2118 2118
2119 2119 line : str
2120 2120 The rest of the first input line as a single string.
2121 2121
2122 2122 cell : str
2123 2123 The body of the cell as a (possibly multiline) string.
2124 2124 """
2125 2125 fn = self.find_cell_magic(magic_name)
2126 2126 if fn is None:
2127 2127 lm = self.find_line_magic(magic_name)
2128 2128 etpl = "Cell magic `%%{0}` not found{1}."
2129 2129 extra = '' if lm is None else (' (But line magic `%{0}` exists, '
2130 2130 'did you mean that instead?)'.format(magic_name))
2131 2131 error(etpl.format(magic_name, extra))
2132 2132 elif cell == '':
2133 2133 message = '%%{0} is a cell magic, but the cell body is empty.'.format(magic_name)
2134 2134 if self.find_line_magic(magic_name) is not None:
2135 2135 message += ' Did you mean the line magic %{0} (single %)?'.format(magic_name)
2136 2136 raise UsageError(message)
2137 2137 else:
2138 2138 # Note: this is the distance in the stack to the user's frame.
2139 2139 # This will need to be updated if the internal calling logic gets
2140 2140 # refactored, or else we'll be expanding the wrong variables.
2141 2141 stack_depth = 2
2142 2142 magic_arg_s = self.var_expand(line, stack_depth)
2143 2143 with self.builtin_trap:
2144 2144 result = fn(magic_arg_s, cell)
2145 2145 return result
2146 2146
2147 2147 def find_line_magic(self, magic_name):
2148 2148 """Find and return a line magic by name.
2149 2149
2150 2150 Returns None if the magic isn't found."""
2151 2151 return self.magics_manager.magics['line'].get(magic_name)
2152 2152
2153 2153 def find_cell_magic(self, magic_name):
2154 2154 """Find and return a cell magic by name.
2155 2155
2156 2156 Returns None if the magic isn't found."""
2157 2157 return self.magics_manager.magics['cell'].get(magic_name)
2158 2158
2159 2159 def find_magic(self, magic_name, magic_kind='line'):
2160 2160 """Find and return a magic of the given type by name.
2161 2161
2162 2162 Returns None if the magic isn't found."""
2163 2163 return self.magics_manager.magics[magic_kind].get(magic_name)
2164 2164
2165 2165 def magic(self, arg_s):
2166 2166 """DEPRECATED. Use run_line_magic() instead.
2167 2167
2168 2168 Call a magic function by name.
2169 2169
2170 2170 Input: a string containing the name of the magic function to call and
2171 2171 any additional arguments to be passed to the magic.
2172 2172
2173 2173 magic('name -opt foo bar') is equivalent to typing at the ipython
2174 2174 prompt:
2175 2175
2176 2176 In[1]: %name -opt foo bar
2177 2177
2178 2178 To call a magic without arguments, simply use magic('name').
2179 2179
2180 2180 This provides a proper Python function to call IPython's magics in any
2181 2181 valid Python code you can type at the interpreter, including loops and
2182 2182 compound statements.
2183 2183 """
2184 2184 # TODO: should we issue a loud deprecation warning here?
2185 2185 magic_name, _, magic_arg_s = arg_s.partition(' ')
2186 2186 magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
2187 2187 return self.run_line_magic(magic_name, magic_arg_s)
2188 2188
2189 2189 #-------------------------------------------------------------------------
2190 2190 # Things related to macros
2191 2191 #-------------------------------------------------------------------------
2192 2192
2193 2193 def define_macro(self, name, themacro):
2194 2194 """Define a new macro
2195 2195
2196 2196 Parameters
2197 2197 ----------
2198 2198 name : str
2199 2199 The name of the macro.
2200 2200 themacro : str or Macro
2201 2201 The action to do upon invoking the macro. If a string, a new
2202 2202 Macro object is created by passing the string to it.
2203 2203 """
2204 2204
2205 2205 from IPython.core import macro
2206 2206
2207 2207 if isinstance(themacro, string_types):
2208 2208 themacro = macro.Macro(themacro)
2209 2209 if not isinstance(themacro, macro.Macro):
2210 2210 raise ValueError('A macro must be a string or a Macro instance.')
2211 2211 self.user_ns[name] = themacro
2212 2212
2213 2213 #-------------------------------------------------------------------------
2214 2214 # Things related to the running of system commands
2215 2215 #-------------------------------------------------------------------------
2216 2216
2217 2217 def system_piped(self, cmd):
2218 2218 """Call the given cmd in a subprocess, piping stdout/err
2219 2219
2220 2220 Parameters
2221 2221 ----------
2222 2222 cmd : str
2223 2223 Command to execute (can not end in '&', as background processes are
2224 2224 not supported. Should not be a command that expects input
2225 2225 other than simple text.
2226 2226 """
2227 2227 if cmd.rstrip().endswith('&'):
2228 2228 # this is *far* from a rigorous test
2229 2229 # We do not support backgrounding processes because we either use
2230 2230 # pexpect or pipes to read from. Users can always just call
2231 2231 # os.system() or use ip.system=ip.system_raw
2232 2232 # if they really want a background process.
2233 2233 raise OSError("Background processes not supported.")
2234 2234
2235 2235 # we explicitly do NOT return the subprocess status code, because
2236 2236 # a non-None value would trigger :func:`sys.displayhook` calls.
2237 2237 # Instead, we store the exit_code in user_ns.
2238 2238 self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
2239 2239
2240 2240 def system_raw(self, cmd):
2241 2241 """Call the given cmd in a subprocess using os.system on Windows or
2242 2242 subprocess.call using the system shell on other platforms.
2243 2243
2244 2244 Parameters
2245 2245 ----------
2246 2246 cmd : str
2247 2247 Command to execute.
2248 2248 """
2249 2249 cmd = self.var_expand(cmd, depth=1)
2250 2250 # protect os.system from UNC paths on Windows, which it can't handle:
2251 2251 if sys.platform == 'win32':
2252 2252 from IPython.utils._process_win32 import AvoidUNCPath
2253 2253 with AvoidUNCPath() as path:
2254 2254 if path is not None:
2255 2255 cmd = '"pushd %s &&"%s' % (path, cmd)
2256 2256 cmd = py3compat.unicode_to_str(cmd)
2257 2257 ec = os.system(cmd)
2258 2258 else:
2259 2259 cmd = py3compat.unicode_to_str(cmd)
2260 2260 # Call the cmd using the OS shell, instead of the default /bin/sh, if set.
2261 2261 ec = subprocess.call(cmd, shell=True, executable=os.environ.get('SHELL', None))
2262 2262 # exit code is positive for program failure, or negative for
2263 2263 # terminating signal number.
2264 2264
2265 2265 # We explicitly do NOT return the subprocess status code, because
2266 2266 # a non-None value would trigger :func:`sys.displayhook` calls.
2267 2267 # Instead, we store the exit_code in user_ns.
2268 2268 self.user_ns['_exit_code'] = ec
2269 2269
2270 2270 # use piped system by default, because it is better behaved
2271 2271 system = system_piped
2272 2272
2273 2273 def getoutput(self, cmd, split=True, depth=0):
2274 2274 """Get output (possibly including stderr) from a subprocess.
2275 2275
2276 2276 Parameters
2277 2277 ----------
2278 2278 cmd : str
2279 2279 Command to execute (can not end in '&', as background processes are
2280 2280 not supported.
2281 2281 split : bool, optional
2282 2282 If True, split the output into an IPython SList. Otherwise, an
2283 2283 IPython LSString is returned. These are objects similar to normal
2284 2284 lists and strings, with a few convenience attributes for easier
2285 2285 manipulation of line-based output. You can use '?' on them for
2286 2286 details.
2287 2287 depth : int, optional
2288 2288 How many frames above the caller are the local variables which should
2289 2289 be expanded in the command string? The default (0) assumes that the
2290 2290 expansion variables are in the stack frame calling this function.
2291 2291 """
2292 2292 if cmd.rstrip().endswith('&'):
2293 2293 # this is *far* from a rigorous test
2294 2294 raise OSError("Background processes not supported.")
2295 2295 out = getoutput(self.var_expand(cmd, depth=depth+1))
2296 2296 if split:
2297 2297 out = SList(out.splitlines())
2298 2298 else:
2299 2299 out = LSString(out)
2300 2300 return out
2301 2301
2302 2302 #-------------------------------------------------------------------------
2303 2303 # Things related to aliases
2304 2304 #-------------------------------------------------------------------------
2305 2305
2306 2306 def init_alias(self):
2307 2307 self.alias_manager = AliasManager(shell=self, parent=self)
2308 2308 self.configurables.append(self.alias_manager)
2309 2309
2310 2310 #-------------------------------------------------------------------------
2311 2311 # Things related to extensions
2312 2312 #-------------------------------------------------------------------------
2313 2313
2314 2314 def init_extension_manager(self):
2315 2315 self.extension_manager = ExtensionManager(shell=self, parent=self)
2316 2316 self.configurables.append(self.extension_manager)
2317 2317
2318 2318 #-------------------------------------------------------------------------
2319 2319 # Things related to payloads
2320 2320 #-------------------------------------------------------------------------
2321 2321
2322 2322 def init_payload(self):
2323 2323 self.payload_manager = PayloadManager(parent=self)
2324 2324 self.configurables.append(self.payload_manager)
2325 2325
2326 2326 #-------------------------------------------------------------------------
2327 2327 # Things related to widgets
2328 2328 #-------------------------------------------------------------------------
2329 2329
2330 2330 def init_comms(self):
2331 2331 # not implemented in the base class
2332 2332 pass
2333 2333
2334 2334 #-------------------------------------------------------------------------
2335 2335 # Things related to the prefilter
2336 2336 #-------------------------------------------------------------------------
2337 2337
2338 2338 def init_prefilter(self):
2339 2339 self.prefilter_manager = PrefilterManager(shell=self, parent=self)
2340 2340 self.configurables.append(self.prefilter_manager)
2341 2341 # Ultimately this will be refactored in the new interpreter code, but
2342 2342 # for now, we should expose the main prefilter method (there's legacy
2343 2343 # code out there that may rely on this).
2344 2344 self.prefilter = self.prefilter_manager.prefilter_lines
2345 2345
2346 2346 def auto_rewrite_input(self, cmd):
2347 2347 """Print to the screen the rewritten form of the user's command.
2348 2348
2349 2349 This shows visual feedback by rewriting input lines that cause
2350 2350 automatic calling to kick in, like::
2351 2351
2352 2352 /f x
2353 2353
2354 2354 into::
2355 2355
2356 2356 ------> f(x)
2357 2357
2358 2358 after the user's input prompt. This helps the user understand that the
2359 2359 input line was transformed automatically by IPython.
2360 2360 """
2361 2361 if not self.show_rewritten_input:
2362 2362 return
2363 2363
2364 2364 rw = self.prompt_manager.render('rewrite') + cmd
2365 2365
2366 2366 try:
2367 2367 # plain ascii works better w/ pyreadline, on some machines, so
2368 2368 # we use it and only print uncolored rewrite if we have unicode
2369 2369 rw = str(rw)
2370 2370 print(rw, file=io.stdout)
2371 2371 except UnicodeEncodeError:
2372 2372 print("------> " + cmd)
2373 2373
2374 2374 #-------------------------------------------------------------------------
2375 2375 # Things related to extracting values/expressions from kernel and user_ns
2376 2376 #-------------------------------------------------------------------------
2377 2377
2378 2378 def _user_obj_error(self):
2379 2379 """return simple exception dict
2380 2380
2381 2381 for use in user_variables / expressions
2382 2382 """
2383 2383
2384 2384 etype, evalue, tb = self._get_exc_info()
2385 2385 stb = self.InteractiveTB.get_exception_only(etype, evalue)
2386 2386
2387 2387 exc_info = {
2388 2388 u'status' : 'error',
2389 2389 u'traceback' : stb,
2390 2390 u'ename' : unicode_type(etype.__name__),
2391 2391 u'evalue' : py3compat.safe_unicode(evalue),
2392 2392 }
2393 2393
2394 2394 return exc_info
2395 2395
2396 2396 def _format_user_obj(self, obj):
2397 2397 """format a user object to display dict
2398 2398
2399 2399 for use in user_expressions / variables
2400 2400 """
2401 2401
2402 2402 data, md = self.display_formatter.format(obj)
2403 2403 value = {
2404 2404 'status' : 'ok',
2405 2405 'data' : data,
2406 2406 'metadata' : md,
2407 2407 }
2408 2408 return value
2409 2409
2410 2410 def user_variables(self, names):
2411 2411 """Get a list of variable names from the user's namespace.
2412 2412
2413 2413 Parameters
2414 2414 ----------
2415 2415 names : list of strings
2416 2416 A list of names of variables to be read from the user namespace.
2417 2417
2418 2418 Returns
2419 2419 -------
2420 2420 A dict, keyed by the input names and with the rich mime-type repr(s) of each value.
2421 2421 Each element will be a sub-dict of the same form as a display_data message.
2422 2422 """
2423 2423 out = {}
2424 2424 user_ns = self.user_ns
2425 2425
2426 2426 for varname in names:
2427 2427 try:
2428 2428 value = self._format_user_obj(user_ns[varname])
2429 2429 except:
2430 2430 value = self._user_obj_error()
2431 2431 out[varname] = value
2432 2432 return out
2433 2433
2434 2434 def user_expressions(self, expressions):
2435 2435 """Evaluate a dict of expressions in the user's namespace.
2436 2436
2437 2437 Parameters
2438 2438 ----------
2439 2439 expressions : dict
2440 2440 A dict with string keys and string values. The expression values
2441 2441 should be valid Python expressions, each of which will be evaluated
2442 2442 in the user namespace.
2443 2443
2444 2444 Returns
2445 2445 -------
2446 2446 A dict, keyed like the input expressions dict, with the rich mime-typed
2447 2447 display_data of each value.
2448 2448 """
2449 2449 out = {}
2450 2450 user_ns = self.user_ns
2451 2451 global_ns = self.user_global_ns
2452 2452
2453 2453 for key, expr in iteritems(expressions):
2454 2454 try:
2455 2455 value = self._format_user_obj(eval(expr, global_ns, user_ns))
2456 2456 except:
2457 2457 value = self._user_obj_error()
2458 2458 out[key] = value
2459 2459 return out
2460 2460
2461 2461 #-------------------------------------------------------------------------
2462 2462 # Things related to the running of code
2463 2463 #-------------------------------------------------------------------------
2464 2464
2465 2465 def ex(self, cmd):
2466 2466 """Execute a normal python statement in user namespace."""
2467 2467 with self.builtin_trap:
2468 2468 exec(cmd, self.user_global_ns, self.user_ns)
2469 2469
2470 2470 def ev(self, expr):
2471 2471 """Evaluate python expression expr in user namespace.
2472 2472
2473 2473 Returns the result of evaluation
2474 2474 """
2475 2475 with self.builtin_trap:
2476 2476 return eval(expr, self.user_global_ns, self.user_ns)
2477 2477
2478 2478 def safe_execfile(self, fname, *where, **kw):
2479 2479 """A safe version of the builtin execfile().
2480 2480
2481 2481 This version will never throw an exception, but instead print
2482 2482 helpful error messages to the screen. This only works on pure
2483 2483 Python files with the .py extension.
2484 2484
2485 2485 Parameters
2486 2486 ----------
2487 2487 fname : string
2488 2488 The name of the file to be executed.
2489 2489 where : tuple
2490 2490 One or two namespaces, passed to execfile() as (globals,locals).
2491 2491 If only one is given, it is passed as both.
2492 2492 exit_ignore : bool (False)
2493 2493 If True, then silence SystemExit for non-zero status (it is always
2494 2494 silenced for zero status, as it is so common).
2495 2495 raise_exceptions : bool (False)
2496 2496 If True raise exceptions everywhere. Meant for testing.
2497 2497
2498 2498 """
2499 2499 kw.setdefault('exit_ignore', False)
2500 2500 kw.setdefault('raise_exceptions', False)
2501 2501
2502 2502 fname = os.path.abspath(os.path.expanduser(fname))
2503 2503
2504 2504 # Make sure we can open the file
2505 2505 try:
2506 2506 with open(fname) as thefile:
2507 2507 pass
2508 2508 except:
2509 2509 warn('Could not open file <%s> for safe execution.' % fname)
2510 2510 return
2511 2511
2512 2512 # Find things also in current directory. This is needed to mimic the
2513 2513 # behavior of running a script from the system command line, where
2514 2514 # Python inserts the script's directory into sys.path
2515 2515 dname = os.path.dirname(fname)
2516 2516
2517 2517 with prepended_to_syspath(dname):
2518 2518 try:
2519 2519 py3compat.execfile(fname,*where)
2520 2520 except SystemExit as status:
2521 2521 # If the call was made with 0 or None exit status (sys.exit(0)
2522 2522 # or sys.exit() ), don't bother showing a traceback, as both of
2523 2523 # these are considered normal by the OS:
2524 2524 # > python -c'import sys;sys.exit(0)'; echo $?
2525 2525 # 0
2526 2526 # > python -c'import sys;sys.exit()'; echo $?
2527 2527 # 0
2528 2528 # For other exit status, we show the exception unless
2529 2529 # explicitly silenced, but only in short form.
2530 2530 if kw['raise_exceptions']:
2531 2531 raise
2532 2532 if status.code and not kw['exit_ignore']:
2533 2533 self.showtraceback(exception_only=True)
2534 2534 except:
2535 2535 if kw['raise_exceptions']:
2536 2536 raise
2537 2537 # tb offset is 2 because we wrap execfile
2538 2538 self.showtraceback(tb_offset=2)
2539 2539
2540 2540 def safe_execfile_ipy(self, fname):
2541 2541 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2542 2542
2543 2543 Parameters
2544 2544 ----------
2545 2545 fname : str
2546 2546 The name of the file to execute. The filename must have a
2547 2547 .ipy or .ipynb extension.
2548 2548 """
2549 2549 fname = os.path.abspath(os.path.expanduser(fname))
2550 2550
2551 2551 # Make sure we can open the file
2552 2552 try:
2553 2553 with open(fname) as thefile:
2554 2554 pass
2555 2555 except:
2556 2556 warn('Could not open file <%s> for safe execution.' % fname)
2557 2557 return
2558 2558
2559 2559 # Find things also in current directory. This is needed to mimic the
2560 2560 # behavior of running a script from the system command line, where
2561 2561 # Python inserts the script's directory into sys.path
2562 2562 dname = os.path.dirname(fname)
2563 2563
2564 2564 def get_cells():
2565 2565 """generator for sequence of code blocks to run"""
2566 2566 if fname.endswith('.ipynb'):
2567 2567 from IPython.nbformat import current
2568 2568 with open(fname) as f:
2569 2569 nb = current.read(f, 'json')
2570 2570 if not nb.worksheets:
2571 2571 return
2572 2572 for cell in nb.worksheets[0].cells:
2573 2573 if cell.cell_type == 'code':
2574 2574 yield cell.input
2575 2575 else:
2576 2576 with open(fname) as f:
2577 2577 yield f.read()
2578 2578
2579 2579 with prepended_to_syspath(dname):
2580 2580 try:
2581 2581 for cell in get_cells():
2582 2582 # self.run_cell currently captures all exceptions
2583 2583 # raised in user code. It would be nice if there were
2584 2584 # versions of run_cell that did raise, so
2585 2585 # we could catch the errors.
2586 2586 self.run_cell(cell, store_history=False, shell_futures=False)
2587 2587 except:
2588 2588 self.showtraceback()
2589 2589 warn('Unknown failure executing file: <%s>' % fname)
2590 2590
2591 2591 def safe_run_module(self, mod_name, where):
2592 2592 """A safe version of runpy.run_module().
2593 2593
2594 2594 This version will never throw an exception, but instead print
2595 2595 helpful error messages to the screen.
2596 2596
2597 2597 `SystemExit` exceptions with status code 0 or None are ignored.
2598 2598
2599 2599 Parameters
2600 2600 ----------
2601 2601 mod_name : string
2602 2602 The name of the module to be executed.
2603 2603 where : dict
2604 2604 The globals namespace.
2605 2605 """
2606 2606 try:
2607 2607 try:
2608 2608 where.update(
2609 2609 runpy.run_module(str(mod_name), run_name="__main__",
2610 2610 alter_sys=True)
2611 2611 )
2612 2612 except SystemExit as status:
2613 2613 if status.code:
2614 2614 raise
2615 2615 except:
2616 2616 self.showtraceback()
2617 2617 warn('Unknown failure executing module: <%s>' % mod_name)
2618 2618
2619 2619 def _run_cached_cell_magic(self, magic_name, line):
2620 2620 """Special method to call a cell magic with the data stored in self.
2621 2621 """
2622 2622 cell = self._current_cell_magic_body
2623 2623 self._current_cell_magic_body = None
2624 2624 return self.run_cell_magic(magic_name, line, cell)
2625 2625
2626 2626 def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True):
2627 2627 """Run a complete IPython cell.
2628 2628
2629 2629 Parameters
2630 2630 ----------
2631 2631 raw_cell : str
2632 2632 The code (including IPython code such as %magic functions) to run.
2633 2633 store_history : bool
2634 2634 If True, the raw and translated cell will be stored in IPython's
2635 2635 history. For user code calling back into IPython's machinery, this
2636 2636 should be set to False.
2637 2637 silent : bool
2638 2638 If True, avoid side-effects, such as implicit displayhooks and
2639 2639 and logging. silent=True forces store_history=False.
2640 2640 shell_futures : bool
2641 2641 If True, the code will share future statements with the interactive
2642 2642 shell. It will both be affected by previous __future__ imports, and
2643 2643 any __future__ imports in the code will affect the shell. If False,
2644 2644 __future__ imports are not shared in either direction.
2645 2645 """
2646 2646 if (not raw_cell) or raw_cell.isspace():
2647 2647 return
2648 2648
2649 2649 if silent:
2650 2650 store_history = False
2651 2651
2652 self.input_transformer_manager.push(raw_cell)
2653 cell = self.input_transformer_manager.source_reset()
2652 # If any of our input transformation (input_transformer_manager or
2653 # prefilter_manager) raises an exception, we store it in this variable
2654 # so that we can display the error after logging the input and storing
2655 # it in the history.
2656 preprocessing_exc_tuple = None
2657 try:
2658 # Static input transformations
2659 cell = self.input_transformer_manager.transform_cell(raw_cell)
2660 except SyntaxError:
2661 preprocessing_exc_tuple = sys.exc_info()
2662 cell = raw_cell # cell has to exist so it can be stored/logged
2663 else:
2664 if len(cell.splitlines()) == 1:
2665 # Dynamic transformations - only applied for single line commands
2666 with self.builtin_trap:
2667 try:
2668 # use prefilter_lines to handle trailing newlines
2669 # restore trailing newline for ast.parse
2670 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2671 except Exception:
2672 # don't allow prefilter errors to crash IPython
2673 preprocessing_exc_tuple = sys.exc_info()
2674
2675 # Store raw and processed history
2676 if store_history:
2677 self.history_manager.store_inputs(self.execution_count,
2678 cell, raw_cell)
2679 if not silent:
2680 self.logger.log(cell, raw_cell)
2681
2682 # Display the exception if input processing failed.
2683 if preprocessing_exc_tuple is not None:
2684 self.showtraceback(preprocessing_exc_tuple)
2685 if store_history:
2686 self.execution_count += 1
2687 return
2654 2688
2655 2689 # Our own compiler remembers the __future__ environment. If we want to
2656 2690 # run code with a separate __future__ environment, use the default
2657 2691 # compiler
2658 2692 compiler = self.compile if shell_futures else CachingCompiler()
2659 2693
2660 2694 with self.builtin_trap:
2661 prefilter_failed = False
2662 if len(cell.splitlines()) == 1:
2663 try:
2664 # use prefilter_lines to handle trailing newlines
2665 # restore trailing newline for ast.parse
2666 cell = self.prefilter_manager.prefilter_lines(cell) + '\n'
2667 except AliasError as e:
2668 error(e)
2669 prefilter_failed = True
2670 except Exception:
2671 # don't allow prefilter errors to crash IPython
2672 self.showtraceback()
2673 prefilter_failed = True
2674
2675 # Store raw and processed history
2676 if store_history:
2677 self.history_manager.store_inputs(self.execution_count,
2678 cell, raw_cell)
2679 if not silent:
2680 self.logger.log(cell, raw_cell)
2695 cell_name = self.compile.cache(cell, self.execution_count)
2681 2696
2682 if not prefilter_failed:
2683 # don't run if prefilter failed
2684 cell_name = self.compile.cache(cell, self.execution_count)
2685
2686 with self.display_trap:
2697 with self.display_trap:
2698 # Compile to bytecode
2699 try:
2700 code_ast = compiler.ast_parse(cell, filename=cell_name)
2701 except IndentationError:
2702 self.showindentationerror()
2703 if store_history:
2704 self.execution_count += 1
2705 return None
2706 except (OverflowError, SyntaxError, ValueError, TypeError,
2707 MemoryError):
2708 self.showsyntaxerror()
2709 if store_history:
2710 self.execution_count += 1
2711 return None
2712
2713 # Apply AST transformations
2714 code_ast = self.transform_ast(code_ast)
2715
2716 # Execute the user code
2717 interactivity = "none" if silent else self.ast_node_interactivity
2718 self.run_ast_nodes(code_ast.body, cell_name,
2719 interactivity=interactivity, compiler=compiler)
2720
2721 # Execute any registered post-execution functions.
2722 # unless we are silent
2723 post_exec = [] if silent else iteritems(self._post_execute)
2724
2725 for func, status in post_exec:
2726 if self.disable_failing_post_execute and not status:
2727 continue
2687 2728 try:
2688 code_ast = compiler.ast_parse(cell, filename=cell_name)
2689 except IndentationError:
2690 self.showindentationerror()
2691 if store_history:
2692 self.execution_count += 1
2693 return None
2694 except (OverflowError, SyntaxError, ValueError, TypeError,
2695 MemoryError):
2696 self.showsyntaxerror()
2697 if store_history:
2698 self.execution_count += 1
2699 return None
2700
2701 code_ast = self.transform_ast(code_ast)
2702
2703 interactivity = "none" if silent else self.ast_node_interactivity
2704 self.run_ast_nodes(code_ast.body, cell_name,
2705 interactivity=interactivity, compiler=compiler)
2706
2707 # Execute any registered post-execution functions.
2708 # unless we are silent
2709 post_exec = [] if silent else iteritems(self._post_execute)
2710
2711 for func, status in post_exec:
2712 if self.disable_failing_post_execute and not status:
2713 continue
2714 try:
2715 func()
2716 except KeyboardInterrupt:
2717 print("\nKeyboardInterrupt", file=io.stderr)
2718 except Exception:
2719 # register as failing:
2720 self._post_execute[func] = False
2721 self.showtraceback()
2722 print('\n'.join([
2723 "post-execution function %r produced an error." % func,
2724 "If this problem persists, you can disable failing post-exec functions with:",
2725 "",
2726 " get_ipython().disable_failing_post_execute = True"
2727 ]), file=io.stderr)
2729 func()
2730 except KeyboardInterrupt:
2731 print("\nKeyboardInterrupt", file=io.stderr)
2732 except Exception:
2733 # register as failing:
2734 self._post_execute[func] = False
2735 self.showtraceback()
2736 print('\n'.join([
2737 "post-execution function %r produced an error." % func,
2738 "If this problem persists, you can disable failing post-exec functions with:",
2739 "",
2740 " get_ipython().disable_failing_post_execute = True"
2741 ]), file=io.stderr)
2728 2742
2729 2743 if store_history:
2730 2744 # Write output to the database. Does nothing unless
2731 2745 # history output logging is enabled.
2732 2746 self.history_manager.store_output(self.execution_count)
2733 2747 # Each cell is a *single* input, regardless of how many lines it has
2734 2748 self.execution_count += 1
2735 2749
2736 2750 def transform_ast(self, node):
2737 2751 """Apply the AST transformations from self.ast_transformers
2738 2752
2739 2753 Parameters
2740 2754 ----------
2741 2755 node : ast.Node
2742 2756 The root node to be transformed. Typically called with the ast.Module
2743 2757 produced by parsing user input.
2744 2758
2745 2759 Returns
2746 2760 -------
2747 2761 An ast.Node corresponding to the node it was called with. Note that it
2748 2762 may also modify the passed object, so don't rely on references to the
2749 2763 original AST.
2750 2764 """
2751 2765 for transformer in self.ast_transformers:
2752 2766 try:
2753 2767 node = transformer.visit(node)
2754 2768 except Exception:
2755 2769 warn("AST transformer %r threw an error. It will be unregistered." % transformer)
2756 2770 self.ast_transformers.remove(transformer)
2757 2771
2758 2772 if self.ast_transformers:
2759 2773 ast.fix_missing_locations(node)
2760 2774 return node
2761 2775
2762 2776
2763 2777 def run_ast_nodes(self, nodelist, cell_name, interactivity='last_expr',
2764 2778 compiler=compile):
2765 2779 """Run a sequence of AST nodes. The execution mode depends on the
2766 2780 interactivity parameter.
2767 2781
2768 2782 Parameters
2769 2783 ----------
2770 2784 nodelist : list
2771 2785 A sequence of AST nodes to run.
2772 2786 cell_name : str
2773 2787 Will be passed to the compiler as the filename of the cell. Typically
2774 2788 the value returned by ip.compile.cache(cell).
2775 2789 interactivity : str
2776 2790 'all', 'last', 'last_expr' or 'none', specifying which nodes should be
2777 2791 run interactively (displaying output from expressions). 'last_expr'
2778 2792 will run the last node interactively only if it is an expression (i.e.
2779 2793 expressions in loops or other blocks are not displayed. Other values
2780 2794 for this parameter will raise a ValueError.
2781 2795 compiler : callable
2782 2796 A function with the same interface as the built-in compile(), to turn
2783 2797 the AST nodes into code objects. Default is the built-in compile().
2784 2798 """
2785 2799 if not nodelist:
2786 2800 return
2787 2801
2788 2802 if interactivity == 'last_expr':
2789 2803 if isinstance(nodelist[-1], ast.Expr):
2790 2804 interactivity = "last"
2791 2805 else:
2792 2806 interactivity = "none"
2793 2807
2794 2808 if interactivity == 'none':
2795 2809 to_run_exec, to_run_interactive = nodelist, []
2796 2810 elif interactivity == 'last':
2797 2811 to_run_exec, to_run_interactive = nodelist[:-1], nodelist[-1:]
2798 2812 elif interactivity == 'all':
2799 2813 to_run_exec, to_run_interactive = [], nodelist
2800 2814 else:
2801 2815 raise ValueError("Interactivity was %r" % interactivity)
2802 2816
2803 2817 exec_count = self.execution_count
2804 2818
2805 2819 try:
2806 2820 for i, node in enumerate(to_run_exec):
2807 2821 mod = ast.Module([node])
2808 2822 code = compiler(mod, cell_name, "exec")
2809 2823 if self.run_code(code):
2810 2824 return True
2811 2825
2812 2826 for i, node in enumerate(to_run_interactive):
2813 2827 mod = ast.Interactive([node])
2814 2828 code = compiler(mod, cell_name, "single")
2815 2829 if self.run_code(code):
2816 2830 return True
2817 2831
2818 2832 # Flush softspace
2819 2833 if softspace(sys.stdout, 0):
2820 2834 print()
2821 2835
2822 2836 except:
2823 2837 # It's possible to have exceptions raised here, typically by
2824 2838 # compilation of odd code (such as a naked 'return' outside a
2825 2839 # function) that did parse but isn't valid. Typically the exception
2826 2840 # is a SyntaxError, but it's safest just to catch anything and show
2827 2841 # the user a traceback.
2828 2842
2829 2843 # We do only one try/except outside the loop to minimize the impact
2830 2844 # on runtime, and also because if any node in the node list is
2831 2845 # broken, we should stop execution completely.
2832 2846 self.showtraceback()
2833 2847
2834 2848 return False
2835 2849
2836 2850 def run_code(self, code_obj):
2837 2851 """Execute a code object.
2838 2852
2839 2853 When an exception occurs, self.showtraceback() is called to display a
2840 2854 traceback.
2841 2855
2842 2856 Parameters
2843 2857 ----------
2844 2858 code_obj : code object
2845 2859 A compiled code object, to be executed
2846 2860
2847 2861 Returns
2848 2862 -------
2849 2863 False : successful execution.
2850 2864 True : an error occurred.
2851 2865 """
2852 2866
2853 2867 # Set our own excepthook in case the user code tries to call it
2854 2868 # directly, so that the IPython crash handler doesn't get triggered
2855 2869 old_excepthook,sys.excepthook = sys.excepthook, self.excepthook
2856 2870
2857 2871 # we save the original sys.excepthook in the instance, in case config
2858 2872 # code (such as magics) needs access to it.
2859 2873 self.sys_excepthook = old_excepthook
2860 2874 outflag = 1 # happens in more places, so it's easier as default
2861 2875 try:
2862 2876 try:
2863 2877 self.hooks.pre_run_code_hook()
2864 2878 #rprint('Running code', repr(code_obj)) # dbg
2865 2879 exec(code_obj, self.user_global_ns, self.user_ns)
2866 2880 finally:
2867 2881 # Reset our crash handler in place
2868 2882 sys.excepthook = old_excepthook
2869 2883 except SystemExit:
2870 2884 self.showtraceback(exception_only=True)
2871 2885 warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1)
2872 2886 except self.custom_exceptions:
2873 2887 etype,value,tb = sys.exc_info()
2874 2888 self.CustomTB(etype,value,tb)
2875 2889 except:
2876 2890 self.showtraceback()
2877 2891 else:
2878 2892 outflag = 0
2879 2893 return outflag
2880 2894
2881 2895 # For backwards compatibility
2882 2896 runcode = run_code
2883 2897
2884 2898 #-------------------------------------------------------------------------
2885 2899 # Things related to GUI support and pylab
2886 2900 #-------------------------------------------------------------------------
2887 2901
2888 2902 def enable_gui(self, gui=None):
2889 2903 raise NotImplementedError('Implement enable_gui in a subclass')
2890 2904
2891 2905 def enable_matplotlib(self, gui=None):
2892 2906 """Enable interactive matplotlib and inline figure support.
2893 2907
2894 2908 This takes the following steps:
2895 2909
2896 2910 1. select the appropriate eventloop and matplotlib backend
2897 2911 2. set up matplotlib for interactive use with that backend
2898 2912 3. configure formatters for inline figure display
2899 2913 4. enable the selected gui eventloop
2900 2914
2901 2915 Parameters
2902 2916 ----------
2903 2917 gui : optional, string
2904 2918 If given, dictates the choice of matplotlib GUI backend to use
2905 2919 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2906 2920 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2907 2921 matplotlib (as dictated by the matplotlib build-time options plus the
2908 2922 user's matplotlibrc configuration file). Note that not all backends
2909 2923 make sense in all contexts, for example a terminal ipython can't
2910 2924 display figures inline.
2911 2925 """
2912 2926 from IPython.core import pylabtools as pt
2913 2927 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
2914 2928
2915 2929 if gui != 'inline':
2916 2930 # If we have our first gui selection, store it
2917 2931 if self.pylab_gui_select is None:
2918 2932 self.pylab_gui_select = gui
2919 2933 # Otherwise if they are different
2920 2934 elif gui != self.pylab_gui_select:
2921 2935 print ('Warning: Cannot change to a different GUI toolkit: %s.'
2922 2936 ' Using %s instead.' % (gui, self.pylab_gui_select))
2923 2937 gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
2924 2938
2925 2939 pt.activate_matplotlib(backend)
2926 2940 pt.configure_inline_support(self, backend)
2927 2941
2928 2942 # Now we must activate the gui pylab wants to use, and fix %run to take
2929 2943 # plot updates into account
2930 2944 self.enable_gui(gui)
2931 2945 self.magics_manager.registry['ExecutionMagics'].default_runner = \
2932 2946 pt.mpl_runner(self.safe_execfile)
2933 2947
2934 2948 return gui, backend
2935 2949
2936 2950 def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
2937 2951 """Activate pylab support at runtime.
2938 2952
2939 2953 This turns on support for matplotlib, preloads into the interactive
2940 2954 namespace all of numpy and pylab, and configures IPython to correctly
2941 2955 interact with the GUI event loop. The GUI backend to be used can be
2942 2956 optionally selected with the optional ``gui`` argument.
2943 2957
2944 2958 This method only adds preloading the namespace to InteractiveShell.enable_matplotlib.
2945 2959
2946 2960 Parameters
2947 2961 ----------
2948 2962 gui : optional, string
2949 2963 If given, dictates the choice of matplotlib GUI backend to use
2950 2964 (should be one of IPython's supported backends, 'qt', 'osx', 'tk',
2951 2965 'gtk', 'wx' or 'inline'), otherwise we use the default chosen by
2952 2966 matplotlib (as dictated by the matplotlib build-time options plus the
2953 2967 user's matplotlibrc configuration file). Note that not all backends
2954 2968 make sense in all contexts, for example a terminal ipython can't
2955 2969 display figures inline.
2956 2970 import_all : optional, bool, default: True
2957 2971 Whether to do `from numpy import *` and `from pylab import *`
2958 2972 in addition to module imports.
2959 2973 welcome_message : deprecated
2960 2974 This argument is ignored, no welcome message will be displayed.
2961 2975 """
2962 2976 from IPython.core.pylabtools import import_pylab
2963 2977
2964 2978 gui, backend = self.enable_matplotlib(gui)
2965 2979
2966 2980 # We want to prevent the loading of pylab to pollute the user's
2967 2981 # namespace as shown by the %who* magics, so we execute the activation
2968 2982 # code in an empty namespace, and we update *both* user_ns and
2969 2983 # user_ns_hidden with this information.
2970 2984 ns = {}
2971 2985 import_pylab(ns, import_all)
2972 2986 # warn about clobbered names
2973 2987 ignored = set(["__builtins__"])
2974 2988 both = set(ns).intersection(self.user_ns).difference(ignored)
2975 2989 clobbered = [ name for name in both if self.user_ns[name] is not ns[name] ]
2976 2990 self.user_ns.update(ns)
2977 2991 self.user_ns_hidden.update(ns)
2978 2992 return gui, backend, clobbered
2979 2993
2980 2994 #-------------------------------------------------------------------------
2981 2995 # Utilities
2982 2996 #-------------------------------------------------------------------------
2983 2997
2984 2998 def var_expand(self, cmd, depth=0, formatter=DollarFormatter()):
2985 2999 """Expand python variables in a string.
2986 3000
2987 3001 The depth argument indicates how many frames above the caller should
2988 3002 be walked to look for the local namespace where to expand variables.
2989 3003
2990 3004 The global namespace for expansion is always the user's interactive
2991 3005 namespace.
2992 3006 """
2993 3007 ns = self.user_ns.copy()
2994 3008 ns.update(sys._getframe(depth+1).f_locals)
2995 3009 try:
2996 3010 # We have to use .vformat() here, because 'self' is a valid and common
2997 3011 # name, and expanding **ns for .format() would make it collide with
2998 3012 # the 'self' argument of the method.
2999 3013 cmd = formatter.vformat(cmd, args=[], kwargs=ns)
3000 3014 except Exception:
3001 3015 # if formatter couldn't format, just let it go untransformed
3002 3016 pass
3003 3017 return cmd
3004 3018
3005 3019 def mktempfile(self, data=None, prefix='ipython_edit_'):
3006 3020 """Make a new tempfile and return its filename.
3007 3021
3008 3022 This makes a call to tempfile.mkstemp (created in a tempfile.mkdtemp),
3009 3023 but it registers the created filename internally so ipython cleans it up
3010 3024 at exit time.
3011 3025
3012 3026 Optional inputs:
3013 3027
3014 3028 - data(None): if data is given, it gets written out to the temp file
3015 3029 immediately, and the file is closed again."""
3016 3030
3017 3031 dirname = tempfile.mkdtemp(prefix=prefix)
3018 3032 self.tempdirs.append(dirname)
3019 3033
3020 3034 handle, filename = tempfile.mkstemp('.py', prefix, dir=dirname)
3021 3035 self.tempfiles.append(filename)
3022 3036
3023 3037 if data:
3024 3038 tmp_file = open(filename,'w')
3025 3039 tmp_file.write(data)
3026 3040 tmp_file.close()
3027 3041 return filename
3028 3042
3029 3043 # TODO: This should be removed when Term is refactored.
3030 3044 def write(self,data):
3031 3045 """Write a string to the default output"""
3032 3046 io.stdout.write(data)
3033 3047
3034 3048 # TODO: This should be removed when Term is refactored.
3035 3049 def write_err(self,data):
3036 3050 """Write a string to the default error output"""
3037 3051 io.stderr.write(data)
3038 3052
3039 3053 def ask_yes_no(self, prompt, default=None):
3040 3054 if self.quiet:
3041 3055 return True
3042 3056 return ask_yes_no(prompt,default)
3043 3057
3044 3058 def show_usage(self):
3045 3059 """Show a usage message"""
3046 3060 page.page(IPython.core.usage.interactive_usage)
3047 3061
3048 3062 def extract_input_lines(self, range_str, raw=False):
3049 3063 """Return as a string a set of input history slices.
3050 3064
3051 3065 Parameters
3052 3066 ----------
3053 3067 range_str : string
3054 3068 The set of slices is given as a string, like "~5/6-~4/2 4:8 9",
3055 3069 since this function is for use by magic functions which get their
3056 3070 arguments as strings. The number before the / is the session
3057 3071 number: ~n goes n back from the current session.
3058 3072
3059 3073 raw : bool, optional
3060 3074 By default, the processed input is used. If this is true, the raw
3061 3075 input history is used instead.
3062 3076
3063 3077 Notes
3064 3078 -----
3065 3079
3066 3080 Slices can be described with two notations:
3067 3081
3068 3082 * ``N:M`` -> standard python form, means including items N...(M-1).
3069 3083 * ``N-M`` -> include items N..M (closed endpoint).
3070 3084 """
3071 3085 lines = self.history_manager.get_range_by_str(range_str, raw=raw)
3072 3086 return "\n".join(x for _, _, x in lines)
3073 3087
3074 3088 def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True):
3075 3089 """Get a code string from history, file, url, or a string or macro.
3076 3090
3077 3091 This is mainly used by magic functions.
3078 3092
3079 3093 Parameters
3080 3094 ----------
3081 3095
3082 3096 target : str
3083 3097
3084 3098 A string specifying code to retrieve. This will be tried respectively
3085 3099 as: ranges of input history (see %history for syntax), url,
3086 3100 correspnding .py file, filename, or an expression evaluating to a
3087 3101 string or Macro in the user namespace.
3088 3102
3089 3103 raw : bool
3090 3104 If true (default), retrieve raw history. Has no effect on the other
3091 3105 retrieval mechanisms.
3092 3106
3093 3107 py_only : bool (default False)
3094 3108 Only try to fetch python code, do not try alternative methods to decode file
3095 3109 if unicode fails.
3096 3110
3097 3111 Returns
3098 3112 -------
3099 3113 A string of code.
3100 3114
3101 3115 ValueError is raised if nothing is found, and TypeError if it evaluates
3102 3116 to an object of another type. In each case, .args[0] is a printable
3103 3117 message.
3104 3118 """
3105 3119 code = self.extract_input_lines(target, raw=raw) # Grab history
3106 3120 if code:
3107 3121 return code
3108 3122 utarget = unquote_filename(target)
3109 3123 try:
3110 3124 if utarget.startswith(('http://', 'https://')):
3111 3125 return openpy.read_py_url(utarget, skip_encoding_cookie=skip_encoding_cookie)
3112 3126 except UnicodeDecodeError:
3113 3127 if not py_only :
3114 3128 # Deferred import
3115 3129 try:
3116 3130 from urllib.request import urlopen # Py3
3117 3131 except ImportError:
3118 3132 from urllib import urlopen
3119 3133 response = urlopen(target)
3120 3134 return response.read().decode('latin1')
3121 3135 raise ValueError(("'%s' seem to be unreadable.") % utarget)
3122 3136
3123 3137 potential_target = [target]
3124 3138 try :
3125 3139 potential_target.insert(0,get_py_filename(target))
3126 3140 except IOError:
3127 3141 pass
3128 3142
3129 3143 for tgt in potential_target :
3130 3144 if os.path.isfile(tgt): # Read file
3131 3145 try :
3132 3146 return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
3133 3147 except UnicodeDecodeError :
3134 3148 if not py_only :
3135 3149 with io_open(tgt,'r', encoding='latin1') as f :
3136 3150 return f.read()
3137 3151 raise ValueError(("'%s' seem to be unreadable.") % target)
3138 3152 elif os.path.isdir(os.path.expanduser(tgt)):
3139 3153 raise ValueError("'%s' is a directory, not a regular file." % target)
3140 3154
3141 3155 try: # User namespace
3142 3156 codeobj = eval(target, self.user_ns)
3143 3157 except Exception:
3144 3158 raise ValueError(("'%s' was not found in history, as a file, url, "
3145 3159 "nor in the user namespace.") % target)
3146 3160 if isinstance(codeobj, string_types):
3147 3161 return codeobj
3148 3162 elif isinstance(codeobj, Macro):
3149 3163 return codeobj.value
3150 3164
3151 3165 raise TypeError("%s is neither a string nor a macro." % target,
3152 3166 codeobj)
3153 3167
3154 3168 #-------------------------------------------------------------------------
3155 3169 # Things related to IPython exiting
3156 3170 #-------------------------------------------------------------------------
3157 3171 def atexit_operations(self):
3158 3172 """This will be executed at the time of exit.
3159 3173
3160 3174 Cleanup operations and saving of persistent data that is done
3161 3175 unconditionally by IPython should be performed here.
3162 3176
3163 3177 For things that may depend on startup flags or platform specifics (such
3164 3178 as having readline or not), register a separate atexit function in the
3165 3179 code that has the appropriate information, rather than trying to
3166 3180 clutter
3167 3181 """
3168 3182 # Close the history session (this stores the end time and line count)
3169 3183 # this must be *before* the tempfile cleanup, in case of temporary
3170 3184 # history db
3171 3185 self.history_manager.end_session()
3172 3186
3173 3187 # Cleanup all tempfiles and folders left around
3174 3188 for tfile in self.tempfiles:
3175 3189 try:
3176 3190 os.unlink(tfile)
3177 3191 except OSError:
3178 3192 pass
3179 3193
3180 3194 for tdir in self.tempdirs:
3181 3195 try:
3182 3196 os.rmdir(tdir)
3183 3197 except OSError:
3184 3198 pass
3185 3199
3186 3200 # Clear all user namespaces to release all references cleanly.
3187 3201 self.reset(new_session=False)
3188 3202
3189 3203 # Run user hooks
3190 3204 self.hooks.shutdown_hook()
3191 3205
3192 3206 def cleanup(self):
3193 3207 self.restore_sys_module_state()
3194 3208
3195 3209
3196 3210 class InteractiveShellABC(with_metaclass(abc.ABCMeta, object)):
3197 3211 """An abstract base class for InteractiveShell."""
3198 3212
3199 3213 InteractiveShellABC.register(InteractiveShell)
@@ -1,584 +1,585 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the inputsplitter module.
3 3
4 4 Authors
5 5 -------
6 6 * Fernando Perez
7 7 * Robert Kern
8 8 """
9 9 from __future__ import print_function
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2010-2011 The IPython Development Team
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20 # stdlib
21 21 import unittest
22 22 import sys
23 23
24 24 # Third party
25 25 import nose.tools as nt
26 26
27 27 # Our own
28 28 from IPython.core import inputsplitter as isp
29 29 from IPython.core.tests.test_inputtransformer import syntax, syntax_ml
30 30 from IPython.testing import tools as tt
31 31 from IPython.utils import py3compat
32 32 from IPython.utils.py3compat import string_types, input
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Semi-complete examples (also used as tests)
36 36 #-----------------------------------------------------------------------------
37 37
38 38 # Note: at the bottom, there's a slightly more complete version of this that
39 39 # can be useful during development of code here.
40 40
41 41 def mini_interactive_loop(input_func):
42 42 """Minimal example of the logic of an interactive interpreter loop.
43 43
44 44 This serves as an example, and it is used by the test system with a fake
45 45 raw_input that simulates interactive input."""
46 46
47 47 from IPython.core.inputsplitter import InputSplitter
48 48
49 49 isp = InputSplitter()
50 50 # In practice, this input loop would be wrapped in an outside loop to read
51 51 # input indefinitely, until some exit/quit command was issued. Here we
52 52 # only illustrate the basic inner loop.
53 53 while isp.push_accepts_more():
54 54 indent = ' '*isp.indent_spaces
55 55 prompt = '>>> ' + indent
56 56 line = indent + input_func(prompt)
57 57 isp.push(line)
58 58
59 59 # Here we just return input so we can use it in a test suite, but a real
60 60 # interpreter would instead send it for execution somewhere.
61 61 src = isp.source_reset()
62 62 #print 'Input source was:\n', src # dbg
63 63 return src
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # Test utilities, just for local use
67 67 #-----------------------------------------------------------------------------
68 68
69 69 def assemble(block):
70 70 """Assemble a block into multi-line sub-blocks."""
71 71 return ['\n'.join(sub_block)+'\n' for sub_block in block]
72 72
73 73
74 74 def pseudo_input(lines):
75 75 """Return a function that acts like raw_input but feeds the input list."""
76 76 ilines = iter(lines)
77 77 def raw_in(prompt):
78 78 try:
79 79 return next(ilines)
80 80 except StopIteration:
81 81 return ''
82 82 return raw_in
83 83
84 84 #-----------------------------------------------------------------------------
85 85 # Tests
86 86 #-----------------------------------------------------------------------------
87 87 def test_spaces():
88 88 tests = [('', 0),
89 89 (' ', 1),
90 90 ('\n', 0),
91 91 (' \n', 1),
92 92 ('x', 0),
93 93 (' x', 1),
94 94 (' x',2),
95 95 (' x',4),
96 96 # Note: tabs are counted as a single whitespace!
97 97 ('\tx', 1),
98 98 ('\t x', 2),
99 99 ]
100 100 tt.check_pairs(isp.num_ini_spaces, tests)
101 101
102 102
103 103 def test_remove_comments():
104 104 tests = [('text', 'text'),
105 105 ('text # comment', 'text '),
106 106 ('text # comment\n', 'text \n'),
107 107 ('text # comment \n', 'text \n'),
108 108 ('line # c \nline\n','line \nline\n'),
109 109 ('line # c \nline#c2 \nline\nline #c\n\n',
110 110 'line \nline\nline\nline \n\n'),
111 111 ]
112 112 tt.check_pairs(isp.remove_comments, tests)
113 113
114 114
115 115 def test_get_input_encoding():
116 116 encoding = isp.get_input_encoding()
117 117 nt.assert_true(isinstance(encoding, string_types))
118 118 # simple-minded check that at least encoding a simple string works with the
119 119 # encoding we got.
120 120 nt.assert_equal(u'test'.encode(encoding), b'test')
121 121
122 122
123 123 class NoInputEncodingTestCase(unittest.TestCase):
124 124 def setUp(self):
125 125 self.old_stdin = sys.stdin
126 126 class X: pass
127 127 fake_stdin = X()
128 128 sys.stdin = fake_stdin
129 129
130 130 def test(self):
131 131 # Verify that if sys.stdin has no 'encoding' attribute we do the right
132 132 # thing
133 133 enc = isp.get_input_encoding()
134 134 self.assertEqual(enc, 'ascii')
135 135
136 136 def tearDown(self):
137 137 sys.stdin = self.old_stdin
138 138
139 139
140 140 class InputSplitterTestCase(unittest.TestCase):
141 141 def setUp(self):
142 142 self.isp = isp.InputSplitter()
143 143
144 144 def test_reset(self):
145 145 isp = self.isp
146 146 isp.push('x=1')
147 147 isp.reset()
148 148 self.assertEqual(isp._buffer, [])
149 149 self.assertEqual(isp.indent_spaces, 0)
150 150 self.assertEqual(isp.source, '')
151 151 self.assertEqual(isp.code, None)
152 152 self.assertEqual(isp._is_complete, False)
153 153
154 154 def test_source(self):
155 155 self.isp._store('1')
156 156 self.isp._store('2')
157 157 self.assertEqual(self.isp.source, '1\n2\n')
158 158 self.assertTrue(len(self.isp._buffer)>0)
159 159 self.assertEqual(self.isp.source_reset(), '1\n2\n')
160 160 self.assertEqual(self.isp._buffer, [])
161 161 self.assertEqual(self.isp.source, '')
162 162
163 163 def test_indent(self):
164 164 isp = self.isp # shorthand
165 165 isp.push('x=1')
166 166 self.assertEqual(isp.indent_spaces, 0)
167 167 isp.push('if 1:\n x=1')
168 168 self.assertEqual(isp.indent_spaces, 4)
169 169 isp.push('y=2\n')
170 170 self.assertEqual(isp.indent_spaces, 0)
171 171
172 172 def test_indent2(self):
173 173 isp = self.isp
174 174 isp.push('if 1:')
175 175 self.assertEqual(isp.indent_spaces, 4)
176 176 isp.push(' x=1')
177 177 self.assertEqual(isp.indent_spaces, 4)
178 178 # Blank lines shouldn't change the indent level
179 179 isp.push(' '*2)
180 180 self.assertEqual(isp.indent_spaces, 4)
181 181
182 182 def test_indent3(self):
183 183 isp = self.isp
184 184 # When a multiline statement contains parens or multiline strings, we
185 185 # shouldn't get confused.
186 186 isp.push("if 1:")
187 187 isp.push(" x = (1+\n 2)")
188 188 self.assertEqual(isp.indent_spaces, 4)
189 189
190 190 def test_indent4(self):
191 191 isp = self.isp
192 192 # whitespace after ':' should not screw up indent level
193 193 isp.push('if 1: \n x=1')
194 194 self.assertEqual(isp.indent_spaces, 4)
195 195 isp.push('y=2\n')
196 196 self.assertEqual(isp.indent_spaces, 0)
197 197 isp.push('if 1:\t\n x=1')
198 198 self.assertEqual(isp.indent_spaces, 4)
199 199 isp.push('y=2\n')
200 200 self.assertEqual(isp.indent_spaces, 0)
201 201
202 202 def test_dedent_pass(self):
203 203 isp = self.isp # shorthand
204 204 # should NOT cause dedent
205 205 isp.push('if 1:\n passes = 5')
206 206 self.assertEqual(isp.indent_spaces, 4)
207 207 isp.push('if 1:\n pass')
208 208 self.assertEqual(isp.indent_spaces, 0)
209 209 isp.push('if 1:\n pass ')
210 210 self.assertEqual(isp.indent_spaces, 0)
211 211
212 212 def test_dedent_break(self):
213 213 isp = self.isp # shorthand
214 214 # should NOT cause dedent
215 215 isp.push('while 1:\n breaks = 5')
216 216 self.assertEqual(isp.indent_spaces, 4)
217 217 isp.push('while 1:\n break')
218 218 self.assertEqual(isp.indent_spaces, 0)
219 219 isp.push('while 1:\n break ')
220 220 self.assertEqual(isp.indent_spaces, 0)
221 221
222 222 def test_dedent_continue(self):
223 223 isp = self.isp # shorthand
224 224 # should NOT cause dedent
225 225 isp.push('while 1:\n continues = 5')
226 226 self.assertEqual(isp.indent_spaces, 4)
227 227 isp.push('while 1:\n continue')
228 228 self.assertEqual(isp.indent_spaces, 0)
229 229 isp.push('while 1:\n continue ')
230 230 self.assertEqual(isp.indent_spaces, 0)
231 231
232 232 def test_dedent_raise(self):
233 233 isp = self.isp # shorthand
234 234 # should NOT cause dedent
235 235 isp.push('if 1:\n raised = 4')
236 236 self.assertEqual(isp.indent_spaces, 4)
237 237 isp.push('if 1:\n raise TypeError()')
238 238 self.assertEqual(isp.indent_spaces, 0)
239 239 isp.push('if 1:\n raise')
240 240 self.assertEqual(isp.indent_spaces, 0)
241 241 isp.push('if 1:\n raise ')
242 242 self.assertEqual(isp.indent_spaces, 0)
243 243
244 244 def test_dedent_return(self):
245 245 isp = self.isp # shorthand
246 246 # should NOT cause dedent
247 247 isp.push('if 1:\n returning = 4')
248 248 self.assertEqual(isp.indent_spaces, 4)
249 249 isp.push('if 1:\n return 5 + 493')
250 250 self.assertEqual(isp.indent_spaces, 0)
251 251 isp.push('if 1:\n return')
252 252 self.assertEqual(isp.indent_spaces, 0)
253 253 isp.push('if 1:\n return ')
254 254 self.assertEqual(isp.indent_spaces, 0)
255 255 isp.push('if 1:\n return(0)')
256 256 self.assertEqual(isp.indent_spaces, 0)
257 257
258 258 def test_push(self):
259 259 isp = self.isp
260 260 self.assertTrue(isp.push('x=1'))
261 261
262 262 def test_push2(self):
263 263 isp = self.isp
264 264 self.assertFalse(isp.push('if 1:'))
265 265 for line in [' x=1', '# a comment', ' y=2']:
266 266 print(line)
267 267 self.assertTrue(isp.push(line))
268 268
269 269 def test_push3(self):
270 270 isp = self.isp
271 271 isp.push('if True:')
272 272 isp.push(' a = 1')
273 273 self.assertFalse(isp.push('b = [1,'))
274 274
275 275 def test_push_accepts_more(self):
276 276 isp = self.isp
277 277 isp.push('x=1')
278 278 self.assertFalse(isp.push_accepts_more())
279 279
280 280 def test_push_accepts_more2(self):
281 281 isp = self.isp
282 282 isp.push('if 1:')
283 283 self.assertTrue(isp.push_accepts_more())
284 284 isp.push(' x=1')
285 285 self.assertTrue(isp.push_accepts_more())
286 286 isp.push('')
287 287 self.assertFalse(isp.push_accepts_more())
288 288
289 289 def test_push_accepts_more3(self):
290 290 isp = self.isp
291 291 isp.push("x = (2+\n3)")
292 292 self.assertFalse(isp.push_accepts_more())
293 293
294 294 def test_push_accepts_more4(self):
295 295 isp = self.isp
296 296 # When a multiline statement contains parens or multiline strings, we
297 297 # shouldn't get confused.
298 298 # FIXME: we should be able to better handle de-dents in statements like
299 299 # multiline strings and multiline expressions (continued with \ or
300 300 # parens). Right now we aren't handling the indentation tracking quite
301 301 # correctly with this, though in practice it may not be too much of a
302 302 # problem. We'll need to see.
303 303 isp.push("if 1:")
304 304 isp.push(" x = (2+")
305 305 isp.push(" 3)")
306 306 self.assertTrue(isp.push_accepts_more())
307 307 isp.push(" y = 3")
308 308 self.assertTrue(isp.push_accepts_more())
309 309 isp.push('')
310 310 self.assertFalse(isp.push_accepts_more())
311 311
312 312 def test_push_accepts_more5(self):
313 313 isp = self.isp
314 314 isp.push('try:')
315 315 isp.push(' a = 5')
316 316 isp.push('except:')
317 317 isp.push(' raise')
318 318 # We want to be able to add an else: block at this point, so it should
319 319 # wait for a blank line.
320 320 self.assertTrue(isp.push_accepts_more())
321 321
322 322 def test_continuation(self):
323 323 isp = self.isp
324 324 isp.push("import os, \\")
325 325 self.assertTrue(isp.push_accepts_more())
326 326 isp.push("sys")
327 327 self.assertFalse(isp.push_accepts_more())
328 328
329 329 def test_syntax_error(self):
330 330 isp = self.isp
331 331 # Syntax errors immediately produce a 'ready' block, so the invalid
332 332 # Python can be sent to the kernel for evaluation with possible ipython
333 333 # special-syntax conversion.
334 334 isp.push('run foo')
335 335 self.assertFalse(isp.push_accepts_more())
336 336
337 337 def test_unicode(self):
338 338 self.isp.push(u"PΓ©rez")
339 339 self.isp.push(u'\xc3\xa9')
340 340 self.isp.push(u"u'\xc3\xa9'")
341 341
342 342 def test_line_continuation(self):
343 343 """ Test issue #2108."""
344 344 isp = self.isp
345 345 # A blank line after a line continuation should not accept more
346 346 isp.push("1 \\\n\n")
347 347 self.assertFalse(isp.push_accepts_more())
348 348 # Whitespace after a \ is a SyntaxError. The only way to test that
349 349 # here is to test that push doesn't accept more (as with
350 350 # test_syntax_error() above).
351 351 isp.push(r"1 \ ")
352 352 self.assertFalse(isp.push_accepts_more())
353 353 # Even if the line is continuable (c.f. the regular Python
354 354 # interpreter)
355 355 isp.push(r"(1 \ ")
356 356 self.assertFalse(isp.push_accepts_more())
357 357
358 358 class InteractiveLoopTestCase(unittest.TestCase):
359 359 """Tests for an interactive loop like a python shell.
360 360 """
361 361 def check_ns(self, lines, ns):
362 362 """Validate that the given input lines produce the resulting namespace.
363 363
364 364 Note: the input lines are given exactly as they would be typed in an
365 365 auto-indenting environment, as mini_interactive_loop above already does
366 366 auto-indenting and prepends spaces to the input.
367 367 """
368 368 src = mini_interactive_loop(pseudo_input(lines))
369 369 test_ns = {}
370 370 exec(src, test_ns)
371 371 # We can't check that the provided ns is identical to the test_ns,
372 372 # because Python fills test_ns with extra keys (copyright, etc). But
373 373 # we can check that the given dict is *contained* in test_ns
374 374 for k,v in ns.items():
375 375 self.assertEqual(test_ns[k], v)
376 376
377 377 def test_simple(self):
378 378 self.check_ns(['x=1'], dict(x=1))
379 379
380 380 def test_simple2(self):
381 381 self.check_ns(['if 1:', 'x=2'], dict(x=2))
382 382
383 383 def test_xy(self):
384 384 self.check_ns(['x=1; y=2'], dict(x=1, y=2))
385 385
386 386 def test_abc(self):
387 387 self.check_ns(['if 1:','a=1','b=2','c=3'], dict(a=1, b=2, c=3))
388 388
389 389 def test_multi(self):
390 390 self.check_ns(['x =(1+','1+','2)'], dict(x=4))
391 391
392 392
393 393 class IPythonInputTestCase(InputSplitterTestCase):
394 394 """By just creating a new class whose .isp is a different instance, we
395 395 re-run the same test battery on the new input splitter.
396 396
397 397 In addition, this runs the tests over the syntax and syntax_ml dicts that
398 398 were tested by individual functions, as part of the OO interface.
399 399
400 400 It also makes some checks on the raw buffer storage.
401 401 """
402 402
403 403 def setUp(self):
404 404 self.isp = isp.IPythonInputSplitter()
405 405
406 406 def test_syntax(self):
407 407 """Call all single-line syntax tests from the main object"""
408 408 isp = self.isp
409 409 for example in syntax.values():
410 410 for raw, out_t in example:
411 411 if raw.startswith(' '):
412 412 continue
413 413
414 414 isp.push(raw+'\n')
415 out, out_raw = isp.source_raw_reset()
415 out_raw = isp.source_raw
416 out = isp.source_reset()
416 417 self.assertEqual(out.rstrip(), out_t,
417 418 tt.pair_fail_msg.format("inputsplitter",raw, out_t, out))
418 419 self.assertEqual(out_raw.rstrip(), raw.rstrip())
419 420
420 421 def test_syntax_multiline(self):
421 422 isp = self.isp
422 423 for example in syntax_ml.values():
423 424 for line_pairs in example:
424 425 out_t_parts = []
425 426 raw_parts = []
426 427 for lraw, out_t_part in line_pairs:
427 428 if out_t_part is not None:
428 429 out_t_parts.append(out_t_part)
429 430
430 431 if lraw is not None:
431 432 isp.push(lraw)
432 433 raw_parts.append(lraw)
433 434
434 out, out_raw = isp.source_raw_reset()
435 out_raw = isp.source_raw
436 out = isp.source_reset()
435 437 out_t = '\n'.join(out_t_parts).rstrip()
436 438 raw = '\n'.join(raw_parts).rstrip()
437 439 self.assertEqual(out.rstrip(), out_t)
438 440 self.assertEqual(out_raw.rstrip(), raw)
439 441
440 442 def test_syntax_multiline_cell(self):
441 443 isp = self.isp
442 444 for example in syntax_ml.values():
443 445
444 446 out_t_parts = []
445 447 for line_pairs in example:
446 448 raw = '\n'.join(r for r, _ in line_pairs if r is not None)
447 449 out_t = '\n'.join(t for _,t in line_pairs if t is not None)
448 450 out = isp.transform_cell(raw)
449 451 # Match ignoring trailing whitespace
450 452 self.assertEqual(out.rstrip(), out_t.rstrip())
451 453
452 454 def test_cellmagic_preempt(self):
453 455 isp = self.isp
454 456 for raw, name, line, cell in [
455 457 ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'),
456 458 ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'),
457 459 (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'),
458 460 ("%%cellm \n>>>hi", u'cellm', u'', u'hi'),
459 461 ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'),
460 462 ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'),
461 463 ]:
462 464 expected = "get_ipython().run_cell_magic(%r, %r, %r)" % (
463 465 name, line, cell
464 466 )
465 467 out = isp.transform_cell(raw)
466 468 self.assertEqual(out.rstrip(), expected.rstrip())
467 469
468 470
469 471
470 472 #-----------------------------------------------------------------------------
471 473 # Main - use as a script, mostly for developer experiments
472 474 #-----------------------------------------------------------------------------
473 475
474 476 if __name__ == '__main__':
475 477 # A simple demo for interactive experimentation. This code will not get
476 478 # picked up by any test suite.
477 479 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
478 480
479 481 # configure here the syntax to use, prompt and whether to autoindent
480 482 #isp, start_prompt = InputSplitter(), '>>> '
481 483 isp, start_prompt = IPythonInputSplitter(), 'In> '
482 484
483 485 autoindent = True
484 486 #autoindent = False
485 487
486 488 try:
487 489 while True:
488 490 prompt = start_prompt
489 491 while isp.push_accepts_more():
490 492 indent = ' '*isp.indent_spaces
491 493 if autoindent:
492 494 line = indent + input(prompt+indent)
493 495 else:
494 496 line = input(prompt)
495 497 isp.push(line)
496 498 prompt = '... '
497 499
498 500 # Here we just return input so we can use it in a test suite, but a
499 501 # real interpreter would instead send it for execution somewhere.
500 502 #src = isp.source; raise EOFError # dbg
501 src, raw = isp.source_raw_reset()
503 raw = isp.source_raw
504 src = isp.source_reset()
502 505 print('Input source was:\n', src)
503 506 print('Raw source was:\n', raw)
504 507 except EOFError:
505 508 print('Bye')
506 509
507 510 # Tests for cell magics support
508 511
509 512 def test_last_blank():
510 513 nt.assert_false(isp.last_blank(''))
511 514 nt.assert_false(isp.last_blank('abc'))
512 515 nt.assert_false(isp.last_blank('abc\n'))
513 516 nt.assert_false(isp.last_blank('abc\na'))
514 517
515 518 nt.assert_true(isp.last_blank('\n'))
516 519 nt.assert_true(isp.last_blank('\n '))
517 520 nt.assert_true(isp.last_blank('abc\n '))
518 521 nt.assert_true(isp.last_blank('abc\n\n'))
519 522 nt.assert_true(isp.last_blank('abc\nd\n\n'))
520 523 nt.assert_true(isp.last_blank('abc\nd\ne\n\n'))
521 524 nt.assert_true(isp.last_blank('abc \n \n \n\n'))
522 525
523 526
524 527 def test_last_two_blanks():
525 528 nt.assert_false(isp.last_two_blanks(''))
526 529 nt.assert_false(isp.last_two_blanks('abc'))
527 530 nt.assert_false(isp.last_two_blanks('abc\n'))
528 531 nt.assert_false(isp.last_two_blanks('abc\n\na'))
529 532 nt.assert_false(isp.last_two_blanks('abc\n \n'))
530 533 nt.assert_false(isp.last_two_blanks('abc\n\n'))
531 534
532 535 nt.assert_true(isp.last_two_blanks('\n\n'))
533 536 nt.assert_true(isp.last_two_blanks('\n\n '))
534 537 nt.assert_true(isp.last_two_blanks('\n \n'))
535 538 nt.assert_true(isp.last_two_blanks('abc\n\n '))
536 539 nt.assert_true(isp.last_two_blanks('abc\n\n\n'))
537 540 nt.assert_true(isp.last_two_blanks('abc\n\n \n'))
538 541 nt.assert_true(isp.last_two_blanks('abc\n\n \n '))
539 542 nt.assert_true(isp.last_two_blanks('abc\n\n \n \n'))
540 543 nt.assert_true(isp.last_two_blanks('abc\nd\n\n\n'))
541 544 nt.assert_true(isp.last_two_blanks('abc\nd\ne\nf\n\n\n'))
542 545
543 546
544 547 class CellMagicsCommon(object):
545 548
546 549 def test_whole_cell(self):
547 550 src = "%%cellm line\nbody\n"
548 sp = self.sp
549 sp.push(src)
550 out = sp.source_reset()
551 out = self.sp.transform_cell(src)
551 552 ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n"
552 553 nt.assert_equal(out, py3compat.u_format(ref))
553 554
554 555 def test_cellmagic_help(self):
555 556 self.sp.push('%%cellm?')
556 557 nt.assert_false(self.sp.push_accepts_more())
557 558
558 559 def tearDown(self):
559 560 self.sp.reset()
560 561
561 562
562 563 class CellModeCellMagics(CellMagicsCommon, unittest.TestCase):
563 564 sp = isp.IPythonInputSplitter(line_input_checker=False)
564 565
565 566 def test_incremental(self):
566 567 sp = self.sp
567 568 sp.push('%%cellm firstline\n')
568 569 nt.assert_true(sp.push_accepts_more()) #1
569 570 sp.push('line2\n')
570 571 nt.assert_true(sp.push_accepts_more()) #2
571 572 sp.push('\n')
572 573 # This should accept a blank line and carry on until the cell is reset
573 574 nt.assert_true(sp.push_accepts_more()) #3
574 575
575 576 class LineModeCellMagics(CellMagicsCommon, unittest.TestCase):
576 577 sp = isp.IPythonInputSplitter(line_input_checker=True)
577 578
578 579 def test_incremental(self):
579 580 sp = self.sp
580 581 sp.push('%%cellm line2\n')
581 582 nt.assert_true(sp.push_accepts_more()) #1
582 583 sp.push('\n')
583 584 # In this case, a blank line should end the cell magic
584 585 nt.assert_false(sp.push_accepts_more()) #2
@@ -1,677 +1,715 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Historically the main classes in interactiveshell have been under-tested. This
5 5 module should grow as many single-method tests as possible to trap many of the
6 6 recurring bugs we seem to encounter with high-level interaction.
7 7
8 8 Authors
9 9 -------
10 10 * Fernando Perez
11 11 """
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22 # stdlib
23 23 import ast
24 24 import os
25 25 import signal
26 26 import shutil
27 27 import sys
28 28 import tempfile
29 29 import unittest
30 30 from os.path import join
31 31
32 32 # third-party
33 33 import nose.tools as nt
34 34
35 35 # Our own
36 from IPython.core.inputtransformer import InputTransformer
36 37 from IPython.testing.decorators import skipif, skip_win32, onlyif_unicode_paths
37 38 from IPython.testing import tools as tt
38 39 from IPython.utils import io
39 40 from IPython.utils import py3compat
40 41 from IPython.utils.py3compat import unicode_type, PY3
41 42
42 43 if PY3:
43 44 from io import StringIO
44 45 else:
45 46 from StringIO import StringIO
46 47
47 48 #-----------------------------------------------------------------------------
48 49 # Globals
49 50 #-----------------------------------------------------------------------------
50 51 # This is used by every single test, no point repeating it ad nauseam
51 52 ip = get_ipython()
52 53
53 54 #-----------------------------------------------------------------------------
54 55 # Tests
55 56 #-----------------------------------------------------------------------------
56 57
57 58 class InteractiveShellTestCase(unittest.TestCase):
58 59 def test_naked_string_cells(self):
59 60 """Test that cells with only naked strings are fully executed"""
60 61 # First, single-line inputs
61 62 ip.run_cell('"a"\n')
62 63 self.assertEqual(ip.user_ns['_'], 'a')
63 64 # And also multi-line cells
64 65 ip.run_cell('"""a\nb"""\n')
65 66 self.assertEqual(ip.user_ns['_'], 'a\nb')
66 67
67 68 def test_run_empty_cell(self):
68 69 """Just make sure we don't get a horrible error with a blank
69 70 cell of input. Yes, I did overlook that."""
70 71 old_xc = ip.execution_count
71 72 ip.run_cell('')
72 73 self.assertEqual(ip.execution_count, old_xc)
73 74
74 75 def test_run_cell_multiline(self):
75 76 """Multi-block, multi-line cells must execute correctly.
76 77 """
77 78 src = '\n'.join(["x=1",
78 79 "y=2",
79 80 "if 1:",
80 81 " x += 1",
81 82 " y += 1",])
82 83 ip.run_cell(src)
83 84 self.assertEqual(ip.user_ns['x'], 2)
84 85 self.assertEqual(ip.user_ns['y'], 3)
85 86
86 87 def test_multiline_string_cells(self):
87 88 "Code sprinkled with multiline strings should execute (GH-306)"
88 89 ip.run_cell('tmp=0')
89 90 self.assertEqual(ip.user_ns['tmp'], 0)
90 91 ip.run_cell('tmp=1;"""a\nb"""\n')
91 92 self.assertEqual(ip.user_ns['tmp'], 1)
92 93
93 94 def test_dont_cache_with_semicolon(self):
94 95 "Ending a line with semicolon should not cache the returned object (GH-307)"
95 96 oldlen = len(ip.user_ns['Out'])
96 97 a = ip.run_cell('1;', store_history=True)
97 98 newlen = len(ip.user_ns['Out'])
98 99 self.assertEqual(oldlen, newlen)
99 100 #also test the default caching behavior
100 101 ip.run_cell('1', store_history=True)
101 102 newlen = len(ip.user_ns['Out'])
102 103 self.assertEqual(oldlen+1, newlen)
103 104
104 105 def test_In_variable(self):
105 106 "Verify that In variable grows with user input (GH-284)"
106 107 oldlen = len(ip.user_ns['In'])
107 108 ip.run_cell('1;', store_history=True)
108 109 newlen = len(ip.user_ns['In'])
109 110 self.assertEqual(oldlen+1, newlen)
110 111 self.assertEqual(ip.user_ns['In'][-1],'1;')
111 112
112 113 def test_magic_names_in_string(self):
113 114 ip.run_cell('a = """\n%exit\n"""')
114 115 self.assertEqual(ip.user_ns['a'], '\n%exit\n')
115 116
116 117 def test_trailing_newline(self):
117 118 """test that running !(command) does not raise a SyntaxError"""
118 119 ip.run_cell('!(true)\n', False)
119 120 ip.run_cell('!(true)\n\n\n', False)
120 121
121 122 def test_gh_597(self):
122 123 """Pretty-printing lists of objects with non-ascii reprs may cause
123 124 problems."""
124 125 class Spam(object):
125 126 def __repr__(self):
126 127 return "\xe9"*50
127 128 import IPython.core.formatters
128 129 f = IPython.core.formatters.PlainTextFormatter()
129 130 f([Spam(),Spam()])
130 131
131 132
132 133 def test_future_flags(self):
133 134 """Check that future flags are used for parsing code (gh-777)"""
134 135 ip.run_cell('from __future__ import print_function')
135 136 try:
136 137 ip.run_cell('prfunc_return_val = print(1,2, sep=" ")')
137 138 assert 'prfunc_return_val' in ip.user_ns
138 139 finally:
139 140 # Reset compiler flags so we don't mess up other tests.
140 141 ip.compile.reset_compiler_flags()
141 142
142 143 def test_future_unicode(self):
143 144 """Check that unicode_literals is imported from __future__ (gh #786)"""
144 145 try:
145 146 ip.run_cell(u'byte_str = "a"')
146 147 assert isinstance(ip.user_ns['byte_str'], str) # string literals are byte strings by default
147 148 ip.run_cell('from __future__ import unicode_literals')
148 149 ip.run_cell(u'unicode_str = "a"')
149 150 assert isinstance(ip.user_ns['unicode_str'], unicode_type) # strings literals are now unicode
150 151 finally:
151 152 # Reset compiler flags so we don't mess up other tests.
152 153 ip.compile.reset_compiler_flags()
153 154
154 155 def test_can_pickle(self):
155 156 "Can we pickle objects defined interactively (GH-29)"
156 157 ip = get_ipython()
157 158 ip.reset()
158 159 ip.run_cell(("class Mylist(list):\n"
159 160 " def __init__(self,x=[]):\n"
160 161 " list.__init__(self,x)"))
161 162 ip.run_cell("w=Mylist([1,2,3])")
162 163
163 164 from pickle import dumps
164 165
165 166 # We need to swap in our main module - this is only necessary
166 167 # inside the test framework, because IPython puts the interactive module
167 168 # in place (but the test framework undoes this).
168 169 _main = sys.modules['__main__']
169 170 sys.modules['__main__'] = ip.user_module
170 171 try:
171 172 res = dumps(ip.user_ns["w"])
172 173 finally:
173 174 sys.modules['__main__'] = _main
174 175 self.assertTrue(isinstance(res, bytes))
175 176
176 177 def test_global_ns(self):
177 178 "Code in functions must be able to access variables outside them."
178 179 ip = get_ipython()
179 180 ip.run_cell("a = 10")
180 181 ip.run_cell(("def f(x):\n"
181 182 " return x + a"))
182 183 ip.run_cell("b = f(12)")
183 184 self.assertEqual(ip.user_ns["b"], 22)
184 185
185 186 def test_bad_custom_tb(self):
186 187 """Check that InteractiveShell is protected from bad custom exception handlers"""
187 188 from IPython.utils import io
188 189 save_stderr = io.stderr
189 190 try:
190 191 # capture stderr
191 192 io.stderr = StringIO()
192 193 ip.set_custom_exc((IOError,), lambda etype,value,tb: 1/0)
193 194 self.assertEqual(ip.custom_exceptions, (IOError,))
194 195 ip.run_cell(u'raise IOError("foo")')
195 196 self.assertEqual(ip.custom_exceptions, ())
196 197 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
197 198 finally:
198 199 io.stderr = save_stderr
199 200
200 201 def test_bad_custom_tb_return(self):
201 202 """Check that InteractiveShell is protected from bad return types in custom exception handlers"""
202 203 from IPython.utils import io
203 204 save_stderr = io.stderr
204 205 try:
205 206 # capture stderr
206 207 io.stderr = StringIO()
207 208 ip.set_custom_exc((NameError,),lambda etype,value,tb, tb_offset=None: 1)
208 209 self.assertEqual(ip.custom_exceptions, (NameError,))
209 210 ip.run_cell(u'a=abracadabra')
210 211 self.assertEqual(ip.custom_exceptions, ())
211 212 self.assertTrue("Custom TB Handler failed" in io.stderr.getvalue())
212 213 finally:
213 214 io.stderr = save_stderr
214 215
215 216 def test_drop_by_id(self):
216 217 myvars = {"a":object(), "b":object(), "c": object()}
217 218 ip.push(myvars, interactive=False)
218 219 for name in myvars:
219 220 assert name in ip.user_ns, name
220 221 assert name in ip.user_ns_hidden, name
221 222 ip.user_ns['b'] = 12
222 223 ip.drop_by_id(myvars)
223 224 for name in ["a", "c"]:
224 225 assert name not in ip.user_ns, name
225 226 assert name not in ip.user_ns_hidden, name
226 227 assert ip.user_ns['b'] == 12
227 228 ip.reset()
228 229
229 230 def test_var_expand(self):
230 231 ip.user_ns['f'] = u'Ca\xf1o'
231 232 self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
232 233 self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o')
233 234 self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1')
234 235 self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2')
235 236
236 237 ip.user_ns['f'] = b'Ca\xc3\xb1o'
237 238 # This should not raise any exception:
238 239 ip.var_expand(u'echo $f')
239 240
240 241 def test_var_expand_local(self):
241 242 """Test local variable expansion in !system and %magic calls"""
242 243 # !system
243 244 ip.run_cell('def test():\n'
244 245 ' lvar = "ttt"\n'
245 246 ' ret = !echo {lvar}\n'
246 247 ' return ret[0]\n')
247 248 res = ip.user_ns['test']()
248 249 nt.assert_in('ttt', res)
249 250
250 251 # %magic
251 252 ip.run_cell('def makemacro():\n'
252 253 ' macroname = "macro_var_expand_locals"\n'
253 254 ' %macro {macroname} codestr\n')
254 255 ip.user_ns['codestr'] = "str(12)"
255 256 ip.run_cell('makemacro()')
256 257 nt.assert_in('macro_var_expand_locals', ip.user_ns)
257 258
258 259 def test_var_expand_self(self):
259 260 """Test variable expansion with the name 'self', which was failing.
260 261
261 262 See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218
262 263 """
263 264 ip.run_cell('class cTest:\n'
264 265 ' classvar="see me"\n'
265 266 ' def test(self):\n'
266 267 ' res = !echo Variable: {self.classvar}\n'
267 268 ' return res[0]\n')
268 269 nt.assert_in('see me', ip.user_ns['cTest']().test())
269 270
270 271 def test_bad_var_expand(self):
271 272 """var_expand on invalid formats shouldn't raise"""
272 273 # SyntaxError
273 274 self.assertEqual(ip.var_expand(u"{'a':5}"), u"{'a':5}")
274 275 # NameError
275 276 self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}")
276 277 # ZeroDivisionError
277 278 self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}")
278 279
279 280 def test_silent_nopostexec(self):
280 281 """run_cell(silent=True) doesn't invoke post-exec funcs"""
281 282 d = dict(called=False)
282 283 def set_called():
283 284 d['called'] = True
284 285
285 286 ip.register_post_execute(set_called)
286 287 ip.run_cell("1", silent=True)
287 288 self.assertFalse(d['called'])
288 289 # double-check that non-silent exec did what we expected
289 290 # silent to avoid
290 291 ip.run_cell("1")
291 292 self.assertTrue(d['called'])
292 293 # remove post-exec
293 294 ip._post_execute.pop(set_called)
294 295
295 296 def test_silent_noadvance(self):
296 297 """run_cell(silent=True) doesn't advance execution_count"""
297 298 ec = ip.execution_count
298 299 # silent should force store_history=False
299 300 ip.run_cell("1", store_history=True, silent=True)
300 301
301 302 self.assertEqual(ec, ip.execution_count)
302 303 # double-check that non-silent exec did what we expected
303 304 # silent to avoid
304 305 ip.run_cell("1", store_history=True)
305 306 self.assertEqual(ec+1, ip.execution_count)
306 307
307 308 def test_silent_nodisplayhook(self):
308 309 """run_cell(silent=True) doesn't trigger displayhook"""
309 310 d = dict(called=False)
310 311
311 312 trap = ip.display_trap
312 313 save_hook = trap.hook
313 314
314 315 def failing_hook(*args, **kwargs):
315 316 d['called'] = True
316 317
317 318 try:
318 319 trap.hook = failing_hook
319 320 ip.run_cell("1", silent=True)
320 321 self.assertFalse(d['called'])
321 322 # double-check that non-silent exec did what we expected
322 323 # silent to avoid
323 324 ip.run_cell("1")
324 325 self.assertTrue(d['called'])
325 326 finally:
326 327 trap.hook = save_hook
327 328
328 329 @skipif(sys.version_info[0] >= 3, "softspace removed in py3")
329 330 def test_print_softspace(self):
330 331 """Verify that softspace is handled correctly when executing multiple
331 332 statements.
332 333
333 334 In [1]: print 1; print 2
334 335 1
335 336 2
336 337
337 338 In [2]: print 1,; print 2
338 339 1 2
339 340 """
340 341
341 342 def test_ofind_line_magic(self):
342 343 from IPython.core.magic import register_line_magic
343 344
344 345 @register_line_magic
345 346 def lmagic(line):
346 347 "A line magic"
347 348
348 349 # Get info on line magic
349 350 lfind = ip._ofind('lmagic')
350 351 info = dict(found=True, isalias=False, ismagic=True,
351 352 namespace = 'IPython internal', obj= lmagic.__wrapped__,
352 353 parent = None)
353 354 nt.assert_equal(lfind, info)
354 355
355 356 def test_ofind_cell_magic(self):
356 357 from IPython.core.magic import register_cell_magic
357 358
358 359 @register_cell_magic
359 360 def cmagic(line, cell):
360 361 "A cell magic"
361 362
362 363 # Get info on cell magic
363 364 find = ip._ofind('cmagic')
364 365 info = dict(found=True, isalias=False, ismagic=True,
365 366 namespace = 'IPython internal', obj= cmagic.__wrapped__,
366 367 parent = None)
367 368 nt.assert_equal(find, info)
368 369
369 370 def test_custom_exception(self):
370 371 called = []
371 372 def my_handler(shell, etype, value, tb, tb_offset=None):
372 373 called.append(etype)
373 374 shell.showtraceback((etype, value, tb), tb_offset=tb_offset)
374 375
375 376 ip.set_custom_exc((ValueError,), my_handler)
376 377 try:
377 378 ip.run_cell("raise ValueError('test')")
378 379 # Check that this was called, and only once.
379 380 self.assertEqual(called, [ValueError])
380 381 finally:
381 382 # Reset the custom exception hook
382 383 ip.set_custom_exc((), None)
383 384
384 385 @skipif(sys.version_info[0] >= 3, "no differences with __future__ in py3")
385 386 def test_future_environment(self):
386 387 "Can we run code with & without the shell's __future__ imports?"
387 388 ip.run_cell("from __future__ import division")
388 389 ip.run_cell("a = 1/2", shell_futures=True)
389 390 self.assertEqual(ip.user_ns['a'], 0.5)
390 391 ip.run_cell("b = 1/2", shell_futures=False)
391 392 self.assertEqual(ip.user_ns['b'], 0)
392 393
393 394 ip.compile.reset_compiler_flags()
394 395 # This shouldn't leak to the shell's compiler
395 396 ip.run_cell("from __future__ import division \nc=1/2", shell_futures=False)
396 397 self.assertEqual(ip.user_ns['c'], 0.5)
397 398 ip.run_cell("d = 1/2", shell_futures=True)
398 399 self.assertEqual(ip.user_ns['d'], 0)
399 400
400 401
401 402 class TestSafeExecfileNonAsciiPath(unittest.TestCase):
402 403
403 404 @onlyif_unicode_paths
404 405 def setUp(self):
405 406 self.BASETESTDIR = tempfile.mkdtemp()
406 407 self.TESTDIR = join(self.BASETESTDIR, u"Γ₯Àâ")
407 408 os.mkdir(self.TESTDIR)
408 409 with open(join(self.TESTDIR, u"Γ₯Àâtestscript.py"), "w") as sfile:
409 410 sfile.write("pass\n")
410 411 self.oldpath = py3compat.getcwd()
411 412 os.chdir(self.TESTDIR)
412 413 self.fname = u"Γ₯Àâtestscript.py"
413 414
414 415 def tearDown(self):
415 416 os.chdir(self.oldpath)
416 417 shutil.rmtree(self.BASETESTDIR)
417 418
418 419 @onlyif_unicode_paths
419 420 def test_1(self):
420 421 """Test safe_execfile with non-ascii path
421 422 """
422 423 ip.safe_execfile(self.fname, {}, raise_exceptions=True)
423 424
424 425 class ExitCodeChecks(tt.TempFileMixin):
425 426 def test_exit_code_ok(self):
426 427 self.system('exit 0')
427 428 self.assertEqual(ip.user_ns['_exit_code'], 0)
428 429
429 430 def test_exit_code_error(self):
430 431 self.system('exit 1')
431 432 self.assertEqual(ip.user_ns['_exit_code'], 1)
432 433
433 434 @skipif(not hasattr(signal, 'SIGALRM'))
434 435 def test_exit_code_signal(self):
435 436 self.mktmp("import signal, time\n"
436 437 "signal.setitimer(signal.ITIMER_REAL, 0.1)\n"
437 438 "time.sleep(1)\n")
438 439 self.system("%s %s" % (sys.executable, self.fname))
439 440 self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM)
440 441
441 442 class TestSystemRaw(unittest.TestCase, ExitCodeChecks):
442 443 system = ip.system_raw
443 444
444 445 @onlyif_unicode_paths
445 446 def test_1(self):
446 447 """Test system_raw with non-ascii cmd
447 448 """
448 449 cmd = u'''python -c "'Γ₯Àâ'" '''
449 450 ip.system_raw(cmd)
450 451
451 452 # TODO: Exit codes are currently ignored on Windows.
452 453 class TestSystemPipedExitCode(unittest.TestCase, ExitCodeChecks):
453 454 system = ip.system_piped
454 455
455 456 @skip_win32
456 457 def test_exit_code_ok(self):
457 458 ExitCodeChecks.test_exit_code_ok(self)
458 459
459 460 @skip_win32
460 461 def test_exit_code_error(self):
461 462 ExitCodeChecks.test_exit_code_error(self)
462 463
463 464 @skip_win32
464 465 def test_exit_code_signal(self):
465 466 ExitCodeChecks.test_exit_code_signal(self)
466 467
467 468 class TestModules(unittest.TestCase, tt.TempFileMixin):
468 469 def test_extraneous_loads(self):
469 470 """Test we're not loading modules on startup that we shouldn't.
470 471 """
471 472 self.mktmp("import sys\n"
472 473 "print('numpy' in sys.modules)\n"
473 474 "print('IPython.parallel' in sys.modules)\n"
474 475 "print('IPython.kernel.zmq' in sys.modules)\n"
475 476 )
476 477 out = "False\nFalse\nFalse\n"
477 478 tt.ipexec_validate(self.fname, out)
478 479
479 480 class Negator(ast.NodeTransformer):
480 481 """Negates all number literals in an AST."""
481 482 def visit_Num(self, node):
482 483 node.n = -node.n
483 484 return node
484 485
485 486 class TestAstTransform(unittest.TestCase):
486 487 def setUp(self):
487 488 self.negator = Negator()
488 489 ip.ast_transformers.append(self.negator)
489 490
490 491 def tearDown(self):
491 492 ip.ast_transformers.remove(self.negator)
492 493
493 494 def test_run_cell(self):
494 495 with tt.AssertPrints('-34'):
495 496 ip.run_cell('print (12 + 22)')
496 497
497 498 # A named reference to a number shouldn't be transformed.
498 499 ip.user_ns['n'] = 55
499 500 with tt.AssertNotPrints('-55'):
500 501 ip.run_cell('print (n)')
501 502
502 503 def test_timeit(self):
503 504 called = set()
504 505 def f(x):
505 506 called.add(x)
506 507 ip.push({'f':f})
507 508
508 509 with tt.AssertPrints("best of "):
509 510 ip.run_line_magic("timeit", "-n1 f(1)")
510 511 self.assertEqual(called, set([-1]))
511 512 called.clear()
512 513
513 514 with tt.AssertPrints("best of "):
514 515 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
515 516 self.assertEqual(called, set([-2, -3]))
516 517
517 518 def test_time(self):
518 519 called = []
519 520 def f(x):
520 521 called.append(x)
521 522 ip.push({'f':f})
522 523
523 524 # Test with an expression
524 525 with tt.AssertPrints("Wall time: "):
525 526 ip.run_line_magic("time", "f(5+9)")
526 527 self.assertEqual(called, [-14])
527 528 called[:] = []
528 529
529 530 # Test with a statement (different code path)
530 531 with tt.AssertPrints("Wall time: "):
531 532 ip.run_line_magic("time", "a = f(-3 + -2)")
532 533 self.assertEqual(called, [5])
533 534
534 535 def test_macro(self):
535 536 ip.push({'a':10})
536 537 # The AST transformation makes this do a+=-1
537 538 ip.define_macro("amacro", "a+=1\nprint(a)")
538 539
539 540 with tt.AssertPrints("9"):
540 541 ip.run_cell("amacro")
541 542 with tt.AssertPrints("8"):
542 543 ip.run_cell("amacro")
543 544
544 545 class IntegerWrapper(ast.NodeTransformer):
545 546 """Wraps all integers in a call to Integer()"""
546 547 def visit_Num(self, node):
547 548 if isinstance(node.n, int):
548 549 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
549 550 args=[node], keywords=[])
550 551 return node
551 552
552 553 class TestAstTransform2(unittest.TestCase):
553 554 def setUp(self):
554 555 self.intwrapper = IntegerWrapper()
555 556 ip.ast_transformers.append(self.intwrapper)
556 557
557 558 self.calls = []
558 559 def Integer(*args):
559 560 self.calls.append(args)
560 561 return args
561 562 ip.push({"Integer": Integer})
562 563
563 564 def tearDown(self):
564 565 ip.ast_transformers.remove(self.intwrapper)
565 566 del ip.user_ns['Integer']
566 567
567 568 def test_run_cell(self):
568 569 ip.run_cell("n = 2")
569 570 self.assertEqual(self.calls, [(2,)])
570 571
571 572 # This shouldn't throw an error
572 573 ip.run_cell("o = 2.0")
573 574 self.assertEqual(ip.user_ns['o'], 2.0)
574 575
575 576 def test_timeit(self):
576 577 called = set()
577 578 def f(x):
578 579 called.add(x)
579 580 ip.push({'f':f})
580 581
581 582 with tt.AssertPrints("best of "):
582 583 ip.run_line_magic("timeit", "-n1 f(1)")
583 584 self.assertEqual(called, set([(1,)]))
584 585 called.clear()
585 586
586 587 with tt.AssertPrints("best of "):
587 588 ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)")
588 589 self.assertEqual(called, set([(2,), (3,)]))
589 590
590 591 class ErrorTransformer(ast.NodeTransformer):
591 592 """Throws an error when it sees a number."""
592 593 def visit_Num(self):
593 594 raise ValueError("test")
594 595
595 596 class TestAstTransformError(unittest.TestCase):
596 597 def test_unregistering(self):
597 598 err_transformer = ErrorTransformer()
598 599 ip.ast_transformers.append(err_transformer)
599 600
600 601 with tt.AssertPrints("unregister", channel='stderr'):
601 602 ip.run_cell("1 + 2")
602 603
603 604 # This should have been removed.
604 605 nt.assert_not_in(err_transformer, ip.ast_transformers)
605 606
606 607 def test__IPYTHON__():
607 608 # This shouldn't raise a NameError, that's all
608 609 __IPYTHON__
609 610
610 611
611 612 class DummyRepr(object):
612 613 def __repr__(self):
613 614 return "DummyRepr"
614 615
615 616 def _repr_html_(self):
616 617 return "<b>dummy</b>"
617 618
618 619 def _repr_javascript_(self):
619 620 return "console.log('hi');", {'key': 'value'}
620 621
621 622
622 623 def test_user_variables():
623 624 # enable all formatters
624 625 ip.display_formatter.active_types = ip.display_formatter.format_types
625 626
626 627 ip.user_ns['dummy'] = d = DummyRepr()
627 628 keys = set(['dummy', 'doesnotexist'])
628 629 r = ip.user_variables(keys)
629 630
630 631 nt.assert_equal(keys, set(r.keys()))
631 632 dummy = r['dummy']
632 633 nt.assert_equal(set(['status', 'data', 'metadata']), set(dummy.keys()))
633 634 nt.assert_equal(dummy['status'], 'ok')
634 635 data = dummy['data']
635 636 metadata = dummy['metadata']
636 637 nt.assert_equal(data.get('text/html'), d._repr_html_())
637 638 js, jsmd = d._repr_javascript_()
638 639 nt.assert_equal(data.get('application/javascript'), js)
639 640 nt.assert_equal(metadata.get('application/javascript'), jsmd)
640 641
641 642 dne = r['doesnotexist']
642 643 nt.assert_equal(dne['status'], 'error')
643 644 nt.assert_equal(dne['ename'], 'KeyError')
644 645
645 646 # back to text only
646 647 ip.display_formatter.active_types = ['text/plain']
647 648
648 649 def test_user_expression():
649 650 # enable all formatters
650 651 ip.display_formatter.active_types = ip.display_formatter.format_types
651 652 query = {
652 653 'a' : '1 + 2',
653 654 'b' : '1/0',
654 655 }
655 656 r = ip.user_expressions(query)
656 657 import pprint
657 658 pprint.pprint(r)
658 659 nt.assert_equal(set(r.keys()), set(query.keys()))
659 660 a = r['a']
660 661 nt.assert_equal(set(['status', 'data', 'metadata']), set(a.keys()))
661 662 nt.assert_equal(a['status'], 'ok')
662 663 data = a['data']
663 664 metadata = a['metadata']
664 665 nt.assert_equal(data.get('text/plain'), '3')
665 666
666 667 b = r['b']
667 668 nt.assert_equal(b['status'], 'error')
668 669 nt.assert_equal(b['ename'], 'ZeroDivisionError')
669 670
670 671 # back to text only
671 672 ip.display_formatter.active_types = ['text/plain']
672 673
673 674
674 675
675 676
676 677
678 class TestSyntaxErrorTransformer(unittest.TestCase):
679 """Check that SyntaxError raised by an input transformer is handled by run_cell()"""
680
681 class SyntaxErrorTransformer(InputTransformer):
682
683 def push(self, line):
684 pos = line.find('syntaxerror')
685 if pos >= 0:
686 e = SyntaxError('input contains "syntaxerror"')
687 e.text = line
688 e.offset = pos + 1
689 raise e
690 return line
691
692 def reset(self):
693 pass
694
695 def setUp(self):
696 self.transformer = TestSyntaxErrorTransformer.SyntaxErrorTransformer()
697 ip.input_splitter.python_line_transforms.append(self.transformer)
698 ip.input_transformer_manager.python_line_transforms.append(self.transformer)
699
700 def tearDown(self):
701 ip.input_splitter.python_line_transforms.remove(self.transformer)
702 ip.input_transformer_manager.python_line_transforms.remove(self.transformer)
703
704 def test_syntaxerror_input_transformer(self):
705 with tt.AssertPrints('1234'):
706 ip.run_cell('1234')
707 with tt.AssertPrints('SyntaxError: invalid syntax'):
708 ip.run_cell('1 2 3') # plain python syntax error
709 with tt.AssertPrints('SyntaxError: input contains "syntaxerror"'):
710 ip.run_cell('2345 # syntaxerror') # input transformer syntax error
711 with tt.AssertPrints('3456'):
712 ip.run_cell('3456')
713
714
677 715
@@ -1,803 +1,806 b''
1 1 from __future__ import print_function
2 2
3 3 # Standard library imports
4 4 from collections import namedtuple
5 5 import sys
6 6 import uuid
7 7
8 8 # System library imports
9 9 from IPython.external import qt
10 10 from IPython.external.qt import QtCore, QtGui
11 11 from IPython.utils import py3compat
12 12 from IPython.utils.importstring import import_item
13 13
14 14 # Local imports
15 15 from IPython.core.inputsplitter import InputSplitter, IPythonInputSplitter
16 16 from IPython.core.inputtransformer import classic_prompt
17 17 from IPython.core.oinspect import call_tip
18 18 from IPython.qt.base_frontend_mixin import BaseFrontendMixin
19 19 from IPython.utils.traitlets import Any, Bool, Instance, Unicode, DottedObjectName
20 20 from .bracket_matcher import BracketMatcher
21 21 from .call_tip_widget import CallTipWidget
22 22 from .completion_lexer import CompletionLexer
23 23 from .history_console_widget import HistoryConsoleWidget
24 24 from .pygments_highlighter import PygmentsHighlighter
25 25
26 26
27 27 class FrontendHighlighter(PygmentsHighlighter):
28 28 """ A PygmentsHighlighter that understands and ignores prompts.
29 29 """
30 30
31 31 def __init__(self, frontend, lexer=None):
32 32 super(FrontendHighlighter, self).__init__(frontend._control.document(), lexer=lexer)
33 33 self._current_offset = 0
34 34 self._frontend = frontend
35 35 self.highlighting_on = False
36 36
37 37 def highlightBlock(self, string):
38 38 """ Highlight a block of text. Reimplemented to highlight selectively.
39 39 """
40 40 if not self.highlighting_on:
41 41 return
42 42
43 43 # The input to this function is a unicode string that may contain
44 44 # paragraph break characters, non-breaking spaces, etc. Here we acquire
45 45 # the string as plain text so we can compare it.
46 46 current_block = self.currentBlock()
47 47 string = self._frontend._get_block_plain_text(current_block)
48 48
49 49 # Decide whether to check for the regular or continuation prompt.
50 50 if current_block.contains(self._frontend._prompt_pos):
51 51 prompt = self._frontend._prompt
52 52 else:
53 53 prompt = self._frontend._continuation_prompt
54 54
55 55 # Only highlight if we can identify a prompt, but make sure not to
56 56 # highlight the prompt.
57 57 if string.startswith(prompt):
58 58 self._current_offset = len(prompt)
59 59 string = string[len(prompt):]
60 60 super(FrontendHighlighter, self).highlightBlock(string)
61 61
62 62 def rehighlightBlock(self, block):
63 63 """ Reimplemented to temporarily enable highlighting if disabled.
64 64 """
65 65 old = self.highlighting_on
66 66 self.highlighting_on = True
67 67 super(FrontendHighlighter, self).rehighlightBlock(block)
68 68 self.highlighting_on = old
69 69
70 70 def setFormat(self, start, count, format):
71 71 """ Reimplemented to highlight selectively.
72 72 """
73 73 start += self._current_offset
74 74 super(FrontendHighlighter, self).setFormat(start, count, format)
75 75
76 76
77 77 class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):
78 78 """ A Qt frontend for a generic Python kernel.
79 79 """
80 80
81 81 # The text to show when the kernel is (re)started.
82 82 banner = Unicode(config=True)
83 83
84 84 # An option and corresponding signal for overriding the default kernel
85 85 # interrupt behavior.
86 86 custom_interrupt = Bool(False)
87 87 custom_interrupt_requested = QtCore.Signal()
88 88
89 89 # An option and corresponding signals for overriding the default kernel
90 90 # restart behavior.
91 91 custom_restart = Bool(False)
92 92 custom_restart_kernel_died = QtCore.Signal(float)
93 93 custom_restart_requested = QtCore.Signal()
94 94
95 95 # Whether to automatically show calltips on open-parentheses.
96 96 enable_calltips = Bool(True, config=True,
97 97 help="Whether to draw information calltips on open-parentheses.")
98 98
99 99 clear_on_kernel_restart = Bool(True, config=True,
100 100 help="Whether to clear the console when the kernel is restarted")
101 101
102 102 confirm_restart = Bool(True, config=True,
103 103 help="Whether to ask for user confirmation when restarting kernel")
104 104
105 105 lexer_class = DottedObjectName(config=True,
106 106 help="The pygments lexer class to use."
107 107 )
108 108 def _lexer_class_changed(self, name, old, new):
109 109 lexer_class = import_item(new)
110 110 self.lexer = lexer_class()
111 111
112 112 def _lexer_class_default(self):
113 113 if py3compat.PY3:
114 114 return 'pygments.lexers.Python3Lexer'
115 115 else:
116 116 return 'pygments.lexers.PythonLexer'
117 117
118 118 lexer = Any()
119 119 def _lexer_default(self):
120 120 lexer_class = import_item(self.lexer_class)
121 121 return lexer_class()
122 122
123 123 # Emitted when a user visible 'execute_request' has been submitted to the
124 124 # kernel from the FrontendWidget. Contains the code to be executed.
125 125 executing = QtCore.Signal(object)
126 126
127 127 # Emitted when a user-visible 'execute_reply' has been received from the
128 128 # kernel and processed by the FrontendWidget. Contains the response message.
129 129 executed = QtCore.Signal(object)
130 130
131 131 # Emitted when an exit request has been received from the kernel.
132 132 exit_requested = QtCore.Signal(object)
133 133
134 134 # Protected class variables.
135 135 _prompt_transformer = IPythonInputSplitter(physical_line_transforms=[classic_prompt()],
136 136 logical_line_transforms=[],
137 137 python_line_transforms=[],
138 138 )
139 139 _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos'])
140 140 _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos'])
141 141 _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind'])
142 142 _input_splitter_class = InputSplitter
143 143 _local_kernel = False
144 144 _highlighter = Instance(FrontendHighlighter)
145 145
146 146 #---------------------------------------------------------------------------
147 147 # 'object' interface
148 148 #---------------------------------------------------------------------------
149 149
150 150 def __init__(self, *args, **kw):
151 151 super(FrontendWidget, self).__init__(*args, **kw)
152 152 # FIXME: remove this when PySide min version is updated past 1.0.7
153 153 # forcefully disable calltips if PySide is < 1.0.7, because they crash
154 154 if qt.QT_API == qt.QT_API_PYSIDE:
155 155 import PySide
156 156 if PySide.__version_info__ < (1,0,7):
157 157 self.log.warn("PySide %s < 1.0.7 detected, disabling calltips" % PySide.__version__)
158 158 self.enable_calltips = False
159 159
160 160 # FrontendWidget protected variables.
161 161 self._bracket_matcher = BracketMatcher(self._control)
162 162 self._call_tip_widget = CallTipWidget(self._control)
163 163 self._completion_lexer = CompletionLexer(self.lexer)
164 164 self._copy_raw_action = QtGui.QAction('Copy (Raw Text)', None)
165 165 self._hidden = False
166 166 self._highlighter = FrontendHighlighter(self, lexer=self.lexer)
167 167 self._input_splitter = self._input_splitter_class()
168 168 self._kernel_manager = None
169 169 self._kernel_client = None
170 170 self._request_info = {}
171 171 self._request_info['execute'] = {};
172 172 self._callback_dict = {}
173 173
174 174 # Configure the ConsoleWidget.
175 175 self.tab_width = 4
176 176 self._set_continuation_prompt('... ')
177 177
178 178 # Configure the CallTipWidget.
179 179 self._call_tip_widget.setFont(self.font)
180 180 self.font_changed.connect(self._call_tip_widget.setFont)
181 181
182 182 # Configure actions.
183 183 action = self._copy_raw_action
184 184 key = QtCore.Qt.CTRL | QtCore.Qt.SHIFT | QtCore.Qt.Key_C
185 185 action.setEnabled(False)
186 186 action.setShortcut(QtGui.QKeySequence(key))
187 187 action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
188 188 action.triggered.connect(self.copy_raw)
189 189 self.copy_available.connect(action.setEnabled)
190 190 self.addAction(action)
191 191
192 192 # Connect signal handlers.
193 193 document = self._control.document()
194 194 document.contentsChange.connect(self._document_contents_change)
195 195
196 196 # Set flag for whether we are connected via localhost.
197 197 self._local_kernel = kw.get('local_kernel',
198 198 FrontendWidget._local_kernel)
199 199
200 200 #---------------------------------------------------------------------------
201 201 # 'ConsoleWidget' public interface
202 202 #---------------------------------------------------------------------------
203 203
204 204 def copy(self):
205 205 """ Copy the currently selected text to the clipboard, removing prompts.
206 206 """
207 207 if self._page_control is not None and self._page_control.hasFocus():
208 208 self._page_control.copy()
209 209 elif self._control.hasFocus():
210 210 text = self._control.textCursor().selection().toPlainText()
211 211 if text:
212 212 text = self._prompt_transformer.transform_cell(text)
213 213 QtGui.QApplication.clipboard().setText(text)
214 214 else:
215 215 self.log.debug("frontend widget : unknown copy target")
216 216
217 217 #---------------------------------------------------------------------------
218 218 # 'ConsoleWidget' abstract interface
219 219 #---------------------------------------------------------------------------
220 220
221 221 def _is_complete(self, source, interactive):
222 222 """ Returns whether 'source' can be completely processed and a new
223 223 prompt created. When triggered by an Enter/Return key press,
224 224 'interactive' is True; otherwise, it is False.
225 225 """
226 226 self._input_splitter.reset()
227 complete = self._input_splitter.push(source)
227 try:
228 complete = self._input_splitter.push(source)
229 except SyntaxError:
230 return True
228 231 if interactive:
229 232 complete = not self._input_splitter.push_accepts_more()
230 233 return complete
231 234
232 235 def _execute(self, source, hidden):
233 236 """ Execute 'source'. If 'hidden', do not show any output.
234 237
235 238 See parent class :meth:`execute` docstring for full details.
236 239 """
237 240 msg_id = self.kernel_client.execute(source, hidden)
238 241 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user')
239 242 self._hidden = hidden
240 243 if not hidden:
241 244 self.executing.emit(source)
242 245
243 246 def _prompt_started_hook(self):
244 247 """ Called immediately after a new prompt is displayed.
245 248 """
246 249 if not self._reading:
247 250 self._highlighter.highlighting_on = True
248 251
249 252 def _prompt_finished_hook(self):
250 253 """ Called immediately after a prompt is finished, i.e. when some input
251 254 will be processed and a new prompt displayed.
252 255 """
253 256 # Flush all state from the input splitter so the next round of
254 257 # reading input starts with a clean buffer.
255 258 self._input_splitter.reset()
256 259
257 260 if not self._reading:
258 261 self._highlighter.highlighting_on = False
259 262
260 263 def _tab_pressed(self):
261 264 """ Called when the tab key is pressed. Returns whether to continue
262 265 processing the event.
263 266 """
264 267 # Perform tab completion if:
265 268 # 1) The cursor is in the input buffer.
266 269 # 2) There is a non-whitespace character before the cursor.
267 270 text = self._get_input_buffer_cursor_line()
268 271 if text is None:
269 272 return False
270 273 complete = bool(text[:self._get_input_buffer_cursor_column()].strip())
271 274 if complete:
272 275 self._complete()
273 276 return not complete
274 277
275 278 #---------------------------------------------------------------------------
276 279 # 'ConsoleWidget' protected interface
277 280 #---------------------------------------------------------------------------
278 281
279 282 def _context_menu_make(self, pos):
280 283 """ Reimplemented to add an action for raw copy.
281 284 """
282 285 menu = super(FrontendWidget, self)._context_menu_make(pos)
283 286 for before_action in menu.actions():
284 287 if before_action.shortcut().matches(QtGui.QKeySequence.Paste) == \
285 288 QtGui.QKeySequence.ExactMatch:
286 289 menu.insertAction(before_action, self._copy_raw_action)
287 290 break
288 291 return menu
289 292
290 293 def request_interrupt_kernel(self):
291 294 if self._executing:
292 295 self.interrupt_kernel()
293 296
294 297 def request_restart_kernel(self):
295 298 message = 'Are you sure you want to restart the kernel?'
296 299 self.restart_kernel(message, now=False)
297 300
298 301 def _event_filter_console_keypress(self, event):
299 302 """ Reimplemented for execution interruption and smart backspace.
300 303 """
301 304 key = event.key()
302 305 if self._control_key_down(event.modifiers(), include_command=False):
303 306
304 307 if key == QtCore.Qt.Key_C and self._executing:
305 308 self.request_interrupt_kernel()
306 309 return True
307 310
308 311 elif key == QtCore.Qt.Key_Period:
309 312 self.request_restart_kernel()
310 313 return True
311 314
312 315 elif not event.modifiers() & QtCore.Qt.AltModifier:
313 316
314 317 # Smart backspace: remove four characters in one backspace if:
315 318 # 1) everything left of the cursor is whitespace
316 319 # 2) the four characters immediately left of the cursor are spaces
317 320 if key == QtCore.Qt.Key_Backspace:
318 321 col = self._get_input_buffer_cursor_column()
319 322 cursor = self._control.textCursor()
320 323 if col > 3 and not cursor.hasSelection():
321 324 text = self._get_input_buffer_cursor_line()[:col]
322 325 if text.endswith(' ') and not text.strip():
323 326 cursor.movePosition(QtGui.QTextCursor.Left,
324 327 QtGui.QTextCursor.KeepAnchor, 4)
325 328 cursor.removeSelectedText()
326 329 return True
327 330
328 331 return super(FrontendWidget, self)._event_filter_console_keypress(event)
329 332
330 333 def _insert_continuation_prompt(self, cursor):
331 334 """ Reimplemented for auto-indentation.
332 335 """
333 336 super(FrontendWidget, self)._insert_continuation_prompt(cursor)
334 337 cursor.insertText(' ' * self._input_splitter.indent_spaces)
335 338
336 339 #---------------------------------------------------------------------------
337 340 # 'BaseFrontendMixin' abstract interface
338 341 #---------------------------------------------------------------------------
339 342
340 343 def _handle_complete_reply(self, rep):
341 344 """ Handle replies for tab completion.
342 345 """
343 346 self.log.debug("complete: %s", rep.get('content', ''))
344 347 cursor = self._get_cursor()
345 348 info = self._request_info.get('complete')
346 349 if info and info.id == rep['parent_header']['msg_id'] and \
347 350 info.pos == cursor.position():
348 351 text = '.'.join(self._get_context())
349 352 cursor.movePosition(QtGui.QTextCursor.Left, n=len(text))
350 353 self._complete_with_items(cursor, rep['content']['matches'])
351 354
352 355 def _silent_exec_callback(self, expr, callback):
353 356 """Silently execute `expr` in the kernel and call `callback` with reply
354 357
355 358 the `expr` is evaluated silently in the kernel (without) output in
356 359 the frontend. Call `callback` with the
357 360 `repr <http://docs.python.org/library/functions.html#repr> `_ as first argument
358 361
359 362 Parameters
360 363 ----------
361 364 expr : string
362 365 valid string to be executed by the kernel.
363 366 callback : function
364 367 function accepting one argument, as a string. The string will be
365 368 the `repr` of the result of evaluating `expr`
366 369
367 370 The `callback` is called with the `repr()` of the result of `expr` as
368 371 first argument. To get the object, do `eval()` on the passed value.
369 372
370 373 See Also
371 374 --------
372 375 _handle_exec_callback : private method, deal with calling callback with reply
373 376
374 377 """
375 378
376 379 # generate uuid, which would be used as an indication of whether or
377 380 # not the unique request originated from here (can use msg id ?)
378 381 local_uuid = str(uuid.uuid1())
379 382 msg_id = self.kernel_client.execute('',
380 383 silent=True, user_expressions={ local_uuid:expr })
381 384 self._callback_dict[local_uuid] = callback
382 385 self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'silent_exec_callback')
383 386
384 387 def _handle_exec_callback(self, msg):
385 388 """Execute `callback` corresponding to `msg` reply, after ``_silent_exec_callback``
386 389
387 390 Parameters
388 391 ----------
389 392 msg : raw message send by the kernel containing an `user_expressions`
390 393 and having a 'silent_exec_callback' kind.
391 394
392 395 Notes
393 396 -----
394 397 This function will look for a `callback` associated with the
395 398 corresponding message id. Association has been made by
396 399 `_silent_exec_callback`. `callback` is then called with the `repr()`
397 400 of the value of corresponding `user_expressions` as argument.
398 401 `callback` is then removed from the known list so that any message
399 402 coming again with the same id won't trigger it.
400 403
401 404 """
402 405
403 406 user_exp = msg['content'].get('user_expressions')
404 407 if not user_exp:
405 408 return
406 409 for expression in user_exp:
407 410 if expression in self._callback_dict:
408 411 self._callback_dict.pop(expression)(user_exp[expression])
409 412
410 413 def _handle_execute_reply(self, msg):
411 414 """ Handles replies for code execution.
412 415 """
413 416 self.log.debug("execute: %s", msg.get('content', ''))
414 417 msg_id = msg['parent_header']['msg_id']
415 418 info = self._request_info['execute'].get(msg_id)
416 419 # unset reading flag, because if execute finished, raw_input can't
417 420 # still be pending.
418 421 self._reading = False
419 422 if info and info.kind == 'user' and not self._hidden:
420 423 # Make sure that all output from the SUB channel has been processed
421 424 # before writing a new prompt.
422 425 self.kernel_client.iopub_channel.flush()
423 426
424 427 # Reset the ANSI style information to prevent bad text in stdout
425 428 # from messing up our colors. We're not a true terminal so we're
426 429 # allowed to do this.
427 430 if self.ansi_codes:
428 431 self._ansi_processor.reset_sgr()
429 432
430 433 content = msg['content']
431 434 status = content['status']
432 435 if status == 'ok':
433 436 self._process_execute_ok(msg)
434 437 elif status == 'error':
435 438 self._process_execute_error(msg)
436 439 elif status == 'aborted':
437 440 self._process_execute_abort(msg)
438 441
439 442 self._show_interpreter_prompt_for_reply(msg)
440 443 self.executed.emit(msg)
441 444 self._request_info['execute'].pop(msg_id)
442 445 elif info and info.kind == 'silent_exec_callback' and not self._hidden:
443 446 self._handle_exec_callback(msg)
444 447 self._request_info['execute'].pop(msg_id)
445 448 else:
446 449 super(FrontendWidget, self)._handle_execute_reply(msg)
447 450
448 451 def _handle_input_request(self, msg):
449 452 """ Handle requests for raw_input.
450 453 """
451 454 self.log.debug("input: %s", msg.get('content', ''))
452 455 if self._hidden:
453 456 raise RuntimeError('Request for raw input during hidden execution.')
454 457
455 458 # Make sure that all output from the SUB channel has been processed
456 459 # before entering readline mode.
457 460 self.kernel_client.iopub_channel.flush()
458 461
459 462 def callback(line):
460 463 self.kernel_client.stdin_channel.input(line)
461 464 if self._reading:
462 465 self.log.debug("Got second input request, assuming first was interrupted.")
463 466 self._reading = False
464 467 self._readline(msg['content']['prompt'], callback=callback)
465 468
466 469 def _kernel_restarted_message(self, died=True):
467 470 msg = "Kernel died, restarting" if died else "Kernel restarting"
468 471 self._append_html("<br>%s<hr><br>" % msg,
469 472 before_prompt=False
470 473 )
471 474
472 475 def _handle_kernel_died(self, since_last_heartbeat):
473 476 """Handle the kernel's death (if we do not own the kernel).
474 477 """
475 478 self.log.warn("kernel died: %s", since_last_heartbeat)
476 479 if self.custom_restart:
477 480 self.custom_restart_kernel_died.emit(since_last_heartbeat)
478 481 else:
479 482 self._kernel_restarted_message(died=True)
480 483 self.reset()
481 484
482 485 def _handle_kernel_restarted(self, died=True):
483 486 """Notice that the autorestarter restarted the kernel.
484 487
485 488 There's nothing to do but show a message.
486 489 """
487 490 self.log.warn("kernel restarted")
488 491 self._kernel_restarted_message(died=died)
489 492 self.reset()
490 493
491 494 def _handle_object_info_reply(self, rep):
492 495 """ Handle replies for call tips.
493 496 """
494 497 self.log.debug("oinfo: %s", rep.get('content', ''))
495 498 cursor = self._get_cursor()
496 499 info = self._request_info.get('call_tip')
497 500 if info and info.id == rep['parent_header']['msg_id'] and \
498 501 info.pos == cursor.position():
499 502 # Get the information for a call tip. For now we format the call
500 503 # line as string, later we can pass False to format_call and
501 504 # syntax-highlight it ourselves for nicer formatting in the
502 505 # calltip.
503 506 content = rep['content']
504 507 # if this is from pykernel, 'docstring' will be the only key
505 508 if content.get('ismagic', False):
506 509 # Don't generate a call-tip for magics. Ideally, we should
507 510 # generate a tooltip, but not on ( like we do for actual
508 511 # callables.
509 512 call_info, doc = None, None
510 513 else:
511 514 call_info, doc = call_tip(content, format_call=True)
512 515 if call_info or doc:
513 516 self._call_tip_widget.show_call_info(call_info, doc)
514 517
515 518 def _handle_pyout(self, msg):
516 519 """ Handle display hook output.
517 520 """
518 521 self.log.debug("pyout: %s", msg.get('content', ''))
519 522 if not self._hidden and self._is_from_this_session(msg):
520 523 text = msg['content']['data']
521 524 self._append_plain_text(text + '\n', before_prompt=True)
522 525
523 526 def _handle_stream(self, msg):
524 527 """ Handle stdout, stderr, and stdin.
525 528 """
526 529 self.log.debug("stream: %s", msg.get('content', ''))
527 530 if not self._hidden and self._is_from_this_session(msg):
528 531 # Most consoles treat tabs as being 8 space characters. Convert tabs
529 532 # to spaces so that output looks as expected regardless of this
530 533 # widget's tab width.
531 534 text = msg['content']['data'].expandtabs(8)
532 535
533 536 self._append_plain_text(text, before_prompt=True)
534 537 self._control.moveCursor(QtGui.QTextCursor.End)
535 538
536 539 def _handle_shutdown_reply(self, msg):
537 540 """ Handle shutdown signal, only if from other console.
538 541 """
539 542 self.log.warn("shutdown: %s", msg.get('content', ''))
540 543 restart = msg.get('content', {}).get('restart', False)
541 544 if not self._hidden and not self._is_from_this_session(msg):
542 545 # got shutdown reply, request came from session other than ours
543 546 if restart:
544 547 # someone restarted the kernel, handle it
545 548 self._handle_kernel_restarted(died=False)
546 549 else:
547 550 # kernel was shutdown permanently
548 551 # this triggers exit_requested if the kernel was local,
549 552 # and a dialog if the kernel was remote,
550 553 # so we don't suddenly clear the qtconsole without asking.
551 554 if self._local_kernel:
552 555 self.exit_requested.emit(self)
553 556 else:
554 557 title = self.window().windowTitle()
555 558 reply = QtGui.QMessageBox.question(self, title,
556 559 "Kernel has been shutdown permanently. "
557 560 "Close the Console?",
558 561 QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
559 562 if reply == QtGui.QMessageBox.Yes:
560 563 self.exit_requested.emit(self)
561 564
562 565 def _handle_status(self, msg):
563 566 """Handle status message"""
564 567 # This is where a busy/idle indicator would be triggered,
565 568 # when we make one.
566 569 state = msg['content'].get('execution_state', '')
567 570 if state == 'starting':
568 571 # kernel started while we were running
569 572 if self._executing:
570 573 self._handle_kernel_restarted(died=True)
571 574 elif state == 'idle':
572 575 pass
573 576 elif state == 'busy':
574 577 pass
575 578
576 579 def _started_channels(self):
577 580 """ Called when the KernelManager channels have started listening or
578 581 when the frontend is assigned an already listening KernelManager.
579 582 """
580 583 self.reset(clear=True)
581 584
582 585 #---------------------------------------------------------------------------
583 586 # 'FrontendWidget' public interface
584 587 #---------------------------------------------------------------------------
585 588
586 589 def copy_raw(self):
587 590 """ Copy the currently selected text to the clipboard without attempting
588 591 to remove prompts or otherwise alter the text.
589 592 """
590 593 self._control.copy()
591 594
592 595 def execute_file(self, path, hidden=False):
593 596 """ Attempts to execute file with 'path'. If 'hidden', no output is
594 597 shown.
595 598 """
596 599 self.execute('execfile(%r)' % path, hidden=hidden)
597 600
598 601 def interrupt_kernel(self):
599 602 """ Attempts to interrupt the running kernel.
600 603
601 604 Also unsets _reading flag, to avoid runtime errors
602 605 if raw_input is called again.
603 606 """
604 607 if self.custom_interrupt:
605 608 self._reading = False
606 609 self.custom_interrupt_requested.emit()
607 610 elif self.kernel_manager:
608 611 self._reading = False
609 612 self.kernel_manager.interrupt_kernel()
610 613 else:
611 614 self._append_plain_text('Cannot interrupt a kernel I did not start.\n')
612 615
613 616 def reset(self, clear=False):
614 617 """ Resets the widget to its initial state if ``clear`` parameter
615 618 is True, otherwise
616 619 prints a visual indication of the fact that the kernel restarted, but
617 620 does not clear the traces from previous usage of the kernel before it
618 621 was restarted. With ``clear=True``, it is similar to ``%clear``, but
619 622 also re-writes the banner and aborts execution if necessary.
620 623 """
621 624 if self._executing:
622 625 self._executing = False
623 626 self._request_info['execute'] = {}
624 627 self._reading = False
625 628 self._highlighter.highlighting_on = False
626 629
627 630 if clear:
628 631 self._control.clear()
629 632 self._append_plain_text(self.banner)
630 633 # update output marker for stdout/stderr, so that startup
631 634 # messages appear after banner:
632 635 self._append_before_prompt_pos = self._get_cursor().position()
633 636 self._show_interpreter_prompt()
634 637
635 638 def restart_kernel(self, message, now=False):
636 639 """ Attempts to restart the running kernel.
637 640 """
638 641 # FIXME: now should be configurable via a checkbox in the dialog. Right
639 642 # now at least the heartbeat path sets it to True and the manual restart
640 643 # to False. But those should just be the pre-selected states of a
641 644 # checkbox that the user could override if so desired. But I don't know
642 645 # enough Qt to go implementing the checkbox now.
643 646
644 647 if self.custom_restart:
645 648 self.custom_restart_requested.emit()
646 649 return
647 650
648 651 if self.kernel_manager:
649 652 # Pause the heart beat channel to prevent further warnings.
650 653 self.kernel_client.hb_channel.pause()
651 654
652 655 # Prompt the user to restart the kernel. Un-pause the heartbeat if
653 656 # they decline. (If they accept, the heartbeat will be un-paused
654 657 # automatically when the kernel is restarted.)
655 658 if self.confirm_restart:
656 659 buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
657 660 result = QtGui.QMessageBox.question(self, 'Restart kernel?',
658 661 message, buttons)
659 662 do_restart = result == QtGui.QMessageBox.Yes
660 663 else:
661 664 # confirm_restart is False, so we don't need to ask user
662 665 # anything, just do the restart
663 666 do_restart = True
664 667 if do_restart:
665 668 try:
666 669 self.kernel_manager.restart_kernel(now=now)
667 670 except RuntimeError as e:
668 671 self._append_plain_text(
669 672 'Error restarting kernel: %s\n' % e,
670 673 before_prompt=True
671 674 )
672 675 else:
673 676 self._append_html("<br>Restarting kernel...\n<hr><br>",
674 677 before_prompt=True,
675 678 )
676 679 else:
677 680 self.kernel_client.hb_channel.unpause()
678 681
679 682 else:
680 683 self._append_plain_text(
681 684 'Cannot restart a Kernel I did not start\n',
682 685 before_prompt=True
683 686 )
684 687
685 688 #---------------------------------------------------------------------------
686 689 # 'FrontendWidget' protected interface
687 690 #---------------------------------------------------------------------------
688 691
689 692 def _call_tip(self):
690 693 """ Shows a call tip, if appropriate, at the current cursor location.
691 694 """
692 695 # Decide if it makes sense to show a call tip
693 696 if not self.enable_calltips:
694 697 return False
695 698 cursor = self._get_cursor()
696 699 cursor.movePosition(QtGui.QTextCursor.Left)
697 700 if cursor.document().characterAt(cursor.position()) != '(':
698 701 return False
699 702 context = self._get_context(cursor)
700 703 if not context:
701 704 return False
702 705
703 706 # Send the metadata request to the kernel
704 707 name = '.'.join(context)
705 708 msg_id = self.kernel_client.object_info(name)
706 709 pos = self._get_cursor().position()
707 710 self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos)
708 711 return True
709 712
710 713 def _complete(self):
711 714 """ Performs completion at the current cursor location.
712 715 """
713 716 context = self._get_context()
714 717 if context:
715 718 # Send the completion request to the kernel
716 719 msg_id = self.kernel_client.complete(
717 720 '.'.join(context), # text
718 721 self._get_input_buffer_cursor_line(), # line
719 722 self._get_input_buffer_cursor_column(), # cursor_pos
720 723 self.input_buffer) # block
721 724 pos = self._get_cursor().position()
722 725 info = self._CompletionRequest(msg_id, pos)
723 726 self._request_info['complete'] = info
724 727
725 728 def _get_context(self, cursor=None):
726 729 """ Gets the context for the specified cursor (or the current cursor
727 730 if none is specified).
728 731 """
729 732 if cursor is None:
730 733 cursor = self._get_cursor()
731 734 cursor.movePosition(QtGui.QTextCursor.StartOfBlock,
732 735 QtGui.QTextCursor.KeepAnchor)
733 736 text = cursor.selection().toPlainText()
734 737 return self._completion_lexer.get_context(text)
735 738
736 739 def _process_execute_abort(self, msg):
737 740 """ Process a reply for an aborted execution request.
738 741 """
739 742 self._append_plain_text("ERROR: execution aborted\n")
740 743
741 744 def _process_execute_error(self, msg):
742 745 """ Process a reply for an execution request that resulted in an error.
743 746 """
744 747 content = msg['content']
745 748 # If a SystemExit is passed along, this means exit() was called - also
746 749 # all the ipython %exit magic syntax of '-k' to be used to keep
747 750 # the kernel running
748 751 if content['ename']=='SystemExit':
749 752 keepkernel = content['evalue']=='-k' or content['evalue']=='True'
750 753 self._keep_kernel_on_exit = keepkernel
751 754 self.exit_requested.emit(self)
752 755 else:
753 756 traceback = ''.join(content['traceback'])
754 757 self._append_plain_text(traceback)
755 758
756 759 def _process_execute_ok(self, msg):
757 760 """ Process a reply for a successful execution request.
758 761 """
759 762 payload = msg['content']['payload']
760 763 for item in payload:
761 764 if not self._process_execute_payload(item):
762 765 warning = 'Warning: received unknown payload of type %s'
763 766 print(warning % repr(item['source']))
764 767
765 768 def _process_execute_payload(self, item):
766 769 """ Process a single payload item from the list of payload items in an
767 770 execution reply. Returns whether the payload was handled.
768 771 """
769 772 # The basic FrontendWidget doesn't handle payloads, as they are a
770 773 # mechanism for going beyond the standard Python interpreter model.
771 774 return False
772 775
773 776 def _show_interpreter_prompt(self):
774 777 """ Shows a prompt for the interpreter.
775 778 """
776 779 self._show_prompt('>>> ')
777 780
778 781 def _show_interpreter_prompt_for_reply(self, msg):
779 782 """ Shows a prompt for the interpreter given an 'execute_reply' message.
780 783 """
781 784 self._show_interpreter_prompt()
782 785
783 786 #------ Signal handlers ----------------------------------------------------
784 787
785 788 def _document_contents_change(self, position, removed, added):
786 789 """ Called whenever the document's content changes. Display a call tip
787 790 if appropriate.
788 791 """
789 792 # Calculate where the cursor should be *after* the change:
790 793 position += added
791 794
792 795 document = self._control.document()
793 796 if position == self._get_cursor().position():
794 797 self._call_tip()
795 798
796 799 #------ Trait default initializers -----------------------------------------
797 800
798 801 def _banner_default(self):
799 802 """ Returns the standard Python banner.
800 803 """
801 804 banner = 'Python %s on %s\nType "help", "copyright", "credits" or ' \
802 805 '"license" for more information.'
803 806 return banner % (sys.version, sys.platform)
@@ -1,1071 +1,1071 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Sphinx directive to support embedded IPython code.
4 4
5 5 This directive allows pasting of entire interactive IPython sessions, prompts
6 6 and all, and their code will actually get re-executed at doc build time, with
7 7 all prompts renumbered sequentially. It also allows you to input code as a pure
8 8 python input by giving the argument python to the directive. The output looks
9 9 like an interactive ipython section.
10 10
11 11 To enable this directive, simply list it in your Sphinx ``conf.py`` file
12 12 (making sure the directory where you placed it is visible to sphinx, as is
13 13 needed for all Sphinx directives). For example, to enable syntax highlighting
14 14 and the IPython directive::
15 15
16 16 extensions = ['IPython.sphinxext.ipython_console_highlighting',
17 17 'IPython.sphinxext.ipython_directive']
18 18
19 19 The IPython directive outputs code-blocks with the language 'ipython'. So
20 20 if you do not have the syntax highlighting extension enabled as well, then
21 21 all rendered code-blocks will be uncolored. By default this directive assumes
22 22 that your prompts are unchanged IPython ones, but this can be customized.
23 23 The configurable options that can be placed in conf.py are:
24 24
25 25 ipython_savefig_dir:
26 26 The directory in which to save the figures. This is relative to the
27 27 Sphinx source directory. The default is `html_static_path`.
28 28 ipython_rgxin:
29 29 The compiled regular expression to denote the start of IPython input
30 30 lines. The default is re.compile('In \[(\d+)\]:\s?(.*)\s*'). You
31 31 shouldn't need to change this.
32 32 ipython_rgxout:
33 33 The compiled regular expression to denote the start of IPython output
34 34 lines. The default is re.compile('Out\[(\d+)\]:\s?(.*)\s*'). You
35 35 shouldn't need to change this.
36 36 ipython_promptin:
37 37 The string to represent the IPython input prompt in the generated ReST.
38 38 The default is 'In [%d]:'. This expects that the line numbers are used
39 39 in the prompt.
40 40 ipython_promptout:
41 41 The string to represent the IPython prompt in the generated ReST. The
42 42 default is 'Out [%d]:'. This expects that the line numbers are used
43 43 in the prompt.
44 44 ipython_mplbackend:
45 45 The string which specifies if the embedded Sphinx shell should import
46 46 Matplotlib and set the backend. The value specifies a backend that is
47 47 passed to `matplotlib.use()` before any lines in `ipython_execlines` are
48 48 executed. If not specified in conf.py, then the default value of 'agg' is
49 49 used. To use the IPython directive without matplotlib as a dependency, set
50 50 the value to `None`. It may end up that matplotlib is still imported
51 51 if the user specifies so in `ipython_execlines` or makes use of the
52 52 @savefig pseudo decorator.
53 53 ipython_execlines:
54 54 A list of strings to be exec'd in the embedded Sphinx shell. Typical
55 55 usage is to make certain packages always available. Set this to an empty
56 56 list if you wish to have no imports always available. If specified in
57 57 conf.py as `None`, then it has the effect of making no imports available.
58 58 If omitted from conf.py altogether, then the default value of
59 59 ['import numpy as np', 'import matplotlib.pyplot as plt'] is used.
60 60 ipython_holdcount
61 61 When the @suppress pseudo-decorator is used, the execution count can be
62 62 incremented or not. The default behavior is to hold the execution count,
63 63 corresponding to a value of `True`. Set this to `False` to increment
64 64 the execution count after each suppressed command.
65 65
66 66 As an example, to use the IPython directive when `matplotlib` is not available,
67 67 one sets the backend to `None`::
68 68
69 69 ipython_mplbackend = None
70 70
71 71 An example usage of the directive is:
72 72
73 73 .. code-block:: rst
74 74
75 75 .. ipython::
76 76
77 77 In [1]: x = 1
78 78
79 79 In [2]: y = x**2
80 80
81 81 In [3]: print(y)
82 82
83 83 See http://matplotlib.org/sampledoc/ipython_directive.html for additional
84 84 documentation.
85 85
86 86 Pseudo-Decorators
87 87 =================
88 88
89 89 In addition to the Pseudo-Decorators/options described at the above link,
90 90 several enhancements have been made.
91 91 The directive will emit a message to the console at build-time if
92 92 code-execution resulted in an exception or warning. You can suppress these on
93 93 a per-block basis by specifying the :okexcept: or :okwarning: options:
94 94
95 95 .. code-block:: rst
96 96
97 97 .. ipython::
98 98 :okexcept:
99 99 :okwarning:
100 100
101 101 In [1]: 1/0
102 102 In [2]: # raise warning.
103 103
104 104 ToDo
105 105 ----
106 106
107 107 - Turn the ad-hoc test() function into a real test suite.
108 108 - Break up ipython-specific functionality from matplotlib stuff into better
109 109 separated code.
110 110
111 111 Authors
112 112 -------
113 113
114 114 - John D Hunter: orignal author.
115 115 - Fernando Perez: refactoring, documentation, cleanups, port to 0.11.
116 116 - VΓ‘clavΕ milauer <eudoxos-AT-arcig.cz>: Prompt generalizations.
117 117 - Skipper Seabold, refactoring, cleanups, pure python addition
118 118 """
119 119 from __future__ import print_function
120 120
121 121 #-----------------------------------------------------------------------------
122 122 # Imports
123 123 #-----------------------------------------------------------------------------
124 124
125 125 # Stdlib
126 126 import os
127 127 import re
128 128 import sys
129 129 import tempfile
130 130 import ast
131 131 import warnings
132 132
133 133 # To keep compatibility with various python versions
134 134 try:
135 135 from hashlib import md5
136 136 except ImportError:
137 137 from md5 import md5
138 138
139 139 # Third-party
140 140 import sphinx
141 141 from docutils.parsers.rst import directives
142 142 from docutils import nodes
143 143 from sphinx.util.compat import Directive
144 144
145 145 # Our own
146 146 from IPython import Config, InteractiveShell
147 147 from IPython.core.profiledir import ProfileDir
148 148 from IPython.utils import io
149 149 from IPython.utils.py3compat import PY3
150 150
151 151 if PY3:
152 152 from io import StringIO
153 153 else:
154 154 from StringIO import StringIO
155 155
156 156 #-----------------------------------------------------------------------------
157 157 # Globals
158 158 #-----------------------------------------------------------------------------
159 159 # for tokenizing blocks
160 160 COMMENT, INPUT, OUTPUT = range(3)
161 161
162 162 #-----------------------------------------------------------------------------
163 163 # Functions and class declarations
164 164 #-----------------------------------------------------------------------------
165 165
166 166 def block_parser(part, rgxin, rgxout, fmtin, fmtout):
167 167 """
168 168 part is a string of ipython text, comprised of at most one
169 169 input, one ouput, comments, and blank lines. The block parser
170 170 parses the text into a list of::
171 171
172 172 blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...]
173 173
174 174 where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and
175 175 data is, depending on the type of token::
176 176
177 177 COMMENT : the comment string
178 178
179 179 INPUT: the (DECORATOR, INPUT_LINE, REST) where
180 180 DECORATOR: the input decorator (or None)
181 181 INPUT_LINE: the input as string (possibly multi-line)
182 182 REST : any stdout generated by the input line (not OUTPUT)
183 183
184 184 OUTPUT: the output string, possibly multi-line
185 185
186 186 """
187 187 block = []
188 188 lines = part.split('\n')
189 189 N = len(lines)
190 190 i = 0
191 191 decorator = None
192 192 while 1:
193 193
194 194 if i==N:
195 195 # nothing left to parse -- the last line
196 196 break
197 197
198 198 line = lines[i]
199 199 i += 1
200 200 line_stripped = line.strip()
201 201 if line_stripped.startswith('#'):
202 202 block.append((COMMENT, line))
203 203 continue
204 204
205 205 if line_stripped.startswith('@'):
206 206 # we're assuming at most one decorator -- may need to
207 207 # rethink
208 208 decorator = line_stripped
209 209 continue
210 210
211 211 # does this look like an input line?
212 212 matchin = rgxin.match(line)
213 213 if matchin:
214 214 lineno, inputline = int(matchin.group(1)), matchin.group(2)
215 215
216 216 # the ....: continuation string
217 217 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
218 218 Nc = len(continuation)
219 219 # input lines can continue on for more than one line, if
220 220 # we have a '\' line continuation char or a function call
221 221 # echo line 'print'. The input line can only be
222 222 # terminated by the end of the block or an output line, so
223 223 # we parse out the rest of the input line if it is
224 224 # multiline as well as any echo text
225 225
226 226 rest = []
227 227 while i<N:
228 228
229 229 # look ahead; if the next line is blank, or a comment, or
230 230 # an output line, we're done
231 231
232 232 nextline = lines[i]
233 233 matchout = rgxout.match(nextline)
234 234 #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation))
235 235 if matchout or nextline.startswith('#'):
236 236 break
237 237 elif nextline.startswith(continuation):
238 238 # The default ipython_rgx* treat the space following the colon as optional.
239 239 # However, If the space is there we must consume it or code
240 240 # employing the cython_magic extension will fail to execute.
241 241 #
242 242 # This works with the default ipython_rgx* patterns,
243 243 # If you modify them, YMMV.
244 244 nextline = nextline[Nc:]
245 245 if nextline and nextline[0] == ' ':
246 246 nextline = nextline[1:]
247 247
248 248 inputline += '\n' + nextline
249 249 else:
250 250 rest.append(nextline)
251 251 i+= 1
252 252
253 253 block.append((INPUT, (decorator, inputline, '\n'.join(rest))))
254 254 continue
255 255
256 256 # if it looks like an output line grab all the text to the end
257 257 # of the block
258 258 matchout = rgxout.match(line)
259 259 if matchout:
260 260 lineno, output = int(matchout.group(1)), matchout.group(2)
261 261 if i<N-1:
262 262 output = '\n'.join([output] + lines[i:])
263 263
264 264 block.append((OUTPUT, output))
265 265 break
266 266
267 267 return block
268 268
269 269
270 270 class EmbeddedSphinxShell(object):
271 271 """An embedded IPython instance to run inside Sphinx"""
272 272
273 273 def __init__(self, exec_lines=None):
274 274
275 275 self.cout = StringIO()
276 276
277 277 if exec_lines is None:
278 278 exec_lines = []
279 279
280 280 # Create config object for IPython
281 281 config = Config()
282 282 config.InteractiveShell.autocall = False
283 283 config.InteractiveShell.autoindent = False
284 284 config.InteractiveShell.colors = 'NoColor'
285 285
286 286 # create a profile so instance history isn't saved
287 287 tmp_profile_dir = tempfile.mkdtemp(prefix='profile_')
288 288 profname = 'auto_profile_sphinx_build'
289 289 pdir = os.path.join(tmp_profile_dir,profname)
290 290 profile = ProfileDir.create_profile_dir(pdir)
291 291
292 292 # Create and initialize global ipython, but don't start its mainloop.
293 293 # This will persist across different EmbededSphinxShell instances.
294 294 IP = InteractiveShell.instance(config=config, profile_dir=profile)
295 295
296 296 # io.stdout redirect must be done after instantiating InteractiveShell
297 297 io.stdout = self.cout
298 298 io.stderr = self.cout
299 299
300 300 # For debugging, so we can see normal output, use this:
301 301 #from IPython.utils.io import Tee
302 302 #io.stdout = Tee(self.cout, channel='stdout') # dbg
303 303 #io.stderr = Tee(self.cout, channel='stderr') # dbg
304 304
305 305 # Store a few parts of IPython we'll need.
306 306 self.IP = IP
307 307 self.user_ns = self.IP.user_ns
308 308 self.user_global_ns = self.IP.user_global_ns
309 309
310 310 self.input = ''
311 311 self.output = ''
312 312
313 313 self.is_verbatim = False
314 314 self.is_doctest = False
315 315 self.is_suppress = False
316 316
317 317 # Optionally, provide more detailed information to shell.
318 318 # this is assigned by the SetUp method of IPythonDirective
319 319 # to point at itself.
320 320 #
321 321 # So, you can access handy things at self.directive.state
322 322 self.directive = None
323 323
324 324 # on the first call to the savefig decorator, we'll import
325 325 # pyplot as plt so we can make a call to the plt.gcf().savefig
326 326 self._pyplot_imported = False
327 327
328 328 # Prepopulate the namespace.
329 329 for line in exec_lines:
330 330 self.process_input_line(line, store_history=False)
331 331
332 332 def clear_cout(self):
333 333 self.cout.seek(0)
334 334 self.cout.truncate(0)
335 335
336 336 def process_input_line(self, line, store_history=True):
337 337 """process the input, capturing stdout"""
338 338
339 339 stdout = sys.stdout
340 340 splitter = self.IP.input_splitter
341 341 try:
342 342 sys.stdout = self.cout
343 343 splitter.push(line)
344 344 more = splitter.push_accepts_more()
345 345 if not more:
346 source_raw = splitter.source_raw_reset()[1]
346 source_raw = splitter.raw_reset()
347 347 self.IP.run_cell(source_raw, store_history=store_history)
348 348 finally:
349 349 sys.stdout = stdout
350 350
351 351 def process_image(self, decorator):
352 352 """
353 353 # build out an image directive like
354 354 # .. image:: somefile.png
355 355 # :width 4in
356 356 #
357 357 # from an input like
358 358 # savefig somefile.png width=4in
359 359 """
360 360 savefig_dir = self.savefig_dir
361 361 source_dir = self.source_dir
362 362 saveargs = decorator.split(' ')
363 363 filename = saveargs[1]
364 364 # insert relative path to image file in source
365 365 outfile = os.path.relpath(os.path.join(savefig_dir,filename),
366 366 source_dir)
367 367
368 368 imagerows = ['.. image:: %s'%outfile]
369 369
370 370 for kwarg in saveargs[2:]:
371 371 arg, val = kwarg.split('=')
372 372 arg = arg.strip()
373 373 val = val.strip()
374 374 imagerows.append(' :%s: %s'%(arg, val))
375 375
376 376 image_file = os.path.basename(outfile) # only return file name
377 377 image_directive = '\n'.join(imagerows)
378 378 return image_file, image_directive
379 379
380 380 # Callbacks for each type of token
381 381 def process_input(self, data, input_prompt, lineno):
382 382 """
383 383 Process data block for INPUT token.
384 384
385 385 """
386 386 decorator, input, rest = data
387 387 image_file = None
388 388 image_directive = None
389 389
390 390 is_verbatim = decorator=='@verbatim' or self.is_verbatim
391 391 is_doctest = (decorator is not None and \
392 392 decorator.startswith('@doctest')) or self.is_doctest
393 393 is_suppress = decorator=='@suppress' or self.is_suppress
394 394 is_okexcept = decorator=='@okexcept' or self.is_okexcept
395 395 is_okwarning = decorator=='@okwarning' or self.is_okwarning
396 396 is_savefig = decorator is not None and \
397 397 decorator.startswith('@savefig')
398 398
399 399 input_lines = input.split('\n')
400 400 if len(input_lines) > 1:
401 401 if input_lines[-1] != "":
402 402 input_lines.append('') # make sure there's a blank line
403 403 # so splitter buffer gets reset
404 404
405 405 continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2))
406 406
407 407 if is_savefig:
408 408 image_file, image_directive = self.process_image(decorator)
409 409
410 410 ret = []
411 411 is_semicolon = False
412 412
413 413 # Hold the execution count, if requested to do so.
414 414 if is_suppress and self.hold_count:
415 415 store_history = False
416 416 else:
417 417 store_history = True
418 418
419 419 # Note: catch_warnings is not thread safe
420 420 with warnings.catch_warnings(record=True) as ws:
421 421 for i, line in enumerate(input_lines):
422 422 if line.endswith(';'):
423 423 is_semicolon = True
424 424
425 425 if i == 0:
426 426 # process the first input line
427 427 if is_verbatim:
428 428 self.process_input_line('')
429 429 self.IP.execution_count += 1 # increment it anyway
430 430 else:
431 431 # only submit the line in non-verbatim mode
432 432 self.process_input_line(line, store_history=store_history)
433 433 formatted_line = '%s %s'%(input_prompt, line)
434 434 else:
435 435 # process a continuation line
436 436 if not is_verbatim:
437 437 self.process_input_line(line, store_history=store_history)
438 438
439 439 formatted_line = '%s %s'%(continuation, line)
440 440
441 441 if not is_suppress:
442 442 ret.append(formatted_line)
443 443
444 444 if not is_suppress and len(rest.strip()) and is_verbatim:
445 445 # the "rest" is the standard output of the
446 446 # input, which needs to be added in
447 447 # verbatim mode
448 448 ret.append(rest)
449 449
450 450 self.cout.seek(0)
451 451 output = self.cout.read()
452 452 if not is_suppress and not is_semicolon:
453 453 ret.append(output)
454 454 elif is_semicolon: # get spacing right
455 455 ret.append('')
456 456
457 457 # context information
458 458 filename = "Unknown"
459 459 lineno = 0
460 460 if self.directive.state:
461 461 filename = self.directive.state.document.current_source
462 462 lineno = self.directive.state.document.current_line
463 463
464 464 # output any exceptions raised during execution to stdout
465 465 # unless :okexcept: has been specified.
466 466 if not is_okexcept and "Traceback" in output:
467 467 s = "\nException in %s at block ending on line %s\n" % (filename, lineno)
468 468 s += "Specify :okexcept: as an option in the ipython:: block to suppress this message\n"
469 469 sys.stdout.write('\n\n>>>' + ('-' * 73))
470 470 sys.stdout.write(s)
471 471 sys.stdout.write(output)
472 472 sys.stdout.write('<<<' + ('-' * 73) + '\n\n')
473 473
474 474 # output any warning raised during execution to stdout
475 475 # unless :okwarning: has been specified.
476 476 if not is_okwarning:
477 477 for w in ws:
478 478 s = "\nWarning in %s at block ending on line %s\n" % (filename, lineno)
479 479 s += "Specify :okwarning: as an option in the ipython:: block to suppress this message\n"
480 480 sys.stdout.write('\n\n>>>' + ('-' * 73))
481 481 sys.stdout.write(s)
482 482 sys.stdout.write(('-' * 76) + '\n')
483 483 s=warnings.formatwarning(w.message, w.category,
484 484 w.filename, w.lineno, w.line)
485 485 sys.stdout.write(s)
486 486 sys.stdout.write('<<<' + ('-' * 73) + '\n')
487 487
488 488 self.cout.truncate(0)
489 489 return (ret, input_lines, output, is_doctest, decorator, image_file,
490 490 image_directive)
491 491
492 492
493 493 def process_output(self, data, output_prompt,
494 494 input_lines, output, is_doctest, decorator, image_file):
495 495 """
496 496 Process data block for OUTPUT token.
497 497
498 498 """
499 499 TAB = ' ' * 4
500 500
501 501 if is_doctest and output is not None:
502 502
503 503 found = output
504 504 found = found.strip()
505 505 submitted = data.strip()
506 506
507 507 if self.directive is None:
508 508 source = 'Unavailable'
509 509 content = 'Unavailable'
510 510 else:
511 511 source = self.directive.state.document.current_source
512 512 content = self.directive.content
513 513 # Add tabs and join into a single string.
514 514 content = '\n'.join([TAB + line for line in content])
515 515
516 516 # Make sure the output contains the output prompt.
517 517 ind = found.find(output_prompt)
518 518 if ind < 0:
519 519 e = ('output does not contain output prompt\n\n'
520 520 'Document source: {0}\n\n'
521 521 'Raw content: \n{1}\n\n'
522 522 'Input line(s):\n{TAB}{2}\n\n'
523 523 'Output line(s):\n{TAB}{3}\n\n')
524 524 e = e.format(source, content, '\n'.join(input_lines),
525 525 repr(found), TAB=TAB)
526 526 raise RuntimeError(e)
527 527 found = found[len(output_prompt):].strip()
528 528
529 529 # Handle the actual doctest comparison.
530 530 if decorator.strip() == '@doctest':
531 531 # Standard doctest
532 532 if found != submitted:
533 533 e = ('doctest failure\n\n'
534 534 'Document source: {0}\n\n'
535 535 'Raw content: \n{1}\n\n'
536 536 'On input line(s):\n{TAB}{2}\n\n'
537 537 'we found output:\n{TAB}{3}\n\n'
538 538 'instead of the expected:\n{TAB}{4}\n\n')
539 539 e = e.format(source, content, '\n'.join(input_lines),
540 540 repr(found), repr(submitted), TAB=TAB)
541 541 raise RuntimeError(e)
542 542 else:
543 543 self.custom_doctest(decorator, input_lines, found, submitted)
544 544
545 545 def process_comment(self, data):
546 546 """Process data fPblock for COMMENT token."""
547 547 if not self.is_suppress:
548 548 return [data]
549 549
550 550 def save_image(self, image_file):
551 551 """
552 552 Saves the image file to disk.
553 553 """
554 554 self.ensure_pyplot()
555 555 command = 'plt.gcf().savefig("%s")'%image_file
556 556 #print 'SAVEFIG', command # dbg
557 557 self.process_input_line('bookmark ipy_thisdir', store_history=False)
558 558 self.process_input_line('cd -b ipy_savedir', store_history=False)
559 559 self.process_input_line(command, store_history=False)
560 560 self.process_input_line('cd -b ipy_thisdir', store_history=False)
561 561 self.process_input_line('bookmark -d ipy_thisdir', store_history=False)
562 562 self.clear_cout()
563 563
564 564 def process_block(self, block):
565 565 """
566 566 process block from the block_parser and return a list of processed lines
567 567 """
568 568 ret = []
569 569 output = None
570 570 input_lines = None
571 571 lineno = self.IP.execution_count
572 572
573 573 input_prompt = self.promptin % lineno
574 574 output_prompt = self.promptout % lineno
575 575 image_file = None
576 576 image_directive = None
577 577
578 578 for token, data in block:
579 579 if token == COMMENT:
580 580 out_data = self.process_comment(data)
581 581 elif token == INPUT:
582 582 (out_data, input_lines, output, is_doctest, decorator,
583 583 image_file, image_directive) = \
584 584 self.process_input(data, input_prompt, lineno)
585 585 elif token == OUTPUT:
586 586 out_data = \
587 587 self.process_output(data, output_prompt,
588 588 input_lines, output, is_doctest,
589 589 decorator, image_file)
590 590 if out_data:
591 591 ret.extend(out_data)
592 592
593 593 # save the image files
594 594 if image_file is not None:
595 595 self.save_image(image_file)
596 596
597 597 return ret, image_directive
598 598
599 599 def ensure_pyplot(self):
600 600 """
601 601 Ensures that pyplot has been imported into the embedded IPython shell.
602 602
603 603 Also, makes sure to set the backend appropriately if not set already.
604 604
605 605 """
606 606 # We are here if the @figure pseudo decorator was used. Thus, it's
607 607 # possible that we could be here even if python_mplbackend were set to
608 608 # `None`. That's also strange and perhaps worthy of raising an
609 609 # exception, but for now, we just set the backend to 'agg'.
610 610
611 611 if not self._pyplot_imported:
612 612 if 'matplotlib.backends' not in sys.modules:
613 613 # Then ipython_matplotlib was set to None but there was a
614 614 # call to the @figure decorator (and ipython_execlines did
615 615 # not set a backend).
616 616 #raise Exception("No backend was set, but @figure was used!")
617 617 import matplotlib
618 618 matplotlib.use('agg')
619 619
620 620 # Always import pyplot into embedded shell.
621 621 self.process_input_line('import matplotlib.pyplot as plt',
622 622 store_history=False)
623 623 self._pyplot_imported = True
624 624
625 625 def process_pure_python(self, content):
626 626 """
627 627 content is a list of strings. it is unedited directive content
628 628
629 629 This runs it line by line in the InteractiveShell, prepends
630 630 prompts as needed capturing stderr and stdout, then returns
631 631 the content as a list as if it were ipython code
632 632 """
633 633 output = []
634 634 savefig = False # keep up with this to clear figure
635 635 multiline = False # to handle line continuation
636 636 multiline_start = None
637 637 fmtin = self.promptin
638 638
639 639 ct = 0
640 640
641 641 for lineno, line in enumerate(content):
642 642
643 643 line_stripped = line.strip()
644 644 if not len(line):
645 645 output.append(line)
646 646 continue
647 647
648 648 # handle decorators
649 649 if line_stripped.startswith('@'):
650 650 output.extend([line])
651 651 if 'savefig' in line:
652 652 savefig = True # and need to clear figure
653 653 continue
654 654
655 655 # handle comments
656 656 if line_stripped.startswith('#'):
657 657 output.extend([line])
658 658 continue
659 659
660 660 # deal with lines checking for multiline
661 661 continuation = u' %s:'% ''.join(['.']*(len(str(ct))+2))
662 662 if not multiline:
663 663 modified = u"%s %s" % (fmtin % ct, line_stripped)
664 664 output.append(modified)
665 665 ct += 1
666 666 try:
667 667 ast.parse(line_stripped)
668 668 output.append(u'')
669 669 except Exception: # on a multiline
670 670 multiline = True
671 671 multiline_start = lineno
672 672 else: # still on a multiline
673 673 modified = u'%s %s' % (continuation, line)
674 674 output.append(modified)
675 675
676 676 # if the next line is indented, it should be part of multiline
677 677 if len(content) > lineno + 1:
678 678 nextline = content[lineno + 1]
679 679 if len(nextline) - len(nextline.lstrip()) > 3:
680 680 continue
681 681 try:
682 682 mod = ast.parse(
683 683 '\n'.join(content[multiline_start:lineno+1]))
684 684 if isinstance(mod.body[0], ast.FunctionDef):
685 685 # check to see if we have the whole function
686 686 for element in mod.body[0].body:
687 687 if isinstance(element, ast.Return):
688 688 multiline = False
689 689 else:
690 690 output.append(u'')
691 691 multiline = False
692 692 except Exception:
693 693 pass
694 694
695 695 if savefig: # clear figure if plotted
696 696 self.ensure_pyplot()
697 697 self.process_input_line('plt.clf()', store_history=False)
698 698 self.clear_cout()
699 699 savefig = False
700 700
701 701 return output
702 702
703 703 def custom_doctest(self, decorator, input_lines, found, submitted):
704 704 """
705 705 Perform a specialized doctest.
706 706
707 707 """
708 708 from .custom_doctests import doctests
709 709
710 710 args = decorator.split()
711 711 doctest_type = args[1]
712 712 if doctest_type in doctests:
713 713 doctests[doctest_type](self, args, input_lines, found, submitted)
714 714 else:
715 715 e = "Invalid option to @doctest: {0}".format(doctest_type)
716 716 raise Exception(e)
717 717
718 718
719 719 class IPythonDirective(Directive):
720 720
721 721 has_content = True
722 722 required_arguments = 0
723 723 optional_arguments = 4 # python, suppress, verbatim, doctest
724 724 final_argumuent_whitespace = True
725 725 option_spec = { 'python': directives.unchanged,
726 726 'suppress' : directives.flag,
727 727 'verbatim' : directives.flag,
728 728 'doctest' : directives.flag,
729 729 'okexcept': directives.flag,
730 730 'okwarning': directives.flag
731 731 }
732 732
733 733 shell = None
734 734
735 735 seen_docs = set()
736 736
737 737 def get_config_options(self):
738 738 # contains sphinx configuration variables
739 739 config = self.state.document.settings.env.config
740 740
741 741 # get config variables to set figure output directory
742 742 confdir = self.state.document.settings.env.app.confdir
743 743 savefig_dir = config.ipython_savefig_dir
744 744 source_dir = os.path.dirname(self.state.document.current_source)
745 745 if savefig_dir is None:
746 746 savefig_dir = config.html_static_path
747 747 if isinstance(savefig_dir, list):
748 748 savefig_dir = savefig_dir[0] # safe to assume only one path?
749 749 savefig_dir = os.path.join(confdir, savefig_dir)
750 750
751 751 # get regex and prompt stuff
752 752 rgxin = config.ipython_rgxin
753 753 rgxout = config.ipython_rgxout
754 754 promptin = config.ipython_promptin
755 755 promptout = config.ipython_promptout
756 756 mplbackend = config.ipython_mplbackend
757 757 exec_lines = config.ipython_execlines
758 758 hold_count = config.ipython_holdcount
759 759
760 760 return (savefig_dir, source_dir, rgxin, rgxout,
761 761 promptin, promptout, mplbackend, exec_lines, hold_count)
762 762
763 763 def setup(self):
764 764 # Get configuration values.
765 765 (savefig_dir, source_dir, rgxin, rgxout, promptin, promptout,
766 766 mplbackend, exec_lines, hold_count) = self.get_config_options()
767 767
768 768 if self.shell is None:
769 769 # We will be here many times. However, when the
770 770 # EmbeddedSphinxShell is created, its interactive shell member
771 771 # is the same for each instance.
772 772
773 773 if mplbackend:
774 774 import matplotlib
775 775 # Repeated calls to use() will not hurt us since `mplbackend`
776 776 # is the same each time.
777 777 matplotlib.use(mplbackend)
778 778
779 779 # Must be called after (potentially) importing matplotlib and
780 780 # setting its backend since exec_lines might import pylab.
781 781 self.shell = EmbeddedSphinxShell(exec_lines)
782 782
783 783 # Store IPython directive to enable better error messages
784 784 self.shell.directive = self
785 785
786 786 # reset the execution count if we haven't processed this doc
787 787 #NOTE: this may be borked if there are multiple seen_doc tmp files
788 788 #check time stamp?
789 789 if not self.state.document.current_source in self.seen_docs:
790 790 self.shell.IP.history_manager.reset()
791 791 self.shell.IP.execution_count = 1
792 792 self.shell.IP.prompt_manager.width = 0
793 793 self.seen_docs.add(self.state.document.current_source)
794 794
795 795 # and attach to shell so we don't have to pass them around
796 796 self.shell.rgxin = rgxin
797 797 self.shell.rgxout = rgxout
798 798 self.shell.promptin = promptin
799 799 self.shell.promptout = promptout
800 800 self.shell.savefig_dir = savefig_dir
801 801 self.shell.source_dir = source_dir
802 802 self.shell.hold_count = hold_count
803 803
804 804 # setup bookmark for saving figures directory
805 805 self.shell.process_input_line('bookmark ipy_savedir %s'%savefig_dir,
806 806 store_history=False)
807 807 self.shell.clear_cout()
808 808
809 809 return rgxin, rgxout, promptin, promptout
810 810
811 811 def teardown(self):
812 812 # delete last bookmark
813 813 self.shell.process_input_line('bookmark -d ipy_savedir',
814 814 store_history=False)
815 815 self.shell.clear_cout()
816 816
817 817 def run(self):
818 818 debug = False
819 819
820 820 #TODO, any reason block_parser can't be a method of embeddable shell
821 821 # then we wouldn't have to carry these around
822 822 rgxin, rgxout, promptin, promptout = self.setup()
823 823
824 824 options = self.options
825 825 self.shell.is_suppress = 'suppress' in options
826 826 self.shell.is_doctest = 'doctest' in options
827 827 self.shell.is_verbatim = 'verbatim' in options
828 828 self.shell.is_okexcept = 'okexcept' in options
829 829 self.shell.is_okwarning = 'okwarning' in options
830 830
831 831 # handle pure python code
832 832 if 'python' in self.arguments:
833 833 content = self.content
834 834 self.content = self.shell.process_pure_python(content)
835 835
836 836 parts = '\n'.join(self.content).split('\n\n')
837 837
838 838 lines = ['.. code-block:: ipython', '']
839 839 figures = []
840 840
841 841 for part in parts:
842 842 block = block_parser(part, rgxin, rgxout, promptin, promptout)
843 843 if len(block):
844 844 rows, figure = self.shell.process_block(block)
845 845 for row in rows:
846 846 lines.extend([' %s'%line for line in row.split('\n')])
847 847
848 848 if figure is not None:
849 849 figures.append(figure)
850 850
851 851 for figure in figures:
852 852 lines.append('')
853 853 lines.extend(figure.split('\n'))
854 854 lines.append('')
855 855
856 856 if len(lines)>2:
857 857 if debug:
858 858 print('\n'.join(lines))
859 859 else:
860 860 # This has to do with input, not output. But if we comment
861 861 # these lines out, then no IPython code will appear in the
862 862 # final output.
863 863 self.state_machine.insert_input(
864 864 lines, self.state_machine.input_lines.source(0))
865 865
866 866 # cleanup
867 867 self.teardown()
868 868
869 869 return []
870 870
871 871 # Enable as a proper Sphinx directive
872 872 def setup(app):
873 873 setup.app = app
874 874
875 875 app.add_directive('ipython', IPythonDirective)
876 876 app.add_config_value('ipython_savefig_dir', None, 'env')
877 877 app.add_config_value('ipython_rgxin',
878 878 re.compile('In \[(\d+)\]:\s?(.*)\s*'), 'env')
879 879 app.add_config_value('ipython_rgxout',
880 880 re.compile('Out\[(\d+)\]:\s?(.*)\s*'), 'env')
881 881 app.add_config_value('ipython_promptin', 'In [%d]:', 'env')
882 882 app.add_config_value('ipython_promptout', 'Out[%d]:', 'env')
883 883
884 884 # We could just let matplotlib pick whatever is specified as the default
885 885 # backend in the matplotlibrc file, but this would cause issues if the
886 886 # backend didn't work in headless environments. For this reason, 'agg'
887 887 # is a good default backend choice.
888 888 app.add_config_value('ipython_mplbackend', 'agg', 'env')
889 889
890 890 # If the user sets this config value to `None`, then EmbeddedSphinxShell's
891 891 # __init__ method will treat it as [].
892 892 execlines = ['import numpy as np', 'import matplotlib.pyplot as plt']
893 893 app.add_config_value('ipython_execlines', execlines, 'env')
894 894
895 895 app.add_config_value('ipython_holdcount', True, 'env')
896 896
897 897 # Simple smoke test, needs to be converted to a proper automatic test.
898 898 def test():
899 899
900 900 examples = [
901 901 r"""
902 902 In [9]: pwd
903 903 Out[9]: '/home/jdhunter/py4science/book'
904 904
905 905 In [10]: cd bookdata/
906 906 /home/jdhunter/py4science/book/bookdata
907 907
908 908 In [2]: from pylab import *
909 909
910 910 In [2]: ion()
911 911
912 912 In [3]: im = imread('stinkbug.png')
913 913
914 914 @savefig mystinkbug.png width=4in
915 915 In [4]: imshow(im)
916 916 Out[4]: <matplotlib.image.AxesImage object at 0x39ea850>
917 917
918 918 """,
919 919 r"""
920 920
921 921 In [1]: x = 'hello world'
922 922
923 923 # string methods can be
924 924 # used to alter the string
925 925 @doctest
926 926 In [2]: x.upper()
927 927 Out[2]: 'HELLO WORLD'
928 928
929 929 @verbatim
930 930 In [3]: x.st<TAB>
931 931 x.startswith x.strip
932 932 """,
933 933 r"""
934 934
935 935 In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\
936 936 .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv'
937 937
938 938 In [131]: print url.split('&')
939 939 ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv']
940 940
941 941 In [60]: import urllib
942 942
943 943 """,
944 944 r"""\
945 945
946 946 In [133]: import numpy.random
947 947
948 948 @suppress
949 949 In [134]: numpy.random.seed(2358)
950 950
951 951 @doctest
952 952 In [135]: numpy.random.rand(10,2)
953 953 Out[135]:
954 954 array([[ 0.64524308, 0.59943846],
955 955 [ 0.47102322, 0.8715456 ],
956 956 [ 0.29370834, 0.74776844],
957 957 [ 0.99539577, 0.1313423 ],
958 958 [ 0.16250302, 0.21103583],
959 959 [ 0.81626524, 0.1312433 ],
960 960 [ 0.67338089, 0.72302393],
961 961 [ 0.7566368 , 0.07033696],
962 962 [ 0.22591016, 0.77731835],
963 963 [ 0.0072729 , 0.34273127]])
964 964
965 965 """,
966 966
967 967 r"""
968 968 In [106]: print x
969 969 jdh
970 970
971 971 In [109]: for i in range(10):
972 972 .....: print i
973 973 .....:
974 974 .....:
975 975 0
976 976 1
977 977 2
978 978 3
979 979 4
980 980 5
981 981 6
982 982 7
983 983 8
984 984 9
985 985 """,
986 986
987 987 r"""
988 988
989 989 In [144]: from pylab import *
990 990
991 991 In [145]: ion()
992 992
993 993 # use a semicolon to suppress the output
994 994 @savefig test_hist.png width=4in
995 995 In [151]: hist(np.random.randn(10000), 100);
996 996
997 997
998 998 @savefig test_plot.png width=4in
999 999 In [151]: plot(np.random.randn(10000), 'o');
1000 1000 """,
1001 1001
1002 1002 r"""
1003 1003 # use a semicolon to suppress the output
1004 1004 In [151]: plt.clf()
1005 1005
1006 1006 @savefig plot_simple.png width=4in
1007 1007 In [151]: plot([1,2,3])
1008 1008
1009 1009 @savefig hist_simple.png width=4in
1010 1010 In [151]: hist(np.random.randn(10000), 100);
1011 1011
1012 1012 """,
1013 1013 r"""
1014 1014 # update the current fig
1015 1015 In [151]: ylabel('number')
1016 1016
1017 1017 In [152]: title('normal distribution')
1018 1018
1019 1019
1020 1020 @savefig hist_with_text.png
1021 1021 In [153]: grid(True)
1022 1022
1023 1023 @doctest float
1024 1024 In [154]: 0.1 + 0.2
1025 1025 Out[154]: 0.3
1026 1026
1027 1027 @doctest float
1028 1028 In [155]: np.arange(16).reshape(4,4)
1029 1029 Out[155]:
1030 1030 array([[ 0, 1, 2, 3],
1031 1031 [ 4, 5, 6, 7],
1032 1032 [ 8, 9, 10, 11],
1033 1033 [12, 13, 14, 15]])
1034 1034
1035 1035 In [1]: x = np.arange(16, dtype=float).reshape(4,4)
1036 1036
1037 1037 In [2]: x[0,0] = np.inf
1038 1038
1039 1039 In [3]: x[0,1] = np.nan
1040 1040
1041 1041 @doctest float
1042 1042 In [4]: x
1043 1043 Out[4]:
1044 1044 array([[ inf, nan, 2., 3.],
1045 1045 [ 4., 5., 6., 7.],
1046 1046 [ 8., 9., 10., 11.],
1047 1047 [ 12., 13., 14., 15.]])
1048 1048
1049 1049
1050 1050 """,
1051 1051 ]
1052 1052 # skip local-file depending first example:
1053 1053 examples = examples[1:]
1054 1054
1055 1055 #ipython_directive.DEBUG = True # dbg
1056 1056 #options = dict(suppress=True) # dbg
1057 1057 options = dict()
1058 1058 for example in examples:
1059 1059 content = example.split('\n')
1060 1060 IPythonDirective('debug', arguments=None, options=options,
1061 1061 content=content, lineno=0,
1062 1062 content_offset=None, block_text=None,
1063 1063 state=None, state_machine=None,
1064 1064 )
1065 1065
1066 1066 # Run test suite as a script
1067 1067 if __name__=='__main__':
1068 1068 if not os.path.isdir('_static'):
1069 1069 os.mkdir('_static')
1070 1070 test()
1071 1071 print('All OK? Check figures in _static/')
@@ -1,501 +1,506 b''
1 1 # -*- coding: utf-8 -*-
2 2 """terminal client to the IPython kernel
3 3
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2013 The IPython Development Team
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING, distributed as part of this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15 from __future__ import print_function
16 16
17 17 import bdb
18 18 import signal
19 19 import os
20 20 import sys
21 21 import time
22 22 import subprocess
23 23 from io import BytesIO
24 24 import base64
25 25
26 26 try:
27 27 from queue import Empty # Py 3
28 28 except ImportError:
29 29 from Queue import Empty # Py 2
30 30
31 31 from IPython.core import page
32 32 from IPython.utils.warn import warn, error
33 33 from IPython.utils import io
34 34 from IPython.utils.py3compat import string_types, input
35 35 from IPython.utils.traitlets import List, Enum, Any, Instance, Unicode, Float
36 36 from IPython.utils.tempdir import NamedFileInTemporaryDirectory
37 37
38 38 from IPython.terminal.interactiveshell import TerminalInteractiveShell
39 39 from IPython.terminal.console.completer import ZMQCompleter
40 40
41 41
42 42 class ZMQTerminalInteractiveShell(TerminalInteractiveShell):
43 43 """A subclass of TerminalInteractiveShell that uses the 0MQ kernel"""
44 44 _executing = False
45 45 _execution_state = Unicode('')
46 46 kernel_timeout = Float(60, config=True,
47 47 help="""Timeout for giving up on a kernel (in seconds).
48 48
49 49 On first connect and restart, the console tests whether the
50 50 kernel is running and responsive by sending kernel_info_requests.
51 51 This sets the timeout in seconds for how long the kernel can take
52 52 before being presumed dead.
53 53 """
54 54 )
55 55
56 56 image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'),
57 57 config=True, help=
58 58 """
59 59 Handler for image type output. This is useful, for example,
60 60 when connecting to the kernel in which pylab inline backend is
61 61 activated. There are four handlers defined. 'PIL': Use
62 62 Python Imaging Library to popup image; 'stream': Use an
63 63 external program to show the image. Image will be fed into
64 64 the STDIN of the program. You will need to configure
65 65 `stream_image_handler`; 'tempfile': Use an external program to
66 66 show the image. Image will be saved in a temporally file and
67 67 the program is called with the temporally file. You will need
68 68 to configure `tempfile_image_handler`; 'callable': You can set
69 69 any Python callable which is called with the image data. You
70 70 will need to configure `callable_image_handler`.
71 71 """
72 72 )
73 73
74 74 stream_image_handler = List(config=True, help=
75 75 """
76 76 Command to invoke an image viewer program when you are using
77 77 'stream' image handler. This option is a list of string where
78 78 the first element is the command itself and reminders are the
79 79 options for the command. Raw image data is given as STDIN to
80 80 the program.
81 81 """
82 82 )
83 83
84 84 tempfile_image_handler = List(config=True, help=
85 85 """
86 86 Command to invoke an image viewer program when you are using
87 87 'tempfile' image handler. This option is a list of string
88 88 where the first element is the command itself and reminders
89 89 are the options for the command. You can use {file} and
90 90 {format} in the string to represent the location of the
91 91 generated image file and image format.
92 92 """
93 93 )
94 94
95 95 callable_image_handler = Any(config=True, help=
96 96 """
97 97 Callable object called via 'callable' image handler with one
98 98 argument, `data`, which is `msg["content"]["data"]` where
99 99 `msg` is the message from iopub channel. For exmaple, you can
100 100 find base64 encoded PNG data as `data['image/png']`.
101 101 """
102 102 )
103 103
104 104 mime_preference = List(
105 105 default_value=['image/png', 'image/jpeg', 'image/svg+xml'],
106 106 config=True, allow_none=False, help=
107 107 """
108 108 Preferred object representation MIME type in order. First
109 109 matched MIME type will be used.
110 110 """
111 111 )
112 112
113 113 manager = Instance('IPython.kernel.KernelManager')
114 114 client = Instance('IPython.kernel.KernelClient')
115 115 def _client_changed(self, name, old, new):
116 116 self.session_id = new.session.session
117 117 session_id = Unicode()
118 118
119 119 def init_completer(self):
120 120 """Initialize the completion machinery.
121 121
122 122 This creates completion machinery that can be used by client code,
123 123 either interactively in-process (typically triggered by the readline
124 124 library), programmatically (such as in test suites) or out-of-process
125 125 (typically over the network by remote frontends).
126 126 """
127 127 from IPython.core.completerlib import (module_completer,
128 128 magic_run_completer, cd_completer)
129 129
130 130 self.Completer = ZMQCompleter(self, self.client, config=self.config)
131 131
132 132
133 133 self.set_hook('complete_command', module_completer, str_key = 'import')
134 134 self.set_hook('complete_command', module_completer, str_key = 'from')
135 135 self.set_hook('complete_command', magic_run_completer, str_key = '%run')
136 136 self.set_hook('complete_command', cd_completer, str_key = '%cd')
137 137
138 138 # Only configure readline if we truly are using readline. IPython can
139 139 # do tab-completion over the network, in GUIs, etc, where readline
140 140 # itself may be absent
141 141 if self.has_readline:
142 142 self.set_readline_completer()
143 143
144 144 def ask_exit(self):
145 145 super(ZMQTerminalInteractiveShell, self).ask_exit()
146 146 if self.exit_now and self.manager:
147 147 self.client.shutdown()
148 148
149 149 def run_cell(self, cell, store_history=True):
150 150 """Run a complete IPython cell.
151 151
152 152 Parameters
153 153 ----------
154 154 cell : str
155 155 The code (including IPython code such as %magic functions) to run.
156 156 store_history : bool
157 157 If True, the raw and translated cell will be stored in IPython's
158 158 history. For user code calling back into IPython's machinery, this
159 159 should be set to False.
160 160 """
161 161 if (not cell) or cell.isspace():
162 162 return
163 163
164 164 if cell.strip() == 'exit':
165 165 # explicitly handle 'exit' command
166 166 return self.ask_exit()
167 167
168 168 # flush stale replies, which could have been ignored, due to missed heartbeats
169 169 while self.client.shell_channel.msg_ready():
170 170 self.client.shell_channel.get_msg()
171 171 # shell_channel.execute takes 'hidden', which is the inverse of store_hist
172 172 msg_id = self.client.shell_channel.execute(cell, not store_history)
173 173
174 174 # first thing is wait for any side effects (output, stdin, etc.)
175 175 self._executing = True
176 176 self._execution_state = "busy"
177 177 while self._execution_state != 'idle' and self.client.is_alive():
178 178 try:
179 179 self.handle_stdin_request(msg_id, timeout=0.05)
180 180 except Empty:
181 181 # display intermediate print statements, etc.
182 182 self.handle_iopub(msg_id)
183 183 pass
184 184
185 185 # after all of that is done, wait for the execute reply
186 186 while self.client.is_alive():
187 187 try:
188 188 self.handle_execute_reply(msg_id, timeout=0.05)
189 189 except Empty:
190 190 pass
191 191 else:
192 192 break
193 193 self._executing = False
194 194
195 195 #-----------------
196 196 # message handlers
197 197 #-----------------
198 198
199 199 def handle_execute_reply(self, msg_id, timeout=None):
200 200 msg = self.client.shell_channel.get_msg(block=False, timeout=timeout)
201 201 if msg["parent_header"].get("msg_id", None) == msg_id:
202 202
203 203 self.handle_iopub(msg_id)
204 204
205 205 content = msg["content"]
206 206 status = content['status']
207 207
208 208 if status == 'aborted':
209 209 self.write('Aborted\n')
210 210 return
211 211 elif status == 'ok':
212 212 # print execution payloads as well:
213 213 for item in content["payload"]:
214 214 text = item.get('text', None)
215 215 if text:
216 216 page.page(text)
217 217
218 218 elif status == 'error':
219 219 for frame in content["traceback"]:
220 220 print(frame, file=io.stderr)
221 221
222 222 self.execution_count = int(content["execution_count"] + 1)
223 223
224 224
225 225 def handle_iopub(self, msg_id):
226 226 """ Method to process subscribe channel's messages
227 227
228 228 This method consumes and processes messages on the IOPub channel,
229 229 such as stdout, stderr, pyout and status.
230 230
231 231 It only displays output that is caused by the given msg_id
232 232 """
233 233 while self.client.iopub_channel.msg_ready():
234 234 sub_msg = self.client.iopub_channel.get_msg()
235 235 msg_type = sub_msg['header']['msg_type']
236 236 parent = sub_msg["parent_header"]
237 237 if (not parent) or msg_id == parent['msg_id']:
238 238 if msg_type == 'status':
239 239 state = self._execution_state = sub_msg["content"]["execution_state"]
240 240 # idle messages mean an individual sequence is complete,
241 241 # so break out of consumption to allow other things to take over.
242 242 if state == 'idle':
243 243 break
244 244
245 245 elif msg_type == 'stream':
246 246 if sub_msg["content"]["name"] == "stdout":
247 247 print(sub_msg["content"]["data"], file=io.stdout, end="")
248 248 io.stdout.flush()
249 249 elif sub_msg["content"]["name"] == "stderr" :
250 250 print(sub_msg["content"]["data"], file=io.stderr, end="")
251 251 io.stderr.flush()
252 252
253 253 elif msg_type == 'pyout':
254 254 self.execution_count = int(sub_msg["content"]["execution_count"])
255 255 format_dict = sub_msg["content"]["data"]
256 256 self.handle_rich_data(format_dict)
257 257 # taken from DisplayHook.__call__:
258 258 hook = self.displayhook
259 259 hook.start_displayhook()
260 260 hook.write_output_prompt()
261 261 hook.write_format_data(format_dict)
262 262 hook.log_output(format_dict)
263 263 hook.finish_displayhook()
264 264
265 265 elif msg_type == 'display_data':
266 266 data = sub_msg["content"]["data"]
267 267 handled = self.handle_rich_data(data)
268 268 if not handled:
269 269 # if it was an image, we handled it by now
270 270 if 'text/plain' in data:
271 271 print(data['text/plain'])
272 272
273 273 _imagemime = {
274 274 'image/png': 'png',
275 275 'image/jpeg': 'jpeg',
276 276 'image/svg+xml': 'svg',
277 277 }
278 278
279 279 def handle_rich_data(self, data):
280 280 for mime in self.mime_preference:
281 281 if mime in data and mime in self._imagemime:
282 282 self.handle_image(data, mime)
283 283 return True
284 284
285 285 def handle_image(self, data, mime):
286 286 handler = getattr(
287 287 self, 'handle_image_{0}'.format(self.image_handler), None)
288 288 if handler:
289 289 handler(data, mime)
290 290
291 291 def handle_image_PIL(self, data, mime):
292 292 if mime not in ('image/png', 'image/jpeg'):
293 293 return
294 294 import PIL.Image
295 295 raw = base64.decodestring(data[mime].encode('ascii'))
296 296 img = PIL.Image.open(BytesIO(raw))
297 297 img.show()
298 298
299 299 def handle_image_stream(self, data, mime):
300 300 raw = base64.decodestring(data[mime].encode('ascii'))
301 301 imageformat = self._imagemime[mime]
302 302 fmt = dict(format=imageformat)
303 303 args = [s.format(**fmt) for s in self.stream_image_handler]
304 304 with open(os.devnull, 'w') as devnull:
305 305 proc = subprocess.Popen(
306 306 args, stdin=subprocess.PIPE,
307 307 stdout=devnull, stderr=devnull)
308 308 proc.communicate(raw)
309 309
310 310 def handle_image_tempfile(self, data, mime):
311 311 raw = base64.decodestring(data[mime].encode('ascii'))
312 312 imageformat = self._imagemime[mime]
313 313 filename = 'tmp.{0}'.format(imageformat)
314 314 with NamedFileInTemporaryDirectory(filename) as f, \
315 315 open(os.devnull, 'w') as devnull:
316 316 f.write(raw)
317 317 f.flush()
318 318 fmt = dict(file=f.name, format=imageformat)
319 319 args = [s.format(**fmt) for s in self.tempfile_image_handler]
320 320 subprocess.call(args, stdout=devnull, stderr=devnull)
321 321
322 322 def handle_image_callable(self, data, mime):
323 323 self.callable_image_handler(data)
324 324
325 325 def handle_stdin_request(self, msg_id, timeout=0.1):
326 326 """ Method to capture raw_input
327 327 """
328 328 msg_rep = self.client.stdin_channel.get_msg(timeout=timeout)
329 329 # in case any iopub came while we were waiting:
330 330 self.handle_iopub(msg_id)
331 331 if msg_id == msg_rep["parent_header"].get("msg_id"):
332 332 # wrap SIGINT handler
333 333 real_handler = signal.getsignal(signal.SIGINT)
334 334 def double_int(sig,frame):
335 335 # call real handler (forwards sigint to kernel),
336 336 # then raise local interrupt, stopping local raw_input
337 337 real_handler(sig,frame)
338 338 raise KeyboardInterrupt
339 339 signal.signal(signal.SIGINT, double_int)
340 340
341 341 try:
342 342 raw_data = input(msg_rep["content"]["prompt"])
343 343 except EOFError:
344 344 # turn EOFError into EOF character
345 345 raw_data = '\x04'
346 346 except KeyboardInterrupt:
347 347 sys.stdout.write('\n')
348 348 return
349 349 finally:
350 350 # restore SIGINT handler
351 351 signal.signal(signal.SIGINT, real_handler)
352 352
353 353 # only send stdin reply if there *was not* another request
354 354 # or execution finished while we were reading.
355 355 if not (self.client.stdin_channel.msg_ready() or self.client.shell_channel.msg_ready()):
356 356 self.client.stdin_channel.input(raw_data)
357 357
358 358 def mainloop(self, display_banner=False):
359 359 while True:
360 360 try:
361 361 self.interact(display_banner=display_banner)
362 362 #self.interact_with_readline()
363 363 # XXX for testing of a readline-decoupled repl loop, call
364 364 # interact_with_readline above
365 365 break
366 366 except KeyboardInterrupt:
367 367 # this should not be necessary, but KeyboardInterrupt
368 368 # handling seems rather unpredictable...
369 369 self.write("\nKeyboardInterrupt in interact()\n")
370 370
371 371 def wait_for_kernel(self, timeout=None):
372 372 """method to wait for a kernel to be ready"""
373 373 tic = time.time()
374 374 self.client.hb_channel.unpause()
375 375 while True:
376 376 msg_id = self.client.kernel_info()
377 377 reply = None
378 378 while True:
379 379 try:
380 380 reply = self.client.get_shell_msg(timeout=1)
381 381 except Empty:
382 382 break
383 383 else:
384 384 if reply['parent_header'].get('msg_id') == msg_id:
385 385 return True
386 386 if timeout is not None \
387 387 and (time.time() - tic) > timeout \
388 388 and not self.client.hb_channel.is_beating():
389 389 # heart failed
390 390 return False
391 391 return True
392 392
393 393 def interact(self, display_banner=None):
394 394 """Closely emulate the interactive Python console."""
395 395
396 396 # batch run -> do not interact
397 397 if self.exit_now:
398 398 return
399 399
400 400 if display_banner is None:
401 401 display_banner = self.display_banner
402 402
403 403 if isinstance(display_banner, string_types):
404 404 self.show_banner(display_banner)
405 405 elif display_banner:
406 406 self.show_banner()
407 407
408 408 more = False
409 409
410 410 # run a non-empty no-op, so that we don't get a prompt until
411 411 # we know the kernel is ready. This keeps the connection
412 412 # message above the first prompt.
413 413 if not self.wait_for_kernel(self.kernel_timeout):
414 414 error("Kernel did not respond\n")
415 415 return
416 416
417 417 if self.has_readline:
418 418 self.readline_startup_hook(self.pre_readline)
419 419 hlen_b4_cell = self.readline.get_current_history_length()
420 420 else:
421 421 hlen_b4_cell = 0
422 422 # exit_now is set by a call to %Exit or %Quit, through the
423 423 # ask_exit callback.
424 424
425 425 while not self.exit_now:
426 426 if not self.client.is_alive():
427 427 # kernel died, prompt for action or exit
428 428
429 429 action = "restart" if self.manager else "wait for restart"
430 430 ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y')
431 431 if ans:
432 432 if self.manager:
433 433 self.manager.restart_kernel(True)
434 434 self.wait_for_kernel(self.kernel_timeout)
435 435 else:
436 436 self.exit_now = True
437 437 continue
438 438 try:
439 439 # protect prompt block from KeyboardInterrupt
440 440 # when sitting on ctrl-C
441 441 self.hooks.pre_prompt_hook()
442 442 if more:
443 443 try:
444 444 prompt = self.prompt_manager.render('in2')
445 445 except Exception:
446 446 self.showtraceback()
447 447 if self.autoindent:
448 448 self.rl_do_indent = True
449 449
450 450 else:
451 451 try:
452 452 prompt = self.separate_in + self.prompt_manager.render('in')
453 453 except Exception:
454 454 self.showtraceback()
455 455
456 456 line = self.raw_input(prompt)
457 457 if self.exit_now:
458 458 # quick exit on sys.std[in|out] close
459 459 break
460 460 if self.autoindent:
461 461 self.rl_do_indent = False
462 462
463 463 except KeyboardInterrupt:
464 464 #double-guard against keyboardinterrupts during kbdint handling
465 465 try:
466 466 self.write('\nKeyboardInterrupt\n')
467 source_raw = self.input_splitter.source_raw_reset()[1]
467 source_raw = self.input_splitter.raw_reset()
468 468 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
469 469 more = False
470 470 except KeyboardInterrupt:
471 471 pass
472 472 except EOFError:
473 473 if self.autoindent:
474 474 self.rl_do_indent = False
475 475 if self.has_readline:
476 476 self.readline_startup_hook(None)
477 477 self.write('\n')
478 478 self.exit()
479 479 except bdb.BdbQuit:
480 480 warn('The Python debugger has exited with a BdbQuit exception.\n'
481 481 'Because of how pdb handles the stack, it is impossible\n'
482 482 'for IPython to properly format this particular exception.\n'
483 483 'IPython will resume normal operation.')
484 484 except:
485 485 # exceptions here are VERY RARE, but they can be triggered
486 486 # asynchronously by signal handlers, for example.
487 487 self.showtraceback()
488 488 else:
489 self.input_splitter.push(line)
490 more = self.input_splitter.push_accepts_more()
489 try:
490 self.input_splitter.push(line)
491 more = self.input_splitter.push_accepts_more()
492 except SyntaxError:
493 # Run the code directly - run_cell takes care of displaying
494 # the exception.
495 more = False
491 496 if (self.SyntaxTB.last_syntax_error and
492 497 self.autoedit_syntax):
493 498 self.edit_syntax_error()
494 499 if not more:
495 source_raw = self.input_splitter.source_raw_reset()[1]
500 source_raw = self.input_splitter.raw_reset()
496 501 hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
497 502 self.run_cell(source_raw)
498 503
499 504
500 505 # Turn off the exit flag, so the mainloop can be restarted if desired
501 506 self.exit_now = False
@@ -1,697 +1,702 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Subclass of InteractiveShell for terminal based frontends."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 import bdb
19 19 import os
20 20 import sys
21 21
22 22 from IPython.core.error import TryNext, UsageError
23 23 from IPython.core.usage import interactive_usage, default_banner
24 24 from IPython.core.inputsplitter import IPythonInputSplitter
25 25 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
26 26 from IPython.core.magic import Magics, magics_class, line_magic
27 27 from IPython.lib.clipboard import ClipboardEmpty
28 28 from IPython.testing.skipdoctest import skip_doctest
29 29 from IPython.utils.encoding import get_stream_enc
30 30 from IPython.utils import py3compat
31 31 from IPython.utils.terminal import toggle_set_term_title, set_term_title
32 32 from IPython.utils.process import abbrev_cwd
33 33 from IPython.utils.warn import warn, error
34 34 from IPython.utils.text import num_ini_spaces, SList, strip_email_quotes
35 35 from IPython.utils.traitlets import Integer, CBool, Unicode
36 36
37 37 #-----------------------------------------------------------------------------
38 38 # Utilities
39 39 #-----------------------------------------------------------------------------
40 40
41 41 def get_default_editor():
42 42 try:
43 43 ed = os.environ['EDITOR']
44 44 if not py3compat.PY3:
45 45 ed = ed.decode()
46 46 return ed
47 47 except KeyError:
48 48 pass
49 49 except UnicodeError:
50 50 warn("$EDITOR environment variable is not pure ASCII. Using platform "
51 51 "default editor.")
52 52
53 53 if os.name == 'posix':
54 54 return 'vi' # the only one guaranteed to be there!
55 55 else:
56 56 return 'notepad' # same in Windows!
57 57
58 58 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
59 59 """ Yield pasted lines until the user enters the given sentinel value.
60 60 """
61 61 if not quiet:
62 62 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
63 63 % sentinel)
64 64 prompt = ":"
65 65 else:
66 66 prompt = ""
67 67 while True:
68 68 try:
69 69 l = l_input(prompt)
70 70 if l == sentinel:
71 71 return
72 72 else:
73 73 yield l
74 74 except EOFError:
75 75 print('<EOF>')
76 76 return
77 77
78 78
79 79 #------------------------------------------------------------------------
80 80 # Terminal-specific magics
81 81 #------------------------------------------------------------------------
82 82
83 83 @magics_class
84 84 class TerminalMagics(Magics):
85 85 def __init__(self, shell):
86 86 super(TerminalMagics, self).__init__(shell)
87 87 self.input_splitter = IPythonInputSplitter()
88 88
89 89 def store_or_execute(self, block, name):
90 90 """ Execute a block, or store it in a variable, per the user's request.
91 91 """
92 92 if name:
93 93 # If storing it for further editing
94 94 self.shell.user_ns[name] = SList(block.splitlines())
95 95 print("Block assigned to '%s'" % name)
96 96 else:
97 97 b = self.preclean_input(block)
98 98 self.shell.user_ns['pasted_block'] = b
99 99 self.shell.using_paste_magics = True
100 100 try:
101 101 self.shell.run_cell(b)
102 102 finally:
103 103 self.shell.using_paste_magics = False
104 104
105 105 def preclean_input(self, block):
106 106 lines = block.splitlines()
107 107 while lines and not lines[0].strip():
108 108 lines = lines[1:]
109 109 return strip_email_quotes('\n'.join(lines))
110 110
111 111 def rerun_pasted(self, name='pasted_block'):
112 112 """ Rerun a previously pasted command.
113 113 """
114 114 b = self.shell.user_ns.get(name)
115 115
116 116 # Sanity checks
117 117 if b is None:
118 118 raise UsageError('No previous pasted block available')
119 119 if not isinstance(b, py3compat.string_types):
120 120 raise UsageError(
121 121 "Variable 'pasted_block' is not a string, can't execute")
122 122
123 123 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
124 124 self.shell.run_cell(b)
125 125
126 126 @line_magic
127 127 def autoindent(self, parameter_s = ''):
128 128 """Toggle autoindent on/off (if available)."""
129 129
130 130 self.shell.set_autoindent()
131 131 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
132 132
133 133 @skip_doctest
134 134 @line_magic
135 135 def cpaste(self, parameter_s=''):
136 136 """Paste & execute a pre-formatted code block from clipboard.
137 137
138 138 You must terminate the block with '--' (two minus-signs) or Ctrl-D
139 139 alone on the line. You can also provide your own sentinel with '%paste
140 140 -s %%' ('%%' is the new sentinel for this operation).
141 141
142 142 The block is dedented prior to execution to enable execution of method
143 143 definitions. '>' and '+' characters at the beginning of a line are
144 144 ignored, to allow pasting directly from e-mails, diff files and
145 145 doctests (the '...' continuation prompt is also stripped). The
146 146 executed block is also assigned to variable named 'pasted_block' for
147 147 later editing with '%edit pasted_block'.
148 148
149 149 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
150 150 This assigns the pasted block to variable 'foo' as string, without
151 151 dedenting or executing it (preceding >>> and + is still stripped)
152 152
153 153 '%cpaste -r' re-executes the block previously entered by cpaste.
154 154 '%cpaste -q' suppresses any additional output messages.
155 155
156 156 Do not be alarmed by garbled output on Windows (it's a readline bug).
157 157 Just press enter and type -- (and press enter again) and the block
158 158 will be what was just pasted.
159 159
160 160 IPython statements (magics, shell escapes) are not supported (yet).
161 161
162 162 See also
163 163 --------
164 164 paste: automatically pull code from clipboard.
165 165
166 166 Examples
167 167 --------
168 168 ::
169 169
170 170 In [8]: %cpaste
171 171 Pasting code; enter '--' alone on the line to stop.
172 172 :>>> a = ["world!", "Hello"]
173 173 :>>> print " ".join(sorted(a))
174 174 :--
175 175 Hello world!
176 176 """
177 177 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
178 178 if 'r' in opts:
179 179 self.rerun_pasted()
180 180 return
181 181
182 182 quiet = ('q' in opts)
183 183
184 184 sentinel = opts.get('s', '--')
185 185 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
186 186 self.store_or_execute(block, name)
187 187
188 188 @line_magic
189 189 def paste(self, parameter_s=''):
190 190 """Paste & execute a pre-formatted code block from clipboard.
191 191
192 192 The text is pulled directly from the clipboard without user
193 193 intervention and printed back on the screen before execution (unless
194 194 the -q flag is given to force quiet mode).
195 195
196 196 The block is dedented prior to execution to enable execution of method
197 197 definitions. '>' and '+' characters at the beginning of a line are
198 198 ignored, to allow pasting directly from e-mails, diff files and
199 199 doctests (the '...' continuation prompt is also stripped). The
200 200 executed block is also assigned to variable named 'pasted_block' for
201 201 later editing with '%edit pasted_block'.
202 202
203 203 You can also pass a variable name as an argument, e.g. '%paste foo'.
204 204 This assigns the pasted block to variable 'foo' as string, without
205 205 executing it (preceding >>> and + is still stripped).
206 206
207 207 Options:
208 208
209 209 -r: re-executes the block previously entered by cpaste.
210 210
211 211 -q: quiet mode: do not echo the pasted text back to the terminal.
212 212
213 213 IPython statements (magics, shell escapes) are not supported (yet).
214 214
215 215 See also
216 216 --------
217 217 cpaste: manually paste code into terminal until you mark its end.
218 218 """
219 219 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
220 220 if 'r' in opts:
221 221 self.rerun_pasted()
222 222 return
223 223 try:
224 224 block = self.shell.hooks.clipboard_get()
225 225 except TryNext as clipboard_exc:
226 226 message = getattr(clipboard_exc, 'args')
227 227 if message:
228 228 error(message[0])
229 229 else:
230 230 error('Could not get text from the clipboard.')
231 231 return
232 232 except ClipboardEmpty:
233 233 raise UsageError("The clipboard appears to be empty")
234 234
235 235 # By default, echo back to terminal unless quiet mode is requested
236 236 if 'q' not in opts:
237 237 write = self.shell.write
238 238 write(self.shell.pycolorize(block))
239 239 if not block.endswith('\n'):
240 240 write('\n')
241 241 write("## -- End pasted text --\n")
242 242
243 243 self.store_or_execute(block, name)
244 244
245 245 # Class-level: add a '%cls' magic only on Windows
246 246 if sys.platform == 'win32':
247 247 @line_magic
248 248 def cls(self, s):
249 249 """Clear screen.
250 250 """
251 251 os.system("cls")
252 252
253 253 #-----------------------------------------------------------------------------
254 254 # Main class
255 255 #-----------------------------------------------------------------------------
256 256
257 257 class TerminalInteractiveShell(InteractiveShell):
258 258
259 259 autoedit_syntax = CBool(False, config=True,
260 260 help="auto editing of files with syntax errors.")
261 261 banner = Unicode('')
262 262 banner1 = Unicode(default_banner, config=True,
263 263 help="""The part of the banner to be printed before the profile"""
264 264 )
265 265 banner2 = Unicode('', config=True,
266 266 help="""The part of the banner to be printed after the profile"""
267 267 )
268 268 confirm_exit = CBool(True, config=True,
269 269 help="""
270 270 Set to confirm when you try to exit IPython with an EOF (Control-D
271 271 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
272 272 you can force a direct exit without any confirmation.""",
273 273 )
274 274 # This display_banner only controls whether or not self.show_banner()
275 275 # is called when mainloop/interact are called. The default is False
276 276 # because for the terminal based application, the banner behavior
277 277 # is controlled by Global.display_banner, which IPythonApp looks at
278 278 # to determine if *it* should call show_banner() by hand or not.
279 279 display_banner = CBool(False) # This isn't configurable!
280 280 embedded = CBool(False)
281 281 embedded_active = CBool(False)
282 282 editor = Unicode(get_default_editor(), config=True,
283 283 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
284 284 )
285 285 pager = Unicode('less', config=True,
286 286 help="The shell program to be used for paging.")
287 287
288 288 screen_length = Integer(0, config=True,
289 289 help=
290 290 """Number of lines of your screen, used to control printing of very
291 291 long strings. Strings longer than this number of lines will be sent
292 292 through a pager instead of directly printed. The default value for
293 293 this is 0, which means IPython will auto-detect your screen size every
294 294 time it needs to print certain potentially long strings (this doesn't
295 295 change the behavior of the 'print' keyword, it's only triggered
296 296 internally). If for some reason this isn't working well (it needs
297 297 curses support), specify it yourself. Otherwise don't change the
298 298 default.""",
299 299 )
300 300 term_title = CBool(False, config=True,
301 301 help="Enable auto setting the terminal title."
302 302 )
303 303
304 304 # This `using_paste_magics` is used to detect whether the code is being
305 305 # executed via paste magics functions
306 306 using_paste_magics = CBool(False)
307 307
308 308 # In the terminal, GUI control is done via PyOS_InputHook
309 309 @staticmethod
310 310 def enable_gui(gui=None, app=None):
311 311 """Switch amongst GUI input hooks by name.
312 312 """
313 313 # Deferred import
314 314 from IPython.lib.inputhook import enable_gui as real_enable_gui
315 315 try:
316 316 return real_enable_gui(gui, app)
317 317 except ValueError as e:
318 318 raise UsageError("%s" % e)
319 319
320 320 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
321 321 user_ns=None, user_module=None, custom_exceptions=((),None),
322 322 usage=None, banner1=None, banner2=None, display_banner=None,
323 323 **kwargs):
324 324
325 325 super(TerminalInteractiveShell, self).__init__(
326 326 config=config, ipython_dir=ipython_dir, profile_dir=profile_dir, user_ns=user_ns,
327 327 user_module=user_module, custom_exceptions=custom_exceptions,
328 328 **kwargs
329 329 )
330 330 # use os.system instead of utils.process.system by default,
331 331 # because piped system doesn't make sense in the Terminal:
332 332 self.system = self.system_raw
333 333
334 334 self.init_term_title()
335 335 self.init_usage(usage)
336 336 self.init_banner(banner1, banner2, display_banner)
337 337
338 338 #-------------------------------------------------------------------------
339 339 # Overrides of init stages
340 340 #-------------------------------------------------------------------------
341 341
342 342 def init_display_formatter(self):
343 343 super(TerminalInteractiveShell, self).init_display_formatter()
344 344 # terminal only supports plaintext
345 345 self.display_formatter.active_types = ['text/plain']
346 346
347 347 #-------------------------------------------------------------------------
348 348 # Things related to the terminal
349 349 #-------------------------------------------------------------------------
350 350
351 351 @property
352 352 def usable_screen_length(self):
353 353 if self.screen_length == 0:
354 354 return 0
355 355 else:
356 356 num_lines_bot = self.separate_in.count('\n')+1
357 357 return self.screen_length - num_lines_bot
358 358
359 359 def init_term_title(self):
360 360 # Enable or disable the terminal title.
361 361 if self.term_title:
362 362 toggle_set_term_title(True)
363 363 set_term_title('IPython: ' + abbrev_cwd())
364 364 else:
365 365 toggle_set_term_title(False)
366 366
367 367 #-------------------------------------------------------------------------
368 368 # Things related to aliases
369 369 #-------------------------------------------------------------------------
370 370
371 371 def init_alias(self):
372 372 # The parent class defines aliases that can be safely used with any
373 373 # frontend.
374 374 super(TerminalInteractiveShell, self).init_alias()
375 375
376 376 # Now define aliases that only make sense on the terminal, because they
377 377 # need direct access to the console in a way that we can't emulate in
378 378 # GUI or web frontend
379 379 if os.name == 'posix':
380 380 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
381 381 ('man', 'man')]
382 382 else :
383 383 aliases = []
384 384
385 385 for name, cmd in aliases:
386 386 self.alias_manager.soft_define_alias(name, cmd)
387 387
388 388 #-------------------------------------------------------------------------
389 389 # Things related to the banner and usage
390 390 #-------------------------------------------------------------------------
391 391
392 392 def _banner1_changed(self):
393 393 self.compute_banner()
394 394
395 395 def _banner2_changed(self):
396 396 self.compute_banner()
397 397
398 398 def _term_title_changed(self, name, new_value):
399 399 self.init_term_title()
400 400
401 401 def init_banner(self, banner1, banner2, display_banner):
402 402 if banner1 is not None:
403 403 self.banner1 = banner1
404 404 if banner2 is not None:
405 405 self.banner2 = banner2
406 406 if display_banner is not None:
407 407 self.display_banner = display_banner
408 408 self.compute_banner()
409 409
410 410 def show_banner(self, banner=None):
411 411 if banner is None:
412 412 banner = self.banner
413 413 self.write(banner)
414 414
415 415 def compute_banner(self):
416 416 self.banner = self.banner1
417 417 if self.profile and self.profile != 'default':
418 418 self.banner += '\nIPython profile: %s\n' % self.profile
419 419 if self.banner2:
420 420 self.banner += '\n' + self.banner2
421 421
422 422 def init_usage(self, usage=None):
423 423 if usage is None:
424 424 self.usage = interactive_usage
425 425 else:
426 426 self.usage = usage
427 427
428 428 #-------------------------------------------------------------------------
429 429 # Mainloop and code execution logic
430 430 #-------------------------------------------------------------------------
431 431
432 432 def mainloop(self, display_banner=None):
433 433 """Start the mainloop.
434 434
435 435 If an optional banner argument is given, it will override the
436 436 internally created default banner.
437 437 """
438 438
439 439 with self.builtin_trap, self.display_trap:
440 440
441 441 while 1:
442 442 try:
443 443 self.interact(display_banner=display_banner)
444 444 #self.interact_with_readline()
445 445 # XXX for testing of a readline-decoupled repl loop, call
446 446 # interact_with_readline above
447 447 break
448 448 except KeyboardInterrupt:
449 449 # this should not be necessary, but KeyboardInterrupt
450 450 # handling seems rather unpredictable...
451 451 self.write("\nKeyboardInterrupt in interact()\n")
452 452
453 453 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
454 454 """Store multiple lines as a single entry in history"""
455 455
456 456 # do nothing without readline or disabled multiline
457 457 if not self.has_readline or not self.multiline_history:
458 458 return hlen_before_cell
459 459
460 460 # windows rl has no remove_history_item
461 461 if not hasattr(self.readline, "remove_history_item"):
462 462 return hlen_before_cell
463 463
464 464 # skip empty cells
465 465 if not source_raw.rstrip():
466 466 return hlen_before_cell
467 467
468 468 # nothing changed do nothing, e.g. when rl removes consecutive dups
469 469 hlen = self.readline.get_current_history_length()
470 470 if hlen == hlen_before_cell:
471 471 return hlen_before_cell
472 472
473 473 for i in range(hlen - hlen_before_cell):
474 474 self.readline.remove_history_item(hlen - i - 1)
475 475 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
476 476 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
477 477 stdin_encoding))
478 478 return self.readline.get_current_history_length()
479 479
480 480 def interact(self, display_banner=None):
481 481 """Closely emulate the interactive Python console."""
482 482
483 483 # batch run -> do not interact
484 484 if self.exit_now:
485 485 return
486 486
487 487 if display_banner is None:
488 488 display_banner = self.display_banner
489 489
490 490 if isinstance(display_banner, py3compat.string_types):
491 491 self.show_banner(display_banner)
492 492 elif display_banner:
493 493 self.show_banner()
494 494
495 495 more = False
496 496
497 497 if self.has_readline:
498 498 self.readline_startup_hook(self.pre_readline)
499 499 hlen_b4_cell = self.readline.get_current_history_length()
500 500 else:
501 501 hlen_b4_cell = 0
502 502 # exit_now is set by a call to %Exit or %Quit, through the
503 503 # ask_exit callback.
504 504
505 505 while not self.exit_now:
506 506 self.hooks.pre_prompt_hook()
507 507 if more:
508 508 try:
509 509 prompt = self.prompt_manager.render('in2')
510 510 except:
511 511 self.showtraceback()
512 512 if self.autoindent:
513 513 self.rl_do_indent = True
514 514
515 515 else:
516 516 try:
517 517 prompt = self.separate_in + self.prompt_manager.render('in')
518 518 except:
519 519 self.showtraceback()
520 520 try:
521 521 line = self.raw_input(prompt)
522 522 if self.exit_now:
523 523 # quick exit on sys.std[in|out] close
524 524 break
525 525 if self.autoindent:
526 526 self.rl_do_indent = False
527 527
528 528 except KeyboardInterrupt:
529 529 #double-guard against keyboardinterrupts during kbdint handling
530 530 try:
531 531 self.write('\nKeyboardInterrupt\n')
532 source_raw = self.input_splitter.source_raw_reset()[1]
532 source_raw = self.input_splitter.raw_reset()
533 533 hlen_b4_cell = \
534 534 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
535 535 more = False
536 536 except KeyboardInterrupt:
537 537 pass
538 538 except EOFError:
539 539 if self.autoindent:
540 540 self.rl_do_indent = False
541 541 if self.has_readline:
542 542 self.readline_startup_hook(None)
543 543 self.write('\n')
544 544 self.exit()
545 545 except bdb.BdbQuit:
546 546 warn('The Python debugger has exited with a BdbQuit exception.\n'
547 547 'Because of how pdb handles the stack, it is impossible\n'
548 548 'for IPython to properly format this particular exception.\n'
549 549 'IPython will resume normal operation.')
550 550 except:
551 551 # exceptions here are VERY RARE, but they can be triggered
552 552 # asynchronously by signal handlers, for example.
553 553 self.showtraceback()
554 554 else:
555 self.input_splitter.push(line)
556 more = self.input_splitter.push_accepts_more()
555 try:
556 self.input_splitter.push(line)
557 more = self.input_splitter.push_accepts_more()
558 except SyntaxError:
559 # Run the code directly - run_cell takes care of displaying
560 # the exception.
561 more = False
557 562 if (self.SyntaxTB.last_syntax_error and
558 563 self.autoedit_syntax):
559 564 self.edit_syntax_error()
560 565 if not more:
561 source_raw = self.input_splitter.source_raw_reset()[1]
566 source_raw = self.input_splitter.raw_reset()
562 567 self.run_cell(source_raw, store_history=True)
563 568 hlen_b4_cell = \
564 569 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
565 570
566 571 # Turn off the exit flag, so the mainloop can be restarted if desired
567 572 self.exit_now = False
568 573
569 574 def raw_input(self, prompt=''):
570 575 """Write a prompt and read a line.
571 576
572 577 The returned line does not include the trailing newline.
573 578 When the user enters the EOF key sequence, EOFError is raised.
574 579
575 580 Parameters
576 581 ----------
577 582
578 583 prompt : str, optional
579 584 A string to be printed to prompt the user.
580 585 """
581 586 # raw_input expects str, but we pass it unicode sometimes
582 587 prompt = py3compat.cast_bytes_py2(prompt)
583 588
584 589 try:
585 590 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
586 591 except ValueError:
587 592 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
588 593 " or sys.stdout.close()!\nExiting IPython!\n")
589 594 self.ask_exit()
590 595 return ""
591 596
592 597 # Try to be reasonably smart about not re-indenting pasted input more
593 598 # than necessary. We do this by trimming out the auto-indent initial
594 599 # spaces, if the user's actual input started itself with whitespace.
595 600 if self.autoindent:
596 601 if num_ini_spaces(line) > self.indent_current_nsp:
597 602 line = line[self.indent_current_nsp:]
598 603 self.indent_current_nsp = 0
599 604
600 605 return line
601 606
602 607 #-------------------------------------------------------------------------
603 608 # Methods to support auto-editing of SyntaxErrors.
604 609 #-------------------------------------------------------------------------
605 610
606 611 def edit_syntax_error(self):
607 612 """The bottom half of the syntax error handler called in the main loop.
608 613
609 614 Loop until syntax error is fixed or user cancels.
610 615 """
611 616
612 617 while self.SyntaxTB.last_syntax_error:
613 618 # copy and clear last_syntax_error
614 619 err = self.SyntaxTB.clear_err_state()
615 620 if not self._should_recompile(err):
616 621 return
617 622 try:
618 623 # may set last_syntax_error again if a SyntaxError is raised
619 624 self.safe_execfile(err.filename,self.user_ns)
620 625 except:
621 626 self.showtraceback()
622 627 else:
623 628 try:
624 629 f = open(err.filename)
625 630 try:
626 631 # This should be inside a display_trap block and I
627 632 # think it is.
628 633 sys.displayhook(f.read())
629 634 finally:
630 635 f.close()
631 636 except:
632 637 self.showtraceback()
633 638
634 639 def _should_recompile(self,e):
635 640 """Utility routine for edit_syntax_error"""
636 641
637 642 if e.filename in ('<ipython console>','<input>','<string>',
638 643 '<console>','<BackgroundJob compilation>',
639 644 None):
640 645
641 646 return False
642 647 try:
643 648 if (self.autoedit_syntax and
644 649 not self.ask_yes_no('Return to editor to correct syntax error? '
645 650 '[Y/n] ','y')):
646 651 return False
647 652 except EOFError:
648 653 return False
649 654
650 655 def int0(x):
651 656 try:
652 657 return int(x)
653 658 except TypeError:
654 659 return 0
655 660 # always pass integer line and offset values to editor hook
656 661 try:
657 662 self.hooks.fix_error_editor(e.filename,
658 663 int0(e.lineno),int0(e.offset),e.msg)
659 664 except TryNext:
660 665 warn('Could not open editor')
661 666 return False
662 667 return True
663 668
664 669 #-------------------------------------------------------------------------
665 670 # Things related to exiting
666 671 #-------------------------------------------------------------------------
667 672
668 673 def ask_exit(self):
669 674 """ Ask the shell to exit. Can be overiden and used as a callback. """
670 675 self.exit_now = True
671 676
672 677 def exit(self):
673 678 """Handle interactive exit.
674 679
675 680 This method calls the ask_exit callback."""
676 681 if self.confirm_exit:
677 682 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
678 683 self.ask_exit()
679 684 else:
680 685 self.ask_exit()
681 686
682 687 #-------------------------------------------------------------------------
683 688 # Things related to magics
684 689 #-------------------------------------------------------------------------
685 690
686 691 def init_magics(self):
687 692 super(TerminalInteractiveShell, self).init_magics()
688 693 self.register_magics(TerminalMagics)
689 694
690 695 def showindentationerror(self):
691 696 super(TerminalInteractiveShell, self).showindentationerror()
692 697 if not self.using_paste_magics:
693 698 print("If you want to paste code into IPython, try the "
694 699 "%paste and %cpaste magic functions.")
695 700
696 701
697 702 InteractiveShellABC.register(TerminalInteractiveShell)
@@ -1,203 +1,295 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tests for the key interactiveshell module.
3 3
4 4 Authors
5 5 -------
6 6 * Julian Taylor
7 7 """
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (C) 2011 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18 # stdlib
19 19 import sys
20 import types
20 21 import unittest
21 22
23 from IPython.core.inputtransformer import InputTransformer
22 24 from IPython.testing.decorators import skipif
23 25 from IPython.utils import py3compat
24 26 from IPython.testing import tools as tt
25 27
28 # Decorator for interaction loop tests -----------------------------------------
29
30 class mock_input_helper(object):
31 """Machinery for tests of the main interact loop.
32
33 Used by the mock_input decorator.
34 """
35 def __init__(self, testgen):
36 self.testgen = testgen
37 self.exception = None
38 self.ip = get_ipython()
39
40 def __enter__(self):
41 self.orig_raw_input = self.ip.raw_input
42 self.ip.raw_input = self.fake_input
43 return self
44
45 def __exit__(self, etype, value, tb):
46 self.ip.raw_input = self.orig_raw_input
47
48 def fake_input(self, prompt):
49 try:
50 return next(self.testgen)
51 except StopIteration:
52 self.ip.exit_now = True
53 return u''
54 except:
55 self.exception = sys.exc_info()
56 self.ip.exit_now = True
57 return u''
58
59 def mock_input(testfunc):
60 """Decorator for tests of the main interact loop.
61
62 Write the test as a generator, yield-ing the input strings, which IPython
63 will see as if they were typed in at the prompt.
64 """
65 def test_method(self):
66 testgen = testfunc(self)
67 with mock_input_helper(testgen) as mih:
68 mih.ip.interact(display_banner=False)
69
70 if mih.exception is not None:
71 # Re-raise captured exception
72 etype, value, tb = mih.exception
73 import traceback
74 traceback.print_tb(tb, file=sys.stdout)
75 del tb # Avoid reference loop
76 raise value
77
78 return test_method
79
80 # Test classes -----------------------------------------------------------------
81
26 82 class InteractiveShellTestCase(unittest.TestCase):
27 83 def rl_hist_entries(self, rl, n):
28 84 """Get last n readline history entries as a list"""
29 85 return [rl.get_history_item(rl.get_current_history_length() - x)
30 86 for x in range(n - 1, -1, -1)]
31 87
32 88 def test_runs_without_rl(self):
33 89 """Test that function does not throw without readline"""
34 90 ip = get_ipython()
35 91 ip.has_readline = False
36 92 ip.readline = None
37 93 ip._replace_rlhist_multiline(u'source', 0)
38 94
39 95 @skipif(not get_ipython().has_readline, 'no readline')
40 96 def test_runs_without_remove_history_item(self):
41 97 """Test that function does not throw on windows without
42 98 remove_history_item"""
43 99 ip = get_ipython()
44 100 if hasattr(ip.readline, 'remove_history_item'):
45 101 del ip.readline.remove_history_item
46 102 ip._replace_rlhist_multiline(u'source', 0)
47 103
48 104 @skipif(not get_ipython().has_readline, 'no readline')
49 105 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
50 106 'no remove_history_item')
51 107 def test_replace_multiline_hist_disabled(self):
52 108 """Test that multiline replace does nothing if disabled"""
53 109 ip = get_ipython()
54 110 ip.multiline_history = False
55 111
56 112 ghist = [u'line1', u'line2']
57 113 for h in ghist:
58 114 ip.readline.add_history(h)
59 115 hlen_b4_cell = ip.readline.get_current_history_length()
60 116 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€\nsource2',
61 117 hlen_b4_cell)
62 118
63 119 self.assertEqual(ip.readline.get_current_history_length(),
64 120 hlen_b4_cell)
65 121 hist = self.rl_hist_entries(ip.readline, 2)
66 122 self.assertEqual(hist, ghist)
67 123
68 124 @skipif(not get_ipython().has_readline, 'no readline')
69 125 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
70 126 'no remove_history_item')
71 127 def test_replace_multiline_hist_adds(self):
72 128 """Test that multiline replace function adds history"""
73 129 ip = get_ipython()
74 130
75 131 hlen_b4_cell = ip.readline.get_current_history_length()
76 132 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€', hlen_b4_cell)
77 133
78 134 self.assertEqual(hlen_b4_cell,
79 135 ip.readline.get_current_history_length())
80 136
81 137 @skipif(not get_ipython().has_readline, 'no readline')
82 138 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
83 139 'no remove_history_item')
84 140 def test_replace_multiline_hist_keeps_history(self):
85 141 """Test that multiline replace does not delete history"""
86 142 ip = get_ipython()
87 143 ip.multiline_history = True
88 144
89 145 ghist = [u'line1', u'line2']
90 146 for h in ghist:
91 147 ip.readline.add_history(h)
92 148
93 149 #start cell
94 150 hlen_b4_cell = ip.readline.get_current_history_length()
95 151 # nothing added to rl history, should do nothing
96 152 hlen_b4_cell = ip._replace_rlhist_multiline(u'sourc€\nsource2',
97 153 hlen_b4_cell)
98 154
99 155 self.assertEqual(ip.readline.get_current_history_length(),
100 156 hlen_b4_cell)
101 157 hist = self.rl_hist_entries(ip.readline, 2)
102 158 self.assertEqual(hist, ghist)
103 159
104 160
105 161 @skipif(not get_ipython().has_readline, 'no readline')
106 162 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
107 163 'no remove_history_item')
108 164 def test_replace_multiline_hist_replaces_twice(self):
109 165 """Test that multiline entries are replaced twice"""
110 166 ip = get_ipython()
111 167 ip.multiline_history = True
112 168
113 169 ip.readline.add_history(u'line0')
114 170 #start cell
115 171 hlen_b4_cell = ip.readline.get_current_history_length()
116 172 ip.readline.add_history('l€ne1')
117 173 ip.readline.add_history('line2')
118 174 #replace cell with single line
119 175 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne1\nline2',
120 176 hlen_b4_cell)
121 177 ip.readline.add_history('l€ne3')
122 178 ip.readline.add_history('line4')
123 179 #replace cell with single line
124 180 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne3\nline4',
125 181 hlen_b4_cell)
126 182
127 183 self.assertEqual(ip.readline.get_current_history_length(),
128 184 hlen_b4_cell)
129 185 hist = self.rl_hist_entries(ip.readline, 3)
130 186 expected = [u'line0', u'l€ne1\nline2', u'l€ne3\nline4']
131 187 # perform encoding, in case of casting due to ASCII locale
132 188 enc = sys.stdin.encoding or "utf-8"
133 189 expected = [ py3compat.unicode_to_str(e, enc) for e in expected ]
134 190 self.assertEqual(hist, expected)
135 191
136 192
137 193 @skipif(not get_ipython().has_readline, 'no readline')
138 194 @skipif(not hasattr(get_ipython().readline, 'remove_history_item'),
139 195 'no remove_history_item')
140 196 def test_replace_multiline_hist_replaces_empty_line(self):
141 197 """Test that multiline history skips empty line cells"""
142 198 ip = get_ipython()
143 199 ip.multiline_history = True
144 200
145 201 ip.readline.add_history(u'line0')
146 202 #start cell
147 203 hlen_b4_cell = ip.readline.get_current_history_length()
148 204 ip.readline.add_history('l€ne1')
149 205 ip.readline.add_history('line2')
150 206 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne1\nline2',
151 207 hlen_b4_cell)
152 208 ip.readline.add_history('')
153 209 hlen_b4_cell = ip._replace_rlhist_multiline(u'', hlen_b4_cell)
154 210 ip.readline.add_history('l€ne3')
155 211 hlen_b4_cell = ip._replace_rlhist_multiline(u'l€ne3', hlen_b4_cell)
156 212 ip.readline.add_history(' ')
157 213 hlen_b4_cell = ip._replace_rlhist_multiline(' ', hlen_b4_cell)
158 214 ip.readline.add_history('\t')
159 215 ip.readline.add_history('\t ')
160 216 hlen_b4_cell = ip._replace_rlhist_multiline('\t', hlen_b4_cell)
161 217 ip.readline.add_history('line4')
162 218 hlen_b4_cell = ip._replace_rlhist_multiline(u'line4', hlen_b4_cell)
163 219
164 220 self.assertEqual(ip.readline.get_current_history_length(),
165 221 hlen_b4_cell)
166 222 hist = self.rl_hist_entries(ip.readline, 4)
167 223 # expect no empty cells in history
168 224 expected = [u'line0', u'l€ne1\nline2', u'l€ne3', u'line4']
169 225 # perform encoding, in case of casting due to ASCII locale
170 226 enc = sys.stdin.encoding or "utf-8"
171 227 expected = [ py3compat.unicode_to_str(e, enc) for e in expected ]
172 228 self.assertEqual(hist, expected)
173 229
230 @mock_input
231 def test_inputtransformer_syntaxerror(self):
232 ip = get_ipython()
233 transformer = SyntaxErrorTransformer()
234 ip.input_splitter.python_line_transforms.append(transformer)
235 ip.input_transformer_manager.python_line_transforms.append(transformer)
236
237 try:
238 #raise Exception
239 with tt.AssertPrints('4', suppress=False):
240 yield u'print(2*2)'
241
242 with tt.AssertPrints('SyntaxError: input contains', suppress=False):
243 yield u'print(2345) # syntaxerror'
244
245 with tt.AssertPrints('16', suppress=False):
246 yield u'print(4*4)'
247
248 finally:
249 ip.input_splitter.python_line_transforms.remove(transformer)
250 ip.input_transformer_manager.python_line_transforms.remove(transformer)
251
252
253 class SyntaxErrorTransformer(InputTransformer):
254 def push(self, line):
255 pos = line.find('syntaxerror')
256 if pos >= 0:
257 e = SyntaxError('input contains "syntaxerror"')
258 e.text = line
259 e.offset = pos + 1
260 raise e
261 return line
262
263 def reset(self):
264 pass
265
174 266 class TerminalMagicsTestCase(unittest.TestCase):
175 267 def test_paste_magics_message(self):
176 268 """Test that an IndentationError while using paste magics doesn't
177 269 trigger a message about paste magics and also the opposite."""
178 270
179 271 ip = get_ipython()
180 272 s = ('for a in range(5):\n'
181 273 'print(a)')
182 274
183 275 tm = ip.magics_manager.registry['TerminalMagics']
184 276 with tt.AssertPrints("If you want to paste code into IPython, try the "
185 277 "%paste and %cpaste magic functions."):
186 278 ip.run_cell(s)
187 279
188 280 with tt.AssertNotPrints("If you want to paste code into IPython, try the "
189 281 "%paste and %cpaste magic functions."):
190 282 tm.store_or_execute(s, name=None)
191 283
192 284 def test_paste_magics_blankline(self):
193 285 """Test that code with a blank line doesn't get split (gh-3246)."""
194 286 ip = get_ipython()
195 287 s = ('def pasted_func(a):\n'
196 288 ' b = a+1\n'
197 289 '\n'
198 290 ' return b')
199 291
200 292 tm = ip.magics_manager.registry['TerminalMagics']
201 293 tm.store_or_execute(s, name=None)
202 294
203 295 self.assertEqual(ip.user_ns['pasted_func'](54), 55)
@@ -1,257 +1,262 b''
1 1 # encoding: utf-8
2 2 """
3 3 IO related utilities.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12 from __future__ import print_function
13 13 from __future__ import absolute_import
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18 import codecs
19 19 import os
20 20 import sys
21 21 import tempfile
22 22 from .capture import CapturedIO, capture_output
23 23 from .py3compat import string_types, input, PY3
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Code
27 27 #-----------------------------------------------------------------------------
28 28
29 29
30 30 class IOStream:
31 31
32 32 def __init__(self,stream, fallback=None):
33 33 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
34 34 if fallback is not None:
35 35 stream = fallback
36 36 else:
37 37 raise ValueError("fallback required, but not specified")
38 38 self.stream = stream
39 39 self._swrite = stream.write
40 40
41 41 # clone all methods not overridden:
42 42 def clone(meth):
43 43 return not hasattr(self, meth) and not meth.startswith('_')
44 44 for meth in filter(clone, dir(stream)):
45 45 setattr(self, meth, getattr(stream, meth))
46 46
47 def __repr__(self):
48 cls = self.__class__
49 tpl = '{mod}.{cls}({args})'
50 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
51
47 52 def write(self,data):
48 53 try:
49 54 self._swrite(data)
50 55 except:
51 56 try:
52 57 # print handles some unicode issues which may trip a plain
53 58 # write() call. Emulate write() by using an empty end
54 59 # argument.
55 60 print(data, end='', file=self.stream)
56 61 except:
57 62 # if we get here, something is seriously broken.
58 63 print('ERROR - failed to write data to stream:', self.stream,
59 64 file=sys.stderr)
60 65
61 66 def writelines(self, lines):
62 67 if isinstance(lines, string_types):
63 68 lines = [lines]
64 69 for line in lines:
65 70 self.write(line)
66 71
67 72 # This class used to have a writeln method, but regular files and streams
68 73 # in Python don't have this method. We need to keep this completely
69 74 # compatible so we removed it.
70 75
71 76 @property
72 77 def closed(self):
73 78 return self.stream.closed
74 79
75 80 def close(self):
76 81 pass
77 82
78 83 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
79 84 devnull = open(os.devnull, 'a')
80 85 stdin = IOStream(sys.stdin, fallback=devnull)
81 86 stdout = IOStream(sys.stdout, fallback=devnull)
82 87 stderr = IOStream(sys.stderr, fallback=devnull)
83 88
84 89 class IOTerm:
85 90 """ Term holds the file or file-like objects for handling I/O operations.
86 91
87 92 These are normally just sys.stdin, sys.stdout and sys.stderr but for
88 93 Windows they can can replaced to allow editing the strings before they are
89 94 displayed."""
90 95
91 96 # In the future, having IPython channel all its I/O operations through
92 97 # this class will make it easier to embed it into other environments which
93 98 # are not a normal terminal (such as a GUI-based shell)
94 99 def __init__(self, stdin=None, stdout=None, stderr=None):
95 100 mymodule = sys.modules[__name__]
96 101 self.stdin = IOStream(stdin, mymodule.stdin)
97 102 self.stdout = IOStream(stdout, mymodule.stdout)
98 103 self.stderr = IOStream(stderr, mymodule.stderr)
99 104
100 105
101 106 class Tee(object):
102 107 """A class to duplicate an output stream to stdout/err.
103 108
104 109 This works in a manner very similar to the Unix 'tee' command.
105 110
106 111 When the object is closed or deleted, it closes the original file given to
107 112 it for duplication.
108 113 """
109 114 # Inspired by:
110 115 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
111 116
112 117 def __init__(self, file_or_name, mode="w", channel='stdout'):
113 118 """Construct a new Tee object.
114 119
115 120 Parameters
116 121 ----------
117 122 file_or_name : filename or open filehandle (writable)
118 123 File that will be duplicated
119 124
120 125 mode : optional, valid mode for open().
121 126 If a filename was give, open with this mode.
122 127
123 128 channel : str, one of ['stdout', 'stderr']
124 129 """
125 130 if channel not in ['stdout', 'stderr']:
126 131 raise ValueError('Invalid channel spec %s' % channel)
127 132
128 133 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
129 134 self.file = file_or_name
130 135 else:
131 136 self.file = open(file_or_name, mode)
132 137 self.channel = channel
133 138 self.ostream = getattr(sys, channel)
134 139 setattr(sys, channel, self)
135 140 self._closed = False
136 141
137 142 def close(self):
138 143 """Close the file and restore the channel."""
139 144 self.flush()
140 145 setattr(sys, self.channel, self.ostream)
141 146 self.file.close()
142 147 self._closed = True
143 148
144 149 def write(self, data):
145 150 """Write data to both channels."""
146 151 self.file.write(data)
147 152 self.ostream.write(data)
148 153 self.ostream.flush()
149 154
150 155 def flush(self):
151 156 """Flush both channels."""
152 157 self.file.flush()
153 158 self.ostream.flush()
154 159
155 160 def __del__(self):
156 161 if not self._closed:
157 162 self.close()
158 163
159 164
160 165 def ask_yes_no(prompt, default=None, interrupt=None):
161 166 """Asks a question and returns a boolean (y/n) answer.
162 167
163 168 If default is given (one of 'y','n'), it is used if the user input is
164 169 empty. If interrupt is given (one of 'y','n'), it is used if the user
165 170 presses Ctrl-C. Otherwise the question is repeated until an answer is
166 171 given.
167 172
168 173 An EOF is treated as the default answer. If there is no default, an
169 174 exception is raised to prevent infinite loops.
170 175
171 176 Valid answers are: y/yes/n/no (match is not case sensitive)."""
172 177
173 178 answers = {'y':True,'n':False,'yes':True,'no':False}
174 179 ans = None
175 180 while ans not in answers.keys():
176 181 try:
177 182 ans = input(prompt+' ').lower()
178 183 if not ans: # response was an empty string
179 184 ans = default
180 185 except KeyboardInterrupt:
181 186 if interrupt:
182 187 ans = interrupt
183 188 except EOFError:
184 189 if default in answers.keys():
185 190 ans = default
186 191 print()
187 192 else:
188 193 raise
189 194
190 195 return answers[ans]
191 196
192 197
193 198 def temp_pyfile(src, ext='.py'):
194 199 """Make a temporary python file, return filename and filehandle.
195 200
196 201 Parameters
197 202 ----------
198 203 src : string or list of strings (no need for ending newlines if list)
199 204 Source code to be written to the file.
200 205
201 206 ext : optional, string
202 207 Extension for the generated file.
203 208
204 209 Returns
205 210 -------
206 211 (filename, open filehandle)
207 212 It is the caller's responsibility to close the open file and unlink it.
208 213 """
209 214 fname = tempfile.mkstemp(ext)[1]
210 215 f = open(fname,'w')
211 216 f.write(src)
212 217 f.flush()
213 218 return fname, f
214 219
215 220
216 221 def raw_print(*args, **kw):
217 222 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
218 223
219 224 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
220 225 file=sys.__stdout__)
221 226 sys.__stdout__.flush()
222 227
223 228
224 229 def raw_print_err(*args, **kw):
225 230 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
226 231
227 232 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
228 233 file=sys.__stderr__)
229 234 sys.__stderr__.flush()
230 235
231 236
232 237 # Short aliases for quick debugging, do NOT use these in production code.
233 238 rprint = raw_print
234 239 rprinte = raw_print_err
235 240
236 241 def unicode_std_stream(stream='stdout'):
237 242 u"""Get a wrapper to write unicode to stdout/stderr as UTF-8.
238 243
239 244 This ignores environment variables and default encodings, to reliably write
240 245 unicode to stdout or stderr.
241 246
242 247 ::
243 248
244 249 unicode_std_stream().write(u'Ε‚@e¢ŧ←')
245 250 """
246 251 assert stream in ('stdout', 'stderr')
247 252 stream = getattr(sys, stream)
248 253 if PY3:
249 254 try:
250 255 stream_b = stream.buffer
251 256 except AttributeError:
252 257 # sys.stdout has been replaced - use it directly
253 258 return stream
254 259 else:
255 260 stream_b = stream
256 261
257 262 return codecs.getwriter('utf-8')(stream_b)
@@ -1,132 +1,140 b''
1 1
2 2 ===========================
3 3 Custom input transformation
4 4 ===========================
5 5
6 6 IPython extends Python syntax to allow things like magic commands, and help with
7 7 the ``?`` syntax. There are several ways to customise how the user's input is
8 8 processed into Python code to be executed.
9 9
10 10 These hooks are mainly for other projects using IPython as the core of their
11 11 interactive interface. Using them carelessly can easily break IPython!
12 12
13 13 String based transformations
14 14 ============================
15 15
16 16 .. currentmodule:: IPython.core.inputtransforms
17 17
18 18 When the user enters a line of code, it is first processed as a string. By the
19 19 end of this stage, it must be valid Python syntax.
20 20
21 21 These transformers all subclass :class:`IPython.core.inputtransformer.InputTransformer`,
22 22 and are used by :class:`IPython.core.inputsplitter.IPythonInputSplitter`.
23 23
24 24 These transformers act in three groups, stored separately as lists of instances
25 25 in attributes of :class:`~IPython.core.inputsplitter.IPythonInputSplitter`:
26 26
27 27 * ``physical_line_transforms`` act on the lines as the user enters them. For
28 28 example, these strip Python prompts from examples pasted in.
29 29 * ``logical_line_transforms`` act on lines as connected by explicit line
30 30 continuations, i.e. ``\`` at the end of physical lines. They are skipped
31 31 inside multiline Python statements. This is the point where IPython recognises
32 32 ``%magic`` commands, for instance.
33 33 * ``python_line_transforms`` act on blocks containing complete Python statements.
34 34 Multi-line strings, lists and function calls are reassembled before being
35 35 passed to these, but note that function and class *definitions* are still a
36 36 series of separate statements. IPython does not use any of these by default.
37 37
38 38 An InteractiveShell instance actually has two
39 39 :class:`~IPython.core.inputsplitter.IPythonInputSplitter` instances, as the
40 40 attributes :attr:`~IPython.core.interactiveshell.InteractiveShell.input_splitter`,
41 41 to tell when a block of input is complete, and
42 42 :attr:`~IPython.core.interactiveshell.InteractiveShell.input_transformer_manager`,
43 43 to transform complete cells. If you add a transformer, you should make sure that
44 44 it gets added to both, e.g.::
45 45
46 46 ip.input_splitter.logical_line_transforms.append(my_transformer())
47 47 ip.input_transformer_manager.logical_line_transforms.append(my_transformer())
48 48
49 These transformers may raise :exc:`SyntaxError` if the input code is invalid, but
50 in most cases it is clearer to pass unrecognised code through unmodified and let
51 Python's own parser decide whether it is valid.
52
53 .. versionchanged:: 2.0
54
55 Added the option to raise :exc:`SyntaxError`.
56
49 57 Stateless transformations
50 58 -------------------------
51 59
52 60 The simplest kind of transformations work one line at a time. Write a function
53 61 which takes a line and returns a line, and decorate it with
54 62 :meth:`StatelessInputTransformer.wrap`::
55 63
56 64 @StatelessInputTransformer.wrap
57 65 def my_special_commands(line):
58 66 if line.startswith("Β¬"):
59 67 return "specialcommand(" + repr(line) + ")"
60 68 return line
61 69
62 70 The decorator returns a factory function which will produce instances of
63 71 :class:`~IPython.core.inputtransformer.StatelessInputTransformer` using your
64 72 function.
65 73
66 74 Coroutine transformers
67 75 ----------------------
68 76
69 77 More advanced transformers can be written as coroutines. The coroutine will be
70 78 sent each line in turn, followed by ``None`` to reset it. It can yield lines, or
71 79 ``None`` if it is accumulating text to yield at a later point. When reset, it
72 80 should give up any code it has accumulated.
73 81
74 82 This code in IPython strips a constant amount of leading indentation from each
75 83 line in a cell::
76 84
77 85 @CoroutineInputTransformer.wrap
78 86 def leading_indent():
79 87 """Remove leading indentation.
80 88
81 89 If the first line starts with a spaces or tabs, the same whitespace will be
82 90 removed from each following line until it is reset.
83 91 """
84 92 space_re = re.compile(r'^[ \t]+')
85 93 line = ''
86 94 while True:
87 95 line = (yield line)
88 96
89 97 if line is None:
90 98 continue
91 99
92 100 m = space_re.match(line)
93 101 if m:
94 102 space = m.group(0)
95 103 while line is not None:
96 104 if line.startswith(space):
97 105 line = line[len(space):]
98 106 line = (yield line)
99 107 else:
100 108 # No leading spaces - wait for reset
101 109 while line is not None:
102 110 line = (yield line)
103 111
104 112 leading_indent.look_in_string = True
105 113
106 114 Token-based transformers
107 115 ------------------------
108 116
109 117 There is an experimental framework that takes care of tokenizing and
110 118 untokenizing lines of code. Define a function that accepts a list of tokens, and
111 119 returns an iterable of output tokens, and decorate it with
112 120 :meth:`TokenInputTransformer.wrap`. These should only be used in
113 121 ``python_line_transforms``.
114 122
115 123 AST transformations
116 124 ===================
117 125
118 126 After the code has been parsed as Python syntax, you can use Python's powerful
119 127 *Abstract Syntax Tree* tools to modify it. Subclass :class:`ast.NodeTransformer`,
120 128 and add an instance to ``shell.ast_transformers``.
121 129
122 130 This example wraps integer literals in an ``Integer`` class, which is useful for
123 131 mathematical frameworks that want to handle e.g. ``1/3`` as a precise fraction::
124 132
125 133
126 134 class IntegerWrapper(ast.NodeTransformer):
127 135 """Wraps all integers in a call to Integer()"""
128 136 def visit_Num(self, node):
129 137 if isinstance(node.n, int):
130 138 return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()),
131 139 args=[node], keywords=[])
132 140 return node
General Comments 0
You need to be logged in to leave comments. Login now