##// END OF EJS Templates
Merge pull request #10134 from srinivasreddy/rm_PY3...
Thomas Kluyver -
r23128:3a5799a9 merge
parent child Browse files
Show More
@@ -1,1229 +1,1227 b''
1 1 # encoding: utf-8
2 2 """Word completion for IPython.
3 3
4 4 This module started as fork of the rlcompleter module in the Python standard
5 5 library. The original enhancements made to rlcompleter have been sent
6 6 upstream and were accepted as of Python 2.3,
7 7
8 8 """
9 9
10 10 # Copyright (c) IPython Development Team.
11 11 # Distributed under the terms of the Modified BSD License.
12 12 #
13 13 # Some of this code originated from rlcompleter in the Python standard library
14 14 # Copyright (C) 2001 Python Software Foundation, www.python.org
15 15
16 16
17 17 import __main__
18 18 import glob
19 19 import inspect
20 20 import itertools
21 21 import keyword
22 22 import os
23 23 import re
24 24 import sys
25 25 import unicodedata
26 26 import string
27 27 import warnings
28 28 from importlib import import_module
29 29
30 30 from traitlets.config.configurable import Configurable
31 31 from IPython.core.error import TryNext
32 32 from IPython.core.inputsplitter import ESC_MAGIC
33 33 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
34 34 from IPython.utils import generics
35 35 from IPython.utils.decorators import undoc
36 36 from IPython.utils.dir2 import dir2, get_real_method
37 37 from IPython.utils.process import arg_split
38 from IPython.utils.py3compat import builtin_mod, PY3, cast_unicode_py2
38 from IPython.utils.py3compat import builtin_mod, cast_unicode_py2
39 39 from traitlets import Bool, Enum, observe
40 40
41 41 from functools import wraps
42 42
43 43 #-----------------------------------------------------------------------------
44 44 # Globals
45 45 #-----------------------------------------------------------------------------
46 46
47 47 # Public API
48 48 __all__ = ['Completer','IPCompleter']
49 49
50 50 if sys.platform == 'win32':
51 51 PROTECTABLES = ' '
52 52 else:
53 53 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
54 54
55 55
56 56 #-----------------------------------------------------------------------------
57 57 # Work around BUG decorators.
58 58 #-----------------------------------------------------------------------------
59 59
60 60 def _strip_single_trailing_space(complete):
61 61 """
62 62 This is a workaround for a weird IPython/Prompt_toolkit behavior,
63 63 that can be removed once we rely on a slightly more recent prompt_toolkit
64 64 version (likely > 1.0.3). So this can likely be removed in IPython 6.0
65 65
66 66 cf https://github.com/ipython/ipython/issues/9658
67 67 and https://github.com/jonathanslenders/python-prompt-toolkit/pull/328
68 68
69 69 The bug is due to the fact that in PTK the completer will reinvoke itself
70 70 after trying to completer to the longuest common prefix of all the
71 71 completions, unless only one completion is available.
72 72
73 73 This logic is faulty if the completion ends with space, which can happen in
74 74 case like::
75 75
76 76 from foo import im<ta>
77 77
78 78 which only matching completion is `import `. Note the leading space at the
79 79 end. So leaving a space at the end is a reasonable request, but for now
80 80 we'll strip it.
81 81 """
82 82
83 83 @wraps(complete)
84 84 def comp(*args, **kwargs):
85 85 text, matches = complete(*args, **kwargs)
86 86 if len(matches) == 1:
87 87 return text, [matches[0].rstrip()]
88 88 return text, matches
89 89
90 90 return comp
91 91
92 92
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Main functions and classes
96 96 #-----------------------------------------------------------------------------
97 97
98 98 def has_open_quotes(s):
99 99 """Return whether a string has open quotes.
100 100
101 101 This simply counts whether the number of quote characters of either type in
102 102 the string is odd.
103 103
104 104 Returns
105 105 -------
106 106 If there is an open quote, the quote character is returned. Else, return
107 107 False.
108 108 """
109 109 # We check " first, then ', so complex cases with nested quotes will get
110 110 # the " to take precedence.
111 111 if s.count('"') % 2:
112 112 return '"'
113 113 elif s.count("'") % 2:
114 114 return "'"
115 115 else:
116 116 return False
117 117
118 118
119 119 def protect_filename(s):
120 120 """Escape a string to protect certain characters."""
121 121 if set(s) & set(PROTECTABLES):
122 122 if sys.platform == "win32":
123 123 return '"' + s + '"'
124 124 else:
125 125 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
126 126 else:
127 127 return s
128 128
129 129
130 130 def expand_user(path):
131 131 """Expand '~'-style usernames in strings.
132 132
133 133 This is similar to :func:`os.path.expanduser`, but it computes and returns
134 134 extra information that will be useful if the input was being used in
135 135 computing completions, and you wish to return the completions with the
136 136 original '~' instead of its expanded value.
137 137
138 138 Parameters
139 139 ----------
140 140 path : str
141 141 String to be expanded. If no ~ is present, the output is the same as the
142 142 input.
143 143
144 144 Returns
145 145 -------
146 146 newpath : str
147 147 Result of ~ expansion in the input path.
148 148 tilde_expand : bool
149 149 Whether any expansion was performed or not.
150 150 tilde_val : str
151 151 The value that ~ was replaced with.
152 152 """
153 153 # Default values
154 154 tilde_expand = False
155 155 tilde_val = ''
156 156 newpath = path
157 157
158 158 if path.startswith('~'):
159 159 tilde_expand = True
160 160 rest = len(path)-1
161 161 newpath = os.path.expanduser(path)
162 162 if rest:
163 163 tilde_val = newpath[:-rest]
164 164 else:
165 165 tilde_val = newpath
166 166
167 167 return newpath, tilde_expand, tilde_val
168 168
169 169
170 170 def compress_user(path, tilde_expand, tilde_val):
171 171 """Does the opposite of expand_user, with its outputs.
172 172 """
173 173 if tilde_expand:
174 174 return path.replace(tilde_val, '~')
175 175 else:
176 176 return path
177 177
178 178
179 179 def completions_sorting_key(word):
180 180 """key for sorting completions
181 181
182 182 This does several things:
183 183
184 184 - Lowercase all completions, so they are sorted alphabetically with
185 185 upper and lower case words mingled
186 186 - Demote any completions starting with underscores to the end
187 187 - Insert any %magic and %%cellmagic completions in the alphabetical order
188 188 by their name
189 189 """
190 190 # Case insensitive sort
191 191 word = word.lower()
192 192
193 193 prio1, prio2 = 0, 0
194 194
195 195 if word.startswith('__'):
196 196 prio1 = 2
197 197 elif word.startswith('_'):
198 198 prio1 = 1
199 199
200 200 if word.endswith('='):
201 201 prio1 = -1
202 202
203 203 if word.startswith('%%'):
204 204 # If there's another % in there, this is something else, so leave it alone
205 205 if not "%" in word[2:]:
206 206 word = word[2:]
207 207 prio2 = 2
208 208 elif word.startswith('%'):
209 209 if not "%" in word[1:]:
210 210 word = word[1:]
211 211 prio2 = 1
212 212
213 213 return prio1, word, prio2
214 214
215 215
216 216 @undoc
217 217 class Bunch(object): pass
218 218
219 219
220 220 if sys.platform == 'win32':
221 221 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
222 222 else:
223 223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
224 224
225 225 GREEDY_DELIMS = ' =\r\n'
226 226
227 227
228 228 class CompletionSplitter(object):
229 229 """An object to split an input line in a manner similar to readline.
230 230
231 231 By having our own implementation, we can expose readline-like completion in
232 232 a uniform manner to all frontends. This object only needs to be given the
233 233 line of text to be split and the cursor position on said line, and it
234 234 returns the 'word' to be completed on at the cursor after splitting the
235 235 entire line.
236 236
237 237 What characters are used as splitting delimiters can be controlled by
238 238 setting the `delims` attribute (this is a property that internally
239 239 automatically builds the necessary regular expression)"""
240 240
241 241 # Private interface
242 242
243 243 # A string of delimiter characters. The default value makes sense for
244 244 # IPython's most typical usage patterns.
245 245 _delims = DELIMS
246 246
247 247 # The expression (a normal string) to be compiled into a regular expression
248 248 # for actual splitting. We store it as an attribute mostly for ease of
249 249 # debugging, since this type of code can be so tricky to debug.
250 250 _delim_expr = None
251 251
252 252 # The regular expression that does the actual splitting
253 253 _delim_re = None
254 254
255 255 def __init__(self, delims=None):
256 256 delims = CompletionSplitter._delims if delims is None else delims
257 257 self.delims = delims
258 258
259 259 @property
260 260 def delims(self):
261 261 """Return the string of delimiter characters."""
262 262 return self._delims
263 263
264 264 @delims.setter
265 265 def delims(self, delims):
266 266 """Set the delimiters for line splitting."""
267 267 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
268 268 self._delim_re = re.compile(expr)
269 269 self._delims = delims
270 270 self._delim_expr = expr
271 271
272 272 def split_line(self, line, cursor_pos=None):
273 273 """Split a line of text with a cursor at the given position.
274 274 """
275 275 l = line if cursor_pos is None else line[:cursor_pos]
276 276 return self._delim_re.split(l)[-1]
277 277
278 278
279 279 class Completer(Configurable):
280 280
281 281 greedy = Bool(False,
282 282 help="""Activate greedy completion
283 283 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
284 284
285 285 This will enable completion on elements of lists, results of function calls, etc.,
286 286 but can be unsafe because the code is actually evaluated on TAB.
287 287 """
288 288 ).tag(config=True)
289 289
290 290
291 291 def __init__(self, namespace=None, global_namespace=None, **kwargs):
292 292 """Create a new completer for the command line.
293 293
294 294 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
295 295
296 296 If unspecified, the default namespace where completions are performed
297 297 is __main__ (technically, __main__.__dict__). Namespaces should be
298 298 given as dictionaries.
299 299
300 300 An optional second namespace can be given. This allows the completer
301 301 to handle cases where both the local and global scopes need to be
302 302 distinguished.
303 303
304 304 Completer instances should be used as the completion mechanism of
305 305 readline via the set_completer() call:
306 306
307 307 readline.set_completer(Completer(my_namespace).complete)
308 308 """
309 309
310 310 # Don't bind to namespace quite yet, but flag whether the user wants a
311 311 # specific namespace or to use __main__.__dict__. This will allow us
312 312 # to bind to __main__.__dict__ at completion time, not now.
313 313 if namespace is None:
314 314 self.use_main_ns = 1
315 315 else:
316 316 self.use_main_ns = 0
317 317 self.namespace = namespace
318 318
319 319 # The global namespace, if given, can be bound directly
320 320 if global_namespace is None:
321 321 self.global_namespace = {}
322 322 else:
323 323 self.global_namespace = global_namespace
324 324
325 325 super(Completer, self).__init__(**kwargs)
326 326
327 327 def complete(self, text, state):
328 328 """Return the next possible completion for 'text'.
329 329
330 330 This is called successively with state == 0, 1, 2, ... until it
331 331 returns None. The completion should begin with 'text'.
332 332
333 333 """
334 334 if self.use_main_ns:
335 335 self.namespace = __main__.__dict__
336 336
337 337 if state == 0:
338 338 if "." in text:
339 339 self.matches = self.attr_matches(text)
340 340 else:
341 341 self.matches = self.global_matches(text)
342 342 try:
343 343 return self.matches[state]
344 344 except IndexError:
345 345 return None
346 346
347 347 def global_matches(self, text):
348 348 """Compute matches when text is a simple name.
349 349
350 350 Return a list of all keywords, built-in functions and names currently
351 351 defined in self.namespace or self.global_namespace that match.
352 352
353 353 """
354 354 matches = []
355 355 match_append = matches.append
356 356 n = len(text)
357 357 for lst in [keyword.kwlist,
358 358 builtin_mod.__dict__.keys(),
359 359 self.namespace.keys(),
360 360 self.global_namespace.keys()]:
361 361 for word in lst:
362 362 if word[:n] == text and word != "__builtins__":
363 363 match_append(word)
364 364 return [cast_unicode_py2(m) for m in matches]
365 365
366 366 def attr_matches(self, text):
367 367 """Compute matches when text contains a dot.
368 368
369 369 Assuming the text is of the form NAME.NAME....[NAME], and is
370 370 evaluatable in self.namespace or self.global_namespace, it will be
371 371 evaluated and its attributes (as revealed by dir()) are used as
372 372 possible completions. (For class instances, class members are are
373 373 also considered.)
374 374
375 375 WARNING: this can still invoke arbitrary C code, if an object
376 376 with a __getattr__ hook is evaluated.
377 377
378 378 """
379 379
380 380 # Another option, seems to work great. Catches things like ''.<tab>
381 381 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
382 382
383 383 if m:
384 384 expr, attr = m.group(1, 3)
385 385 elif self.greedy:
386 386 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
387 387 if not m2:
388 388 return []
389 389 expr, attr = m2.group(1,2)
390 390 else:
391 391 return []
392 392
393 393 try:
394 394 obj = eval(expr, self.namespace)
395 395 except:
396 396 try:
397 397 obj = eval(expr, self.global_namespace)
398 398 except:
399 399 return []
400 400
401 401 if self.limit_to__all__ and hasattr(obj, '__all__'):
402 402 words = get__all__entries(obj)
403 403 else:
404 404 words = dir2(obj)
405 405
406 406 try:
407 407 words = generics.complete_object(obj, words)
408 408 except TryNext:
409 409 pass
410 410 except Exception:
411 411 # Silence errors from completion function
412 412 #raise # dbg
413 413 pass
414 414 # Build match list to return
415 415 n = len(attr)
416 416 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
417 417
418 418
419 419 def get__all__entries(obj):
420 420 """returns the strings in the __all__ attribute"""
421 421 try:
422 422 words = getattr(obj, '__all__')
423 423 except:
424 424 return []
425 425
426 426 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
427 427
428 428
429 429 def match_dict_keys(keys, prefix, delims):
430 430 """Used by dict_key_matches, matching the prefix to a list of keys"""
431 431 if not prefix:
432 432 return None, 0, [repr(k) for k in keys
433 433 if isinstance(k, (str, bytes))]
434 434 quote_match = re.search('["\']', prefix)
435 435 quote = quote_match.group()
436 436 try:
437 437 prefix_str = eval(prefix + quote, {})
438 438 except Exception:
439 439 return None, 0, []
440 440
441 441 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
442 442 token_match = re.search(pattern, prefix, re.UNICODE)
443 443 token_start = token_match.start()
444 444 token_prefix = token_match.group()
445 445
446 446 # TODO: support bytes in Py3k
447 447 matched = []
448 448 for key in keys:
449 449 try:
450 450 if not key.startswith(prefix_str):
451 451 continue
452 452 except (AttributeError, TypeError, UnicodeError):
453 453 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
454 454 continue
455 455
456 456 # reformat remainder of key to begin with prefix
457 457 rem = key[len(prefix_str):]
458 458 # force repr wrapped in '
459 459 rem_repr = repr(rem + '"')
460 460 if rem_repr.startswith('u') and prefix[0] not in 'uU':
461 461 # Found key is unicode, but prefix is Py2 string.
462 462 # Therefore attempt to interpret key as string.
463 463 try:
464 464 rem_repr = repr(rem.encode('ascii') + '"')
465 465 except UnicodeEncodeError:
466 466 continue
467 467
468 468 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
469 469 if quote == '"':
470 470 # The entered prefix is quoted with ",
471 471 # but the match is quoted with '.
472 472 # A contained " hence needs escaping for comparison:
473 473 rem_repr = rem_repr.replace('"', '\\"')
474 474
475 475 # then reinsert prefix from start of token
476 476 matched.append('%s%s' % (token_prefix, rem_repr))
477 477 return quote, token_start, matched
478 478
479 479
480 480 def _safe_isinstance(obj, module, class_name):
481 481 """Checks if obj is an instance of module.class_name if loaded
482 482 """
483 483 return (module in sys.modules and
484 484 isinstance(obj, getattr(import_module(module), class_name)))
485 485
486 486
487 487 def back_unicode_name_matches(text):
488 488 u"""Match unicode characters back to unicode name
489 489
490 490 This does β˜ƒ -> \\snowman
491 491
492 492 Note that snowman is not a valid python3 combining character but will be expanded.
493 493 Though it will not recombine back to the snowman character by the completion machinery.
494 494
495 495 This will not either back-complete standard sequences like \\n, \\b ...
496 496
497 497 Used on Python 3 only.
498 498 """
499 499 if len(text)<2:
500 500 return u'', ()
501 501 maybe_slash = text[-2]
502 502 if maybe_slash != '\\':
503 503 return u'', ()
504 504
505 505 char = text[-1]
506 506 # no expand on quote for completion in strings.
507 507 # nor backcomplete standard ascii keys
508 508 if char in string.ascii_letters or char in ['"',"'"]:
509 509 return u'', ()
510 510 try :
511 511 unic = unicodedata.name(char)
512 512 return '\\'+char,['\\'+unic]
513 513 except KeyError:
514 514 pass
515 515 return u'', ()
516 516
517 517 def back_latex_name_matches(text):
518 518 u"""Match latex characters back to unicode name
519 519
520 520 This does ->\\sqrt
521 521
522 522 Used on Python 3 only.
523 523 """
524 524 if len(text)<2:
525 525 return u'', ()
526 526 maybe_slash = text[-2]
527 527 if maybe_slash != '\\':
528 528 return u'', ()
529 529
530 530
531 531 char = text[-1]
532 532 # no expand on quote for completion in strings.
533 533 # nor backcomplete standard ascii keys
534 534 if char in string.ascii_letters or char in ['"',"'"]:
535 535 return u'', ()
536 536 try :
537 537 latex = reverse_latex_symbol[char]
538 538 # '\\' replace the \ as well
539 539 return '\\'+char,[latex]
540 540 except KeyError:
541 541 pass
542 542 return u'', ()
543 543
544 544
545 545 class IPCompleter(Completer):
546 546 """Extension of the completer class with IPython-specific features"""
547 547
548 548 @observe('greedy')
549 549 def _greedy_changed(self, change):
550 550 """update the splitter and readline delims when greedy is changed"""
551 551 if change['new']:
552 552 self.splitter.delims = GREEDY_DELIMS
553 553 else:
554 554 self.splitter.delims = DELIMS
555 555
556 556 merge_completions = Bool(True,
557 557 help="""Whether to merge completion results into a single list
558 558
559 559 If False, only the completion results from the first non-empty
560 560 completer will be returned.
561 561 """
562 562 ).tag(config=True)
563 563 omit__names = Enum((0,1,2), default_value=2,
564 564 help="""Instruct the completer to omit private method names
565 565
566 566 Specifically, when completing on ``object.<tab>``.
567 567
568 568 When 2 [default]: all names that start with '_' will be excluded.
569 569
570 570 When 1: all 'magic' names (``__foo__``) will be excluded.
571 571
572 572 When 0: nothing will be excluded.
573 573 """
574 574 ).tag(config=True)
575 575 limit_to__all__ = Bool(False,
576 576 help="""
577 577 DEPRECATED as of version 5.0.
578 578
579 579 Instruct the completer to use __all__ for the completion
580 580
581 581 Specifically, when completing on ``object.<tab>``.
582 582
583 583 When True: only those names in obj.__all__ will be included.
584 584
585 585 When False [default]: the __all__ attribute is ignored
586 586 """,
587 587 ).tag(config=True)
588 588
589 589 def __init__(self, shell=None, namespace=None, global_namespace=None,
590 590 use_readline=False, config=None, **kwargs):
591 591 """IPCompleter() -> completer
592 592
593 593 Return a completer object suitable for use by the readline library
594 594 via readline.set_completer().
595 595
596 596 Inputs:
597 597
598 598 - shell: a pointer to the ipython shell itself. This is needed
599 599 because this completer knows about magic functions, and those can
600 600 only be accessed via the ipython instance.
601 601
602 602 - namespace: an optional dict where completions are performed.
603 603
604 604 - global_namespace: secondary optional dict for completions, to
605 605 handle cases (such as IPython embedded inside functions) where
606 606 both Python scopes are visible.
607 607
608 608 use_readline : bool, optional
609 609 DEPRECATED, ignored.
610 610 """
611 611
612 612 self.magic_escape = ESC_MAGIC
613 613 self.splitter = CompletionSplitter()
614 614
615 615 if use_readline:
616 616 warnings.warn('The use_readline parameter is deprecated and ignored since IPython 6.0.',
617 617 DeprecationWarning, stacklevel=2)
618 618
619 619 # _greedy_changed() depends on splitter and readline being defined:
620 620 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
621 621 config=config, **kwargs)
622 622
623 623 # List where completion matches will be stored
624 624 self.matches = []
625 625 self.shell = shell
626 626 # Regexp to split filenames with spaces in them
627 627 self.space_name_re = re.compile(r'([^\\] )')
628 628 # Hold a local ref. to glob.glob for speed
629 629 self.glob = glob.glob
630 630
631 631 # Determine if we are running on 'dumb' terminals, like (X)Emacs
632 632 # buffers, to avoid completion problems.
633 633 term = os.environ.get('TERM','xterm')
634 634 self.dumb_terminal = term in ['dumb','emacs']
635 635
636 636 # Special handling of backslashes needed in win32 platforms
637 637 if sys.platform == "win32":
638 638 self.clean_glob = self._clean_glob_win32
639 639 else:
640 640 self.clean_glob = self._clean_glob
641 641
642 642 #regexp to parse docstring for function signature
643 643 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
644 644 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
645 645 #use this if positional argument name is also needed
646 646 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
647 647
648 648 # All active matcher routines for completion
649 649 self.matchers = [
650 650 self.python_matches,
651 651 self.file_matches,
652 652 self.magic_matches,
653 653 self.python_func_kw_matches,
654 654 self.dict_key_matches,
655 655 ]
656 656
657 657 # This is set externally by InteractiveShell
658 658 self.custom_completers = None
659 659
660 660 def all_completions(self, text):
661 661 """
662 662 Wrapper around the complete method for the benefit of emacs.
663 663 """
664 664 return self.complete(text)[1]
665 665
666 666 def _clean_glob(self, text):
667 667 return self.glob("%s*" % text)
668 668
669 669 def _clean_glob_win32(self,text):
670 670 return [f.replace("\\","/")
671 671 for f in self.glob("%s*" % text)]
672 672
673 673 def file_matches(self, text):
674 674 """Match filenames, expanding ~USER type strings.
675 675
676 676 Most of the seemingly convoluted logic in this completer is an
677 677 attempt to handle filenames with spaces in them. And yet it's not
678 678 quite perfect, because Python's readline doesn't expose all of the
679 679 GNU readline details needed for this to be done correctly.
680 680
681 681 For a filename with a space in it, the printed completions will be
682 682 only the parts after what's already been typed (instead of the
683 683 full completions, as is normally done). I don't think with the
684 684 current (as of Python 2.3) Python readline it's possible to do
685 685 better."""
686 686
687 687 # chars that require escaping with backslash - i.e. chars
688 688 # that readline treats incorrectly as delimiters, but we
689 689 # don't want to treat as delimiters in filename matching
690 690 # when escaped with backslash
691 691 if text.startswith('!'):
692 692 text = text[1:]
693 693 text_prefix = u'!'
694 694 else:
695 695 text_prefix = u''
696 696
697 697 text_until_cursor = self.text_until_cursor
698 698 # track strings with open quotes
699 699 open_quotes = has_open_quotes(text_until_cursor)
700 700
701 701 if '(' in text_until_cursor or '[' in text_until_cursor:
702 702 lsplit = text
703 703 else:
704 704 try:
705 705 # arg_split ~ shlex.split, but with unicode bugs fixed by us
706 706 lsplit = arg_split(text_until_cursor)[-1]
707 707 except ValueError:
708 708 # typically an unmatched ", or backslash without escaped char.
709 709 if open_quotes:
710 710 lsplit = text_until_cursor.split(open_quotes)[-1]
711 711 else:
712 712 return []
713 713 except IndexError:
714 714 # tab pressed on empty line
715 715 lsplit = ""
716 716
717 717 if not open_quotes and lsplit != protect_filename(lsplit):
718 718 # if protectables are found, do matching on the whole escaped name
719 719 has_protectables = True
720 720 text0,text = text,lsplit
721 721 else:
722 722 has_protectables = False
723 723 text = os.path.expanduser(text)
724 724
725 725 if text == "":
726 726 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
727 727
728 728 # Compute the matches from the filesystem
729 729 if sys.platform == 'win32':
730 730 m0 = self.clean_glob(text)
731 731 else:
732 732 m0 = self.clean_glob(text.replace('\\', ''))
733 733
734 734 if has_protectables:
735 735 # If we had protectables, we need to revert our changes to the
736 736 # beginning of filename so that we don't double-write the part
737 737 # of the filename we have so far
738 738 len_lsplit = len(lsplit)
739 739 matches = [text_prefix + text0 +
740 740 protect_filename(f[len_lsplit:]) for f in m0]
741 741 else:
742 742 if open_quotes:
743 743 # if we have a string with an open quote, we don't need to
744 744 # protect the names at all (and we _shouldn't_, as it
745 745 # would cause bugs when the filesystem call is made).
746 746 matches = m0
747 747 else:
748 748 matches = [text_prefix +
749 749 protect_filename(f) for f in m0]
750 750
751 751 # Mark directories in input list by appending '/' to their names.
752 752 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
753 753
754 754 def magic_matches(self, text):
755 755 """Match magics"""
756 756 # Get all shell magics now rather than statically, so magics loaded at
757 757 # runtime show up too.
758 758 lsm = self.shell.magics_manager.lsmagic()
759 759 line_magics = lsm['line']
760 760 cell_magics = lsm['cell']
761 761 pre = self.magic_escape
762 762 pre2 = pre+pre
763 763
764 764 # Completion logic:
765 765 # - user gives %%: only do cell magics
766 766 # - user gives %: do both line and cell magics
767 767 # - no prefix: do both
768 768 # In other words, line magics are skipped if the user gives %% explicitly
769 769 bare_text = text.lstrip(pre)
770 770 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
771 771 if not text.startswith(pre2):
772 772 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
773 773 return [cast_unicode_py2(c) for c in comp]
774 774
775 775
776 776 def python_matches(self, text):
777 777 """Match attributes or global python names"""
778 778 if "." in text:
779 779 try:
780 780 matches = self.attr_matches(text)
781 781 if text.endswith('.') and self.omit__names:
782 782 if self.omit__names == 1:
783 783 # true if txt is _not_ a __ name, false otherwise:
784 784 no__name = (lambda txt:
785 785 re.match(r'.*\.__.*?__',txt) is None)
786 786 else:
787 787 # true if txt is _not_ a _ name, false otherwise:
788 788 no__name = (lambda txt:
789 789 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
790 790 matches = filter(no__name, matches)
791 791 except NameError:
792 792 # catches <undefined attributes>.<tab>
793 793 matches = []
794 794 else:
795 795 matches = self.global_matches(text)
796 796 return matches
797 797
798 798 def _default_arguments_from_docstring(self, doc):
799 799 """Parse the first line of docstring for call signature.
800 800
801 801 Docstring should be of the form 'min(iterable[, key=func])\n'.
802 802 It can also parse cython docstring of the form
803 803 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
804 804 """
805 805 if doc is None:
806 806 return []
807 807
808 808 #care only the firstline
809 809 line = doc.lstrip().splitlines()[0]
810 810
811 811 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
812 812 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
813 813 sig = self.docstring_sig_re.search(line)
814 814 if sig is None:
815 815 return []
816 816 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
817 817 sig = sig.groups()[0].split(',')
818 818 ret = []
819 819 for s in sig:
820 820 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
821 821 ret += self.docstring_kwd_re.findall(s)
822 822 return ret
823 823
824 824 def _default_arguments(self, obj):
825 825 """Return the list of default arguments of obj if it is callable,
826 826 or empty list otherwise."""
827 827 call_obj = obj
828 828 ret = []
829 829 if inspect.isbuiltin(obj):
830 830 pass
831 831 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
832 832 if inspect.isclass(obj):
833 833 #for cython embededsignature=True the constructor docstring
834 834 #belongs to the object itself not __init__
835 835 ret += self._default_arguments_from_docstring(
836 836 getattr(obj, '__doc__', ''))
837 837 # for classes, check for __init__,__new__
838 838 call_obj = (getattr(obj, '__init__', None) or
839 839 getattr(obj, '__new__', None))
840 840 # for all others, check if they are __call__able
841 841 elif hasattr(obj, '__call__'):
842 842 call_obj = obj.__call__
843 843 ret += self._default_arguments_from_docstring(
844 844 getattr(call_obj, '__doc__', ''))
845 845
846 846 _keeps = (inspect.Parameter.KEYWORD_ONLY,
847 847 inspect.Parameter.POSITIONAL_OR_KEYWORD)
848 848
849 849 try:
850 850 sig = inspect.signature(call_obj)
851 851 ret.extend(k for k, v in sig.parameters.items() if
852 852 v.kind in _keeps)
853 853 except ValueError:
854 854 pass
855 855
856 856 return list(set(ret))
857 857
858 858 def python_func_kw_matches(self,text):
859 859 """Match named parameters (kwargs) of the last open function"""
860 860
861 861 if "." in text: # a parameter cannot be dotted
862 862 return []
863 863 try: regexp = self.__funcParamsRegex
864 864 except AttributeError:
865 865 regexp = self.__funcParamsRegex = re.compile(r'''
866 866 '.*?(?<!\\)' | # single quoted strings or
867 867 ".*?(?<!\\)" | # double quoted strings or
868 868 \w+ | # identifier
869 869 \S # other characters
870 870 ''', re.VERBOSE | re.DOTALL)
871 871 # 1. find the nearest identifier that comes before an unclosed
872 872 # parenthesis before the cursor
873 873 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
874 874 tokens = regexp.findall(self.text_until_cursor)
875 875 iterTokens = reversed(tokens); openPar = 0
876 876
877 877 for token in iterTokens:
878 878 if token == ')':
879 879 openPar -= 1
880 880 elif token == '(':
881 881 openPar += 1
882 882 if openPar > 0:
883 883 # found the last unclosed parenthesis
884 884 break
885 885 else:
886 886 return []
887 887 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
888 888 ids = []
889 889 isId = re.compile(r'\w+$').match
890 890
891 891 while True:
892 892 try:
893 893 ids.append(next(iterTokens))
894 894 if not isId(ids[-1]):
895 895 ids.pop(); break
896 896 if not next(iterTokens) == '.':
897 897 break
898 898 except StopIteration:
899 899 break
900 900
901 901 # Find all named arguments already assigned to, as to avoid suggesting
902 902 # them again
903 903 usedNamedArgs = set()
904 904 par_level = -1
905 905 for token, next_token in zip(tokens, tokens[1:]):
906 906 if token == '(':
907 907 par_level += 1
908 908 elif token == ')':
909 909 par_level -= 1
910 910
911 911 if par_level != 0:
912 912 continue
913 913
914 914 if next_token != '=':
915 915 continue
916 916
917 917 usedNamedArgs.add(token)
918 918
919 919 # lookup the candidate callable matches either using global_matches
920 920 # or attr_matches for dotted names
921 921 if len(ids) == 1:
922 922 callableMatches = self.global_matches(ids[0])
923 923 else:
924 924 callableMatches = self.attr_matches('.'.join(ids[::-1]))
925 925 argMatches = []
926 926 for callableMatch in callableMatches:
927 927 try:
928 928 namedArgs = self._default_arguments(eval(callableMatch,
929 929 self.namespace))
930 930 except:
931 931 continue
932 932
933 933 # Remove used named arguments from the list, no need to show twice
934 934 for namedArg in set(namedArgs) - usedNamedArgs:
935 935 if namedArg.startswith(text):
936 936 argMatches.append(u"%s=" %namedArg)
937 937 return argMatches
938 938
939 939 def dict_key_matches(self, text):
940 940 "Match string keys in a dictionary, after e.g. 'foo[' "
941 941 def get_keys(obj):
942 942 # Objects can define their own completions by defining an
943 943 # _ipy_key_completions_() method.
944 944 method = get_real_method(obj, '_ipython_key_completions_')
945 945 if method is not None:
946 946 return method()
947 947
948 948 # Special case some common in-memory dict-like types
949 949 if isinstance(obj, dict) or\
950 950 _safe_isinstance(obj, 'pandas', 'DataFrame'):
951 951 try:
952 952 return list(obj.keys())
953 953 except Exception:
954 954 return []
955 955 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
956 956 _safe_isinstance(obj, 'numpy', 'void'):
957 957 return obj.dtype.names or []
958 958 return []
959 959
960 960 try:
961 961 regexps = self.__dict_key_regexps
962 962 except AttributeError:
963 963 dict_key_re_fmt = r'''(?x)
964 964 ( # match dict-referring expression wrt greedy setting
965 965 %s
966 966 )
967 967 \[ # open bracket
968 968 \s* # and optional whitespace
969 969 ([uUbB]? # string prefix (r not handled)
970 970 (?: # unclosed string
971 971 '(?:[^']|(?<!\\)\\')*
972 972 |
973 973 "(?:[^"]|(?<!\\)\\")*
974 974 )
975 975 )?
976 976 $
977 977 '''
978 978 regexps = self.__dict_key_regexps = {
979 979 False: re.compile(dict_key_re_fmt % '''
980 980 # identifiers separated by .
981 981 (?!\d)\w+
982 982 (?:\.(?!\d)\w+)*
983 983 '''),
984 984 True: re.compile(dict_key_re_fmt % '''
985 985 .+
986 986 ''')
987 987 }
988 988
989 989 match = regexps[self.greedy].search(self.text_until_cursor)
990 990 if match is None:
991 991 return []
992 992
993 993 expr, prefix = match.groups()
994 994 try:
995 995 obj = eval(expr, self.namespace)
996 996 except Exception:
997 997 try:
998 998 obj = eval(expr, self.global_namespace)
999 999 except Exception:
1000 1000 return []
1001 1001
1002 1002 keys = get_keys(obj)
1003 1003 if not keys:
1004 1004 return keys
1005 1005 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1006 1006 if not matches:
1007 1007 return matches
1008 1008
1009 1009 # get the cursor position of
1010 1010 # - the text being completed
1011 1011 # - the start of the key text
1012 1012 # - the start of the completion
1013 1013 text_start = len(self.text_until_cursor) - len(text)
1014 1014 if prefix:
1015 1015 key_start = match.start(2)
1016 1016 completion_start = key_start + token_offset
1017 1017 else:
1018 1018 key_start = completion_start = match.end()
1019 1019
1020 1020 # grab the leading prefix, to make sure all completions start with `text`
1021 1021 if text_start > key_start:
1022 1022 leading = ''
1023 1023 else:
1024 1024 leading = text[text_start:completion_start]
1025 1025
1026 1026 # the index of the `[` character
1027 1027 bracket_idx = match.end(1)
1028 1028
1029 1029 # append closing quote and bracket as appropriate
1030 1030 # this is *not* appropriate if the opening quote or bracket is outside
1031 1031 # the text given to this method
1032 1032 suf = ''
1033 1033 continuation = self.line_buffer[len(self.text_until_cursor):]
1034 1034 if key_start > text_start and closing_quote:
1035 1035 # quotes were opened inside text, maybe close them
1036 1036 if continuation.startswith(closing_quote):
1037 1037 continuation = continuation[len(closing_quote):]
1038 1038 else:
1039 1039 suf += closing_quote
1040 1040 if bracket_idx > text_start:
1041 1041 # brackets were opened inside text, maybe close them
1042 1042 if not continuation.startswith(']'):
1043 1043 suf += ']'
1044 1044
1045 1045 return [leading + k + suf for k in matches]
1046 1046
1047 1047 def unicode_name_matches(self, text):
1048 1048 u"""Match Latex-like syntax for unicode characters base
1049 1049 on the name of the character.
1050 1050
1051 1051 This does \\GREEK SMALL LETTER ETA -> Ξ·
1052 1052
1053 1053 Works only on valid python 3 identifier, or on combining characters that
1054 1054 will combine to form a valid identifier.
1055 1055
1056 1056 Used on Python 3 only.
1057 1057 """
1058 1058 slashpos = text.rfind('\\')
1059 1059 if slashpos > -1:
1060 1060 s = text[slashpos+1:]
1061 1061 try :
1062 1062 unic = unicodedata.lookup(s)
1063 1063 # allow combining chars
1064 1064 if ('a'+unic).isidentifier():
1065 1065 return '\\'+s,[unic]
1066 1066 except KeyError:
1067 1067 pass
1068 1068 return u'', []
1069 1069
1070 1070
1071 1071
1072 1072
1073 1073 def latex_matches(self, text):
1074 1074 u"""Match Latex syntax for unicode characters.
1075 1075
1076 1076 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1077 1077
1078 1078 Used on Python 3 only.
1079 1079 """
1080 1080 slashpos = text.rfind('\\')
1081 1081 if slashpos > -1:
1082 1082 s = text[slashpos:]
1083 1083 if s in latex_symbols:
1084 1084 # Try to complete a full latex symbol to unicode
1085 1085 # \\alpha -> Ξ±
1086 1086 return s, [latex_symbols[s]]
1087 1087 else:
1088 1088 # If a user has partially typed a latex symbol, give them
1089 1089 # a full list of options \al -> [\aleph, \alpha]
1090 1090 matches = [k for k in latex_symbols if k.startswith(s)]
1091 1091 return s, matches
1092 1092 return u'', []
1093 1093
1094 1094 def dispatch_custom_completer(self, text):
1095 1095 if not self.custom_completers:
1096 1096 return
1097 1097
1098 1098 line = self.line_buffer
1099 1099 if not line.strip():
1100 1100 return None
1101 1101
1102 1102 # Create a little structure to pass all the relevant information about
1103 1103 # the current completion to any custom completer.
1104 1104 event = Bunch()
1105 1105 event.line = line
1106 1106 event.symbol = text
1107 1107 cmd = line.split(None,1)[0]
1108 1108 event.command = cmd
1109 1109 event.text_until_cursor = self.text_until_cursor
1110 1110
1111 1111 # for foo etc, try also to find completer for %foo
1112 1112 if not cmd.startswith(self.magic_escape):
1113 1113 try_magic = self.custom_completers.s_matches(
1114 1114 self.magic_escape + cmd)
1115 1115 else:
1116 1116 try_magic = []
1117 1117
1118 1118 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1119 1119 try_magic,
1120 1120 self.custom_completers.flat_matches(self.text_until_cursor)):
1121 1121 try:
1122 1122 res = c(event)
1123 1123 if res:
1124 1124 # first, try case sensitive match
1125 1125 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1126 1126 if withcase:
1127 1127 return withcase
1128 1128 # if none, then case insensitive ones are ok too
1129 1129 text_low = text.lower()
1130 1130 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1131 1131 except TryNext:
1132 1132 pass
1133 1133
1134 1134 return None
1135 1135
1136 1136 @_strip_single_trailing_space
1137 1137 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1138 1138 """Find completions for the given text and line context.
1139 1139
1140 1140 Note that both the text and the line_buffer are optional, but at least
1141 1141 one of them must be given.
1142 1142
1143 1143 Parameters
1144 1144 ----------
1145 1145 text : string, optional
1146 1146 Text to perform the completion on. If not given, the line buffer
1147 1147 is split using the instance's CompletionSplitter object.
1148 1148
1149 1149 line_buffer : string, optional
1150 1150 If not given, the completer attempts to obtain the current line
1151 1151 buffer via readline. This keyword allows clients which are
1152 1152 requesting for text completions in non-readline contexts to inform
1153 1153 the completer of the entire text.
1154 1154
1155 1155 cursor_pos : int, optional
1156 1156 Index of the cursor in the full line buffer. Should be provided by
1157 1157 remote frontends where kernel has no access to frontend state.
1158 1158
1159 1159 Returns
1160 1160 -------
1161 1161 text : str
1162 1162 Text that was actually used in the completion.
1163 1163
1164 1164 matches : list
1165 1165 A list of completion matches.
1166 1166 """
1167 1167 # if the cursor position isn't given, the only sane assumption we can
1168 1168 # make is that it's at the end of the line (the common case)
1169 1169 if cursor_pos is None:
1170 1170 cursor_pos = len(line_buffer) if text is None else len(text)
1171 1171
1172 1172 if self.use_main_ns:
1173 1173 self.namespace = __main__.__dict__
1174 1174
1175 if PY3:
1176
1177 1175 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1178 1176 latex_text, latex_matches = self.latex_matches(base_text)
1179 1177 if latex_matches:
1180 1178 return latex_text, latex_matches
1181 1179 name_text = ''
1182 1180 name_matches = []
1183 1181 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1184 1182 name_text, name_matches = meth(base_text)
1185 1183 if name_text:
1186 1184 return name_text, name_matches
1187 1185
1188 1186 # if text is either None or an empty string, rely on the line buffer
1189 1187 if not text:
1190 1188 text = self.splitter.split_line(line_buffer, cursor_pos)
1191 1189
1192 1190 # If no line buffer is given, assume the input text is all there was
1193 1191 if line_buffer is None:
1194 1192 line_buffer = text
1195 1193
1196 1194 self.line_buffer = line_buffer
1197 1195 self.text_until_cursor = self.line_buffer[:cursor_pos]
1198 1196
1199 1197 # Start with a clean slate of completions
1200 1198 self.matches[:] = []
1201 1199 custom_res = self.dispatch_custom_completer(text)
1202 1200 if custom_res is not None:
1203 1201 # did custom completers produce something?
1204 1202 self.matches = custom_res
1205 1203 else:
1206 1204 # Extend the list of completions with the results of each
1207 1205 # matcher, so we return results to the user from all
1208 1206 # namespaces.
1209 1207 if self.merge_completions:
1210 1208 self.matches = []
1211 1209 for matcher in self.matchers:
1212 1210 try:
1213 1211 self.matches.extend(matcher(text))
1214 1212 except:
1215 1213 # Show the ugly traceback if the matcher causes an
1216 1214 # exception, but do NOT crash the kernel!
1217 1215 sys.excepthook(*sys.exc_info())
1218 1216 else:
1219 1217 for matcher in self.matchers:
1220 1218 self.matches = matcher(text)
1221 1219 if self.matches:
1222 1220 break
1223 1221 # FIXME: we should extend our api to return a dict with completions for
1224 1222 # different types of objects. The rlcomplete() method could then
1225 1223 # simply collapse the dict into a list for readline, but we'd have
1226 1224 # richer completion semantics in other evironments.
1227 1225 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1228 1226
1229 1227 return text, self.matches
@@ -1,537 +1,532 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 from io import StringIO
9 10
10 11 from IPython.core.splitinput import LineInfo
11 12 from IPython.utils import tokenize2
12 from IPython.utils.py3compat import PY3
13 13 from IPython.utils.tokenize2 import generate_tokens, untokenize, TokenError
14 14
15 if PY3:
16 from io import StringIO
17 else:
18 from StringIO import StringIO
19
20 15 #-----------------------------------------------------------------------------
21 16 # Globals
22 17 #-----------------------------------------------------------------------------
23 18
24 19 # The escape sequences that define the syntax transformations IPython will
25 20 # apply to user input. These can NOT be just changed here: many regular
26 21 # expressions and other parts of the code may use their hardcoded values, and
27 22 # for all intents and purposes they constitute the 'IPython syntax', so they
28 23 # should be considered fixed.
29 24
30 25 ESC_SHELL = '!' # Send line to underlying system shell
31 26 ESC_SH_CAP = '!!' # Send line to system shell and capture output
32 27 ESC_HELP = '?' # Find information about object
33 28 ESC_HELP2 = '??' # Find extra-detailed information about object
34 29 ESC_MAGIC = '%' # Call magic function
35 30 ESC_MAGIC2 = '%%' # Call cell-magic function
36 31 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
37 32 ESC_QUOTE2 = ';' # Quote all args as a single string, call
38 33 ESC_PAREN = '/' # Call first argument with rest of line as arguments
39 34
40 35 ESC_SEQUENCES = [ESC_SHELL, ESC_SH_CAP, ESC_HELP ,\
41 36 ESC_HELP2, ESC_MAGIC, ESC_MAGIC2,\
42 37 ESC_QUOTE, ESC_QUOTE2, ESC_PAREN ]
43 38
44 39
45 40 class InputTransformer(metaclass=abc.ABCMeta):
46 41 """Abstract base class for line-based input transformers."""
47 42
48 43 @abc.abstractmethod
49 44 def push(self, line):
50 45 """Send a line of input to the transformer, returning the transformed
51 46 input or None if the transformer is waiting for more input.
52 47
53 48 Must be overridden by subclasses.
54 49
55 50 Implementations may raise ``SyntaxError`` if the input is invalid. No
56 51 other exceptions may be raised.
57 52 """
58 53 pass
59 54
60 55 @abc.abstractmethod
61 56 def reset(self):
62 57 """Return, transformed any lines that the transformer has accumulated,
63 58 and reset its internal state.
64 59
65 60 Must be overridden by subclasses.
66 61 """
67 62 pass
68 63
69 64 @classmethod
70 65 def wrap(cls, func):
71 66 """Can be used by subclasses as a decorator, to return a factory that
72 67 will allow instantiation with the decorated object.
73 68 """
74 69 @functools.wraps(func)
75 70 def transformer_factory(**kwargs):
76 71 return cls(func, **kwargs)
77 72
78 73 return transformer_factory
79 74
80 75 class StatelessInputTransformer(InputTransformer):
81 76 """Wrapper for a stateless input transformer implemented as a function."""
82 77 def __init__(self, func):
83 78 self.func = func
84 79
85 80 def __repr__(self):
86 81 return "StatelessInputTransformer(func={0!r})".format(self.func)
87 82
88 83 def push(self, line):
89 84 """Send a line of input to the transformer, returning the
90 85 transformed input."""
91 86 return self.func(line)
92 87
93 88 def reset(self):
94 89 """No-op - exists for compatibility."""
95 90 pass
96 91
97 92 class CoroutineInputTransformer(InputTransformer):
98 93 """Wrapper for an input transformer implemented as a coroutine."""
99 94 def __init__(self, coro, **kwargs):
100 95 # Prime it
101 96 self.coro = coro(**kwargs)
102 97 next(self.coro)
103 98
104 99 def __repr__(self):
105 100 return "CoroutineInputTransformer(coro={0!r})".format(self.coro)
106 101
107 102 def push(self, line):
108 103 """Send a line of input to the transformer, returning the
109 104 transformed input or None if the transformer is waiting for more
110 105 input.
111 106 """
112 107 return self.coro.send(line)
113 108
114 109 def reset(self):
115 110 """Return, transformed any lines that the transformer has
116 111 accumulated, and reset its internal state.
117 112 """
118 113 return self.coro.send(None)
119 114
120 115 class TokenInputTransformer(InputTransformer):
121 116 """Wrapper for a token-based input transformer.
122 117
123 118 func should accept a list of tokens (5-tuples, see tokenize docs), and
124 119 return an iterable which can be passed to tokenize.untokenize().
125 120 """
126 121 def __init__(self, func):
127 122 self.func = func
128 123 self.current_line = ""
129 124 self.line_used = False
130 125 self.reset_tokenizer()
131 126
132 127 def reset_tokenizer(self):
133 128 self.tokenizer = generate_tokens(self.get_line)
134 129
135 130 def get_line(self):
136 131 if self.line_used:
137 132 raise TokenError
138 133 self.line_used = True
139 134 return self.current_line
140 135
141 136 def push(self, line):
142 137 self.current_line += line + "\n"
143 138 if self.current_line.isspace():
144 139 return self.reset()
145 140
146 141 self.line_used = False
147 142 tokens = []
148 143 stop_at_NL = False
149 144 try:
150 145 for intok in self.tokenizer:
151 146 tokens.append(intok)
152 147 t = intok[0]
153 148 if t == tokenize2.NEWLINE or (stop_at_NL and t == tokenize2.NL):
154 149 # Stop before we try to pull a line we don't have yet
155 150 break
156 151 elif t == tokenize2.ERRORTOKEN:
157 152 stop_at_NL = True
158 153 except TokenError:
159 154 # Multi-line statement - stop and try again with the next line
160 155 self.reset_tokenizer()
161 156 return None
162 157
163 158 return self.output(tokens)
164 159
165 160 def output(self, tokens):
166 161 self.current_line = ""
167 162 self.reset_tokenizer()
168 163 return untokenize(self.func(tokens)).rstrip('\n')
169 164
170 165 def reset(self):
171 166 l = self.current_line
172 167 self.current_line = ""
173 168 self.reset_tokenizer()
174 169 if l:
175 170 return l.rstrip('\n')
176 171
177 172 class assemble_python_lines(TokenInputTransformer):
178 173 def __init__(self):
179 174 super(assemble_python_lines, self).__init__(None)
180 175
181 176 def output(self, tokens):
182 177 return self.reset()
183 178
184 179 @CoroutineInputTransformer.wrap
185 180 def assemble_logical_lines():
186 181 """Join lines following explicit line continuations (\)"""
187 182 line = ''
188 183 while True:
189 184 line = (yield line)
190 185 if not line or line.isspace():
191 186 continue
192 187
193 188 parts = []
194 189 while line is not None:
195 190 if line.endswith('\\') and (not has_comment(line)):
196 191 parts.append(line[:-1])
197 192 line = (yield None) # Get another line
198 193 else:
199 194 parts.append(line)
200 195 break
201 196
202 197 # Output
203 198 line = ''.join(parts)
204 199
205 200 # Utilities
206 201 def _make_help_call(target, esc, lspace, next_input=None):
207 202 """Prepares a pinfo(2)/psearch call from a target name and the escape
208 203 (i.e. ? or ??)"""
209 204 method = 'pinfo2' if esc == '??' \
210 205 else 'psearch' if '*' in target \
211 206 else 'pinfo'
212 207 arg = " ".join([method, target])
213 208 if next_input is None:
214 209 return '%sget_ipython().magic(%r)' % (lspace, arg)
215 210 else:
216 211 return '%sget_ipython().set_next_input(%r);get_ipython().magic(%r)' % \
217 212 (lspace, next_input, arg)
218 213
219 214 # These define the transformations for the different escape characters.
220 215 def _tr_system(line_info):
221 216 "Translate lines escaped with: !"
222 217 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
223 218 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
224 219
225 220 def _tr_system2(line_info):
226 221 "Translate lines escaped with: !!"
227 222 cmd = line_info.line.lstrip()[2:]
228 223 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
229 224
230 225 def _tr_help(line_info):
231 226 "Translate lines escaped with: ?/??"
232 227 # A naked help line should just fire the intro help screen
233 228 if not line_info.line[1:]:
234 229 return 'get_ipython().show_usage()'
235 230
236 231 return _make_help_call(line_info.ifun, line_info.esc, line_info.pre)
237 232
238 233 def _tr_magic(line_info):
239 234 "Translate lines escaped with: %"
240 235 tpl = '%sget_ipython().magic(%r)'
241 236 if line_info.line.startswith(ESC_MAGIC2):
242 237 return line_info.line
243 238 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
244 239 return tpl % (line_info.pre, cmd)
245 240
246 241 def _tr_quote(line_info):
247 242 "Translate lines escaped with: ,"
248 243 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
249 244 '", "'.join(line_info.the_rest.split()) )
250 245
251 246 def _tr_quote2(line_info):
252 247 "Translate lines escaped with: ;"
253 248 return '%s%s("%s")' % (line_info.pre, line_info.ifun,
254 249 line_info.the_rest)
255 250
256 251 def _tr_paren(line_info):
257 252 "Translate lines escaped with: /"
258 253 return '%s%s(%s)' % (line_info.pre, line_info.ifun,
259 254 ", ".join(line_info.the_rest.split()))
260 255
261 256 tr = { ESC_SHELL : _tr_system,
262 257 ESC_SH_CAP : _tr_system2,
263 258 ESC_HELP : _tr_help,
264 259 ESC_HELP2 : _tr_help,
265 260 ESC_MAGIC : _tr_magic,
266 261 ESC_QUOTE : _tr_quote,
267 262 ESC_QUOTE2 : _tr_quote2,
268 263 ESC_PAREN : _tr_paren }
269 264
270 265 @StatelessInputTransformer.wrap
271 266 def escaped_commands(line):
272 267 """Transform escaped commands - %magic, !system, ?help + various autocalls.
273 268 """
274 269 if not line or line.isspace():
275 270 return line
276 271 lineinf = LineInfo(line)
277 272 if lineinf.esc not in tr:
278 273 return line
279 274
280 275 return tr[lineinf.esc](lineinf)
281 276
282 277 _initial_space_re = re.compile(r'\s*')
283 278
284 279 _help_end_re = re.compile(r"""(%{0,2}
285 280 [a-zA-Z_*][\w*]* # Variable name
286 281 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
287 282 )
288 283 (\?\??)$ # ? or ??
289 284 """,
290 285 re.VERBOSE)
291 286
292 287 # Extra pseudotokens for multiline strings and data structures
293 288 _MULTILINE_STRING = object()
294 289 _MULTILINE_STRUCTURE = object()
295 290
296 291 def _line_tokens(line):
297 292 """Helper for has_comment and ends_in_comment_or_string."""
298 293 readline = StringIO(line).readline
299 294 toktypes = set()
300 295 try:
301 296 for t in generate_tokens(readline):
302 297 toktypes.add(t[0])
303 298 except TokenError as e:
304 299 # There are only two cases where a TokenError is raised.
305 300 if 'multi-line string' in e.args[0]:
306 301 toktypes.add(_MULTILINE_STRING)
307 302 else:
308 303 toktypes.add(_MULTILINE_STRUCTURE)
309 304 return toktypes
310 305
311 306 def has_comment(src):
312 307 """Indicate whether an input line has (i.e. ends in, or is) a comment.
313 308
314 309 This uses tokenize, so it can distinguish comments from # inside strings.
315 310
316 311 Parameters
317 312 ----------
318 313 src : string
319 314 A single line input string.
320 315
321 316 Returns
322 317 -------
323 318 comment : bool
324 319 True if source has a comment.
325 320 """
326 321 return (tokenize2.COMMENT in _line_tokens(src))
327 322
328 323 def ends_in_comment_or_string(src):
329 324 """Indicates whether or not an input line ends in a comment or within
330 325 a multiline string.
331 326
332 327 Parameters
333 328 ----------
334 329 src : string
335 330 A single line input string.
336 331
337 332 Returns
338 333 -------
339 334 comment : bool
340 335 True if source ends in a comment or multiline string.
341 336 """
342 337 toktypes = _line_tokens(src)
343 338 return (tokenize2.COMMENT in toktypes) or (_MULTILINE_STRING in toktypes)
344 339
345 340
346 341 @StatelessInputTransformer.wrap
347 342 def help_end(line):
348 343 """Translate lines with ?/?? at the end"""
349 344 m = _help_end_re.search(line)
350 345 if m is None or ends_in_comment_or_string(line):
351 346 return line
352 347 target = m.group(1)
353 348 esc = m.group(3)
354 349 lspace = _initial_space_re.match(line).group(0)
355 350
356 351 # If we're mid-command, put it back on the next prompt for the user.
357 352 next_input = line.rstrip('?') if line.strip() != m.group(0) else None
358 353
359 354 return _make_help_call(target, esc, lspace, next_input)
360 355
361 356
362 357 @CoroutineInputTransformer.wrap
363 358 def cellmagic(end_on_blank_line=False):
364 359 """Captures & transforms cell magics.
365 360
366 361 After a cell magic is started, this stores up any lines it gets until it is
367 362 reset (sent None).
368 363 """
369 364 tpl = 'get_ipython().run_cell_magic(%r, %r, %r)'
370 365 cellmagic_help_re = re.compile('%%\w+\?')
371 366 line = ''
372 367 while True:
373 368 line = (yield line)
374 369 # consume leading empty lines
375 370 while not line:
376 371 line = (yield line)
377 372
378 373 if not line.startswith(ESC_MAGIC2):
379 374 # This isn't a cell magic, idle waiting for reset then start over
380 375 while line is not None:
381 376 line = (yield line)
382 377 continue
383 378
384 379 if cellmagic_help_re.match(line):
385 380 # This case will be handled by help_end
386 381 continue
387 382
388 383 first = line
389 384 body = []
390 385 line = (yield None)
391 386 while (line is not None) and \
392 387 ((line.strip() != '') or not end_on_blank_line):
393 388 body.append(line)
394 389 line = (yield None)
395 390
396 391 # Output
397 392 magic_name, _, first = first.partition(' ')
398 393 magic_name = magic_name.lstrip(ESC_MAGIC2)
399 394 line = tpl % (magic_name, first, u'\n'.join(body))
400 395
401 396
402 397 def _strip_prompts(prompt_re, initial_re=None, turnoff_re=None):
403 398 """Remove matching input prompts from a block of input.
404 399
405 400 Parameters
406 401 ----------
407 402 prompt_re : regular expression
408 403 A regular expression matching any input prompt (including continuation)
409 404 initial_re : regular expression, optional
410 405 A regular expression matching only the initial prompt, but not continuation.
411 406 If no initial expression is given, prompt_re will be used everywhere.
412 407 Used mainly for plain Python prompts, where the continuation prompt
413 408 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
414 409
415 410 If initial_re and prompt_re differ,
416 411 only initial_re will be tested against the first line.
417 412 If any prompt is found on the first two lines,
418 413 prompts will be stripped from the rest of the block.
419 414 """
420 415 if initial_re is None:
421 416 initial_re = prompt_re
422 417 line = ''
423 418 while True:
424 419 line = (yield line)
425 420
426 421 # First line of cell
427 422 if line is None:
428 423 continue
429 424 out, n1 = initial_re.subn('', line, count=1)
430 425 if turnoff_re and not n1:
431 426 if turnoff_re.match(line):
432 427 # We're in e.g. a cell magic; disable this transformer for
433 428 # the rest of the cell.
434 429 while line is not None:
435 430 line = (yield line)
436 431 continue
437 432
438 433 line = (yield out)
439 434
440 435 if line is None:
441 436 continue
442 437 # check for any prompt on the second line of the cell,
443 438 # because people often copy from just after the first prompt,
444 439 # so we might not see it in the first line.
445 440 out, n2 = prompt_re.subn('', line, count=1)
446 441 line = (yield out)
447 442
448 443 if n1 or n2:
449 444 # Found a prompt in the first two lines - check for it in
450 445 # the rest of the cell as well.
451 446 while line is not None:
452 447 line = (yield prompt_re.sub('', line, count=1))
453 448
454 449 else:
455 450 # Prompts not in input - wait for reset
456 451 while line is not None:
457 452 line = (yield line)
458 453
459 454 @CoroutineInputTransformer.wrap
460 455 def classic_prompt():
461 456 """Strip the >>>/... prompts of the Python interactive shell."""
462 457 # FIXME: non-capturing version (?:...) usable?
463 458 prompt_re = re.compile(r'^(>>>|\.\.\.)( |$)')
464 459 initial_re = re.compile(r'^>>>( |$)')
465 460 # Any %magic/!system is IPython syntax, so we needn't look for >>> prompts
466 461 turnoff_re = re.compile(r'^[%!]')
467 462 return _strip_prompts(prompt_re, initial_re, turnoff_re)
468 463
469 464 @CoroutineInputTransformer.wrap
470 465 def ipy_prompt():
471 466 """Strip IPython's In [1]:/...: prompts."""
472 467 # FIXME: non-capturing version (?:...) usable?
473 468 prompt_re = re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)')
474 469 # Disable prompt stripping inside cell magics
475 470 turnoff_re = re.compile(r'^%%')
476 471 return _strip_prompts(prompt_re, turnoff_re=turnoff_re)
477 472
478 473
479 474 @CoroutineInputTransformer.wrap
480 475 def leading_indent():
481 476 """Remove leading indentation.
482 477
483 478 If the first line starts with a spaces or tabs, the same whitespace will be
484 479 removed from each following line until it is reset.
485 480 """
486 481 space_re = re.compile(r'^[ \t]+')
487 482 line = ''
488 483 while True:
489 484 line = (yield line)
490 485
491 486 if line is None:
492 487 continue
493 488
494 489 m = space_re.match(line)
495 490 if m:
496 491 space = m.group(0)
497 492 while line is not None:
498 493 if line.startswith(space):
499 494 line = line[len(space):]
500 495 line = (yield line)
501 496 else:
502 497 # No leading spaces - wait for reset
503 498 while line is not None:
504 499 line = (yield line)
505 500
506 501
507 502 _assign_pat = \
508 503 r'''(?P<lhs>(\s*)
509 504 ([\w\.]+) # Initial identifier
510 505 (\s*,\s*
511 506 \*?[\w\.]+)* # Further identifiers for unpacking
512 507 \s*?,? # Trailing comma
513 508 )
514 509 \s*=\s*
515 510 '''
516 511
517 512 assign_system_re = re.compile(r'{}!\s*(?P<cmd>.*)'.format(_assign_pat), re.VERBOSE)
518 513 assign_system_template = '%s = get_ipython().getoutput(%r)'
519 514 @StatelessInputTransformer.wrap
520 515 def assign_from_system(line):
521 516 """Transform assignment from system commands (e.g. files = !ls)"""
522 517 m = assign_system_re.match(line)
523 518 if m is None:
524 519 return line
525 520
526 521 return assign_system_template % m.group('lhs', 'cmd')
527 522
528 523 assign_magic_re = re.compile(r'{}%\s*(?P<cmd>.*)'.format(_assign_pat), re.VERBOSE)
529 524 assign_magic_template = '%s = get_ipython().magic(%r)'
530 525 @StatelessInputTransformer.wrap
531 526 def assign_from_magic(line):
532 527 """Transform assignment from magic commands (e.g. a = %who_ls)"""
533 528 m = assign_magic_re.match(line)
534 529 if m is None:
535 530 return line
536 531
537 532 return assign_magic_template % m.group('lhs', 'cmd')
@@ -1,1380 +1,1374 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Implementation of execution-related magic functions."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 import ast
9 9 import bdb
10 10 import gc
11 11 import itertools
12 12 import os
13 13 import sys
14 14 import time
15 15 import timeit
16 16 import math
17 17 from pdb import Restart
18 18
19 19 # cProfile was added in Python2.5
20 20 try:
21 21 import cProfile as profile
22 22 import pstats
23 23 except ImportError:
24 24 # profile isn't bundled by default in Debian for license reasons
25 25 try:
26 26 import profile, pstats
27 27 except ImportError:
28 28 profile = pstats = None
29 29
30 30 from IPython.core import oinspect
31 31 from IPython.core import magic_arguments
32 32 from IPython.core import page
33 33 from IPython.core.error import UsageError
34 34 from IPython.core.macro import Macro
35 35 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
36 36 line_cell_magic, on_off, needs_local_scope)
37 37 from IPython.testing.skipdoctest import skip_doctest
38 38 from IPython.utils import py3compat
39 from IPython.utils.py3compat import builtin_mod, PY3
39 from IPython.utils.py3compat import builtin_mod
40 40 from IPython.utils.contexts import preserve_keys
41 41 from IPython.utils.capture import capture_output
42 42 from IPython.utils.ipstruct import Struct
43 43 from IPython.utils.module_paths import find_mod
44 44 from IPython.utils.path import get_py_filename, shellglob
45 45 from IPython.utils.timing import clock, clock2
46 46 from warnings import warn
47 47 from logging import error
48
49 if PY3:
50 48 from io import StringIO
51 else:
52 from StringIO import StringIO
49
53 50
54 51 #-----------------------------------------------------------------------------
55 52 # Magic implementation classes
56 53 #-----------------------------------------------------------------------------
57 54
58 55
59 56 class TimeitResult(object):
60 57 """
61 58 Object returned by the timeit magic with info about the run.
62 59
63 60 Contains the following attributes :
64 61
65 62 loops: (int) number of loops done per measurement
66 63 repeat: (int) number of times the measurement has been repeated
67 64 best: (float) best execution time / number
68 65 all_runs: (list of float) execution time of each run (in s)
69 66 compile_time: (float) time of statement compilation (s)
70 67
71 68 """
72 69 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
73 70 self.loops = loops
74 71 self.repeat = repeat
75 72 self.best = best
76 73 self.worst = worst
77 74 self.all_runs = all_runs
78 75 self.compile_time = compile_time
79 76 self._precision = precision
80 77 self.timings = [ dt / self.loops for dt in all_runs]
81 78
82 79 @property
83 80 def average(self):
84 81 return math.fsum(self.timings) / len(self.timings)
85 82
86 83 @property
87 84 def stdev(self):
88 85 mean = self.average
89 86 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
90 87
91 88 def __str__(self):
92 89 return (u"%s loop%s, average of %d: %s +- %s per loop (using standard deviation)"
93 90 % (self.loops,"" if self.loops == 1 else "s", self.repeat,
94 91 _format_time(self.average, self._precision),
95 92 _format_time(self.stdev, self._precision)))
96 93
97 94 def _repr_pretty_(self, p , cycle):
98 95 unic = self.__str__()
99 96 p.text(u'<TimeitResult : '+unic+u'>')
100 97
101 98
102 99
103 100 class TimeitTemplateFiller(ast.NodeTransformer):
104 101 """Fill in the AST template for timing execution.
105 102
106 103 This is quite closely tied to the template definition, which is in
107 104 :meth:`ExecutionMagics.timeit`.
108 105 """
109 106 def __init__(self, ast_setup, ast_stmt):
110 107 self.ast_setup = ast_setup
111 108 self.ast_stmt = ast_stmt
112 109
113 110 def visit_FunctionDef(self, node):
114 111 "Fill in the setup statement"
115 112 self.generic_visit(node)
116 113 if node.name == "inner":
117 114 node.body[:1] = self.ast_setup.body
118 115
119 116 return node
120 117
121 118 def visit_For(self, node):
122 119 "Fill in the statement to be timed"
123 120 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
124 121 node.body = self.ast_stmt.body
125 122 return node
126 123
127 124
128 125 class Timer(timeit.Timer):
129 126 """Timer class that explicitly uses self.inner
130 127
131 128 which is an undocumented implementation detail of CPython,
132 129 not shared by PyPy.
133 130 """
134 131 # Timer.timeit copied from CPython 3.4.2
135 132 def timeit(self, number=timeit.default_number):
136 133 """Time 'number' executions of the main statement.
137 134
138 135 To be precise, this executes the setup statement once, and
139 136 then returns the time it takes to execute the main statement
140 137 a number of times, as a float measured in seconds. The
141 138 argument is the number of times through the loop, defaulting
142 139 to one million. The main statement, the setup statement and
143 140 the timer function to be used are passed to the constructor.
144 141 """
145 142 it = itertools.repeat(None, number)
146 143 gcold = gc.isenabled()
147 144 gc.disable()
148 145 try:
149 146 timing = self.inner(it, self.timer)
150 147 finally:
151 148 if gcold:
152 149 gc.enable()
153 150 return timing
154 151
155 152
156 153 @magics_class
157 154 class ExecutionMagics(Magics):
158 155 """Magics related to code execution, debugging, profiling, etc.
159 156
160 157 """
161 158
162 159 def __init__(self, shell):
163 160 super(ExecutionMagics, self).__init__(shell)
164 161 if profile is None:
165 162 self.prun = self.profile_missing_notice
166 163 # Default execution function used to actually run user code.
167 164 self.default_runner = None
168 165
169 166 def profile_missing_notice(self, *args, **kwargs):
170 167 error("""\
171 168 The profile module could not be found. It has been removed from the standard
172 169 python packages because of its non-free license. To use profiling, install the
173 170 python-profiler package from non-free.""")
174 171
175 172 @skip_doctest
176 173 @line_cell_magic
177 174 def prun(self, parameter_s='', cell=None):
178 175
179 176 """Run a statement through the python code profiler.
180 177
181 178 Usage, in line mode:
182 179 %prun [options] statement
183 180
184 181 Usage, in cell mode:
185 182 %%prun [options] [statement]
186 183 code...
187 184 code...
188 185
189 186 In cell mode, the additional code lines are appended to the (possibly
190 187 empty) statement in the first line. Cell mode allows you to easily
191 188 profile multiline blocks without having to put them in a separate
192 189 function.
193 190
194 191 The given statement (which doesn't require quote marks) is run via the
195 192 python profiler in a manner similar to the profile.run() function.
196 193 Namespaces are internally managed to work correctly; profile.run
197 194 cannot be used in IPython because it makes certain assumptions about
198 195 namespaces which do not hold under IPython.
199 196
200 197 Options:
201 198
202 199 -l <limit>
203 200 you can place restrictions on what or how much of the
204 201 profile gets printed. The limit value can be:
205 202
206 203 * A string: only information for function names containing this string
207 204 is printed.
208 205
209 206 * An integer: only these many lines are printed.
210 207
211 208 * A float (between 0 and 1): this fraction of the report is printed
212 209 (for example, use a limit of 0.4 to see the topmost 40% only).
213 210
214 211 You can combine several limits with repeated use of the option. For
215 212 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
216 213 information about class constructors.
217 214
218 215 -r
219 216 return the pstats.Stats object generated by the profiling. This
220 217 object has all the information about the profile in it, and you can
221 218 later use it for further analysis or in other functions.
222 219
223 220 -s <key>
224 221 sort profile by given key. You can provide more than one key
225 222 by using the option several times: '-s key1 -s key2 -s key3...'. The
226 223 default sorting key is 'time'.
227 224
228 225 The following is copied verbatim from the profile documentation
229 226 referenced below:
230 227
231 228 When more than one key is provided, additional keys are used as
232 229 secondary criteria when the there is equality in all keys selected
233 230 before them.
234 231
235 232 Abbreviations can be used for any key names, as long as the
236 233 abbreviation is unambiguous. The following are the keys currently
237 234 defined:
238 235
239 236 ============ =====================
240 237 Valid Arg Meaning
241 238 ============ =====================
242 239 "calls" call count
243 240 "cumulative" cumulative time
244 241 "file" file name
245 242 "module" file name
246 243 "pcalls" primitive call count
247 244 "line" line number
248 245 "name" function name
249 246 "nfl" name/file/line
250 247 "stdname" standard name
251 248 "time" internal time
252 249 ============ =====================
253 250
254 251 Note that all sorts on statistics are in descending order (placing
255 252 most time consuming items first), where as name, file, and line number
256 253 searches are in ascending order (i.e., alphabetical). The subtle
257 254 distinction between "nfl" and "stdname" is that the standard name is a
258 255 sort of the name as printed, which means that the embedded line
259 256 numbers get compared in an odd way. For example, lines 3, 20, and 40
260 257 would (if the file names were the same) appear in the string order
261 258 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
262 259 line numbers. In fact, sort_stats("nfl") is the same as
263 260 sort_stats("name", "file", "line").
264 261
265 262 -T <filename>
266 263 save profile results as shown on screen to a text
267 264 file. The profile is still shown on screen.
268 265
269 266 -D <filename>
270 267 save (via dump_stats) profile statistics to given
271 268 filename. This data is in a format understood by the pstats module, and
272 269 is generated by a call to the dump_stats() method of profile
273 270 objects. The profile is still shown on screen.
274 271
275 272 -q
276 273 suppress output to the pager. Best used with -T and/or -D above.
277 274
278 275 If you want to run complete programs under the profiler's control, use
279 276 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
280 277 contains profiler specific options as described here.
281 278
282 279 You can read the complete documentation for the profile module with::
283 280
284 281 In [1]: import profile; profile.help()
285 282 """
286 283 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
287 284 list_all=True, posix=False)
288 285 if cell is not None:
289 286 arg_str += '\n' + cell
290 287 arg_str = self.shell.input_splitter.transform_cell(arg_str)
291 288 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
292 289
293 290 def _run_with_profiler(self, code, opts, namespace):
294 291 """
295 292 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
296 293
297 294 Parameters
298 295 ----------
299 296 code : str
300 297 Code to be executed.
301 298 opts : Struct
302 299 Options parsed by `self.parse_options`.
303 300 namespace : dict
304 301 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
305 302
306 303 """
307 304
308 305 # Fill default values for unspecified options:
309 306 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
310 307
311 308 prof = profile.Profile()
312 309 try:
313 310 prof = prof.runctx(code, namespace, namespace)
314 311 sys_exit = ''
315 312 except SystemExit:
316 313 sys_exit = """*** SystemExit exception caught in code being profiled."""
317 314
318 315 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
319 316
320 317 lims = opts.l
321 318 if lims:
322 319 lims = [] # rebuild lims with ints/floats/strings
323 320 for lim in opts.l:
324 321 try:
325 322 lims.append(int(lim))
326 323 except ValueError:
327 324 try:
328 325 lims.append(float(lim))
329 326 except ValueError:
330 327 lims.append(lim)
331 328
332 329 # Trap output.
333 330 stdout_trap = StringIO()
334 331 stats_stream = stats.stream
335 332 try:
336 333 stats.stream = stdout_trap
337 334 stats.print_stats(*lims)
338 335 finally:
339 336 stats.stream = stats_stream
340 337
341 338 output = stdout_trap.getvalue()
342 339 output = output.rstrip()
343 340
344 341 if 'q' not in opts:
345 342 page.page(output)
346 343 print(sys_exit, end=' ')
347 344
348 345 dump_file = opts.D[0]
349 346 text_file = opts.T[0]
350 347 if dump_file:
351 348 prof.dump_stats(dump_file)
352 349 print('\n*** Profile stats marshalled to file',\
353 350 repr(dump_file)+'.',sys_exit)
354 351 if text_file:
355 352 pfile = open(text_file,'w')
356 353 pfile.write(output)
357 354 pfile.close()
358 355 print('\n*** Profile printout saved to text file',\
359 356 repr(text_file)+'.',sys_exit)
360 357
361 358 if 'r' in opts:
362 359 return stats
363 360 else:
364 361 return None
365 362
366 363 @line_magic
367 364 def pdb(self, parameter_s=''):
368 365 """Control the automatic calling of the pdb interactive debugger.
369 366
370 367 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
371 368 argument it works as a toggle.
372 369
373 370 When an exception is triggered, IPython can optionally call the
374 371 interactive pdb debugger after the traceback printout. %pdb toggles
375 372 this feature on and off.
376 373
377 374 The initial state of this feature is set in your configuration
378 375 file (the option is ``InteractiveShell.pdb``).
379 376
380 377 If you want to just activate the debugger AFTER an exception has fired,
381 378 without having to type '%pdb on' and rerunning your code, you can use
382 379 the %debug magic."""
383 380
384 381 par = parameter_s.strip().lower()
385 382
386 383 if par:
387 384 try:
388 385 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
389 386 except KeyError:
390 387 print ('Incorrect argument. Use on/1, off/0, '
391 388 'or nothing for a toggle.')
392 389 return
393 390 else:
394 391 # toggle
395 392 new_pdb = not self.shell.call_pdb
396 393
397 394 # set on the shell
398 395 self.shell.call_pdb = new_pdb
399 396 print('Automatic pdb calling has been turned',on_off(new_pdb))
400 397
401 398 @skip_doctest
402 399 @magic_arguments.magic_arguments()
403 400 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
404 401 help="""
405 402 Set break point at LINE in FILE.
406 403 """
407 404 )
408 405 @magic_arguments.argument('statement', nargs='*',
409 406 help="""
410 407 Code to run in debugger.
411 408 You can omit this in cell magic mode.
412 409 """
413 410 )
414 411 @line_cell_magic
415 412 def debug(self, line='', cell=None):
416 413 """Activate the interactive debugger.
417 414
418 415 This magic command support two ways of activating debugger.
419 416 One is to activate debugger before executing code. This way, you
420 417 can set a break point, to step through the code from the point.
421 418 You can use this mode by giving statements to execute and optionally
422 419 a breakpoint.
423 420
424 421 The other one is to activate debugger in post-mortem mode. You can
425 422 activate this mode simply running %debug without any argument.
426 423 If an exception has just occurred, this lets you inspect its stack
427 424 frames interactively. Note that this will always work only on the last
428 425 traceback that occurred, so you must call this quickly after an
429 426 exception that you wish to inspect has fired, because if another one
430 427 occurs, it clobbers the previous one.
431 428
432 429 If you want IPython to automatically do this on every exception, see
433 430 the %pdb magic for more details.
434 431 """
435 432 args = magic_arguments.parse_argstring(self.debug, line)
436 433
437 434 if not (args.breakpoint or args.statement or cell):
438 435 self._debug_post_mortem()
439 436 else:
440 437 code = "\n".join(args.statement)
441 438 if cell:
442 439 code += "\n" + cell
443 440 self._debug_exec(code, args.breakpoint)
444 441
445 442 def _debug_post_mortem(self):
446 443 self.shell.debugger(force=True)
447 444
448 445 def _debug_exec(self, code, breakpoint):
449 446 if breakpoint:
450 447 (filename, bp_line) = breakpoint.rsplit(':', 1)
451 448 bp_line = int(bp_line)
452 449 else:
453 450 (filename, bp_line) = (None, None)
454 451 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
455 452
456 453 @line_magic
457 454 def tb(self, s):
458 455 """Print the last traceback with the currently active exception mode.
459 456
460 457 See %xmode for changing exception reporting modes."""
461 458 self.shell.showtraceback()
462 459
463 460 @skip_doctest
464 461 @line_magic
465 462 def run(self, parameter_s='', runner=None,
466 463 file_finder=get_py_filename):
467 464 """Run the named file inside IPython as a program.
468 465
469 466 Usage::
470 467
471 468 %run [-n -i -e -G]
472 469 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
473 470 ( -m mod | file ) [args]
474 471
475 472 Parameters after the filename are passed as command-line arguments to
476 473 the program (put in sys.argv). Then, control returns to IPython's
477 474 prompt.
478 475
479 476 This is similar to running at a system prompt ``python file args``,
480 477 but with the advantage of giving you IPython's tracebacks, and of
481 478 loading all variables into your interactive namespace for further use
482 479 (unless -p is used, see below).
483 480
484 481 The file is executed in a namespace initially consisting only of
485 482 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
486 483 sees its environment as if it were being run as a stand-alone program
487 484 (except for sharing global objects such as previously imported
488 485 modules). But after execution, the IPython interactive namespace gets
489 486 updated with all variables defined in the program (except for __name__
490 487 and sys.argv). This allows for very convenient loading of code for
491 488 interactive work, while giving each program a 'clean sheet' to run in.
492 489
493 490 Arguments are expanded using shell-like glob match. Patterns
494 491 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
495 492 tilde '~' will be expanded into user's home directory. Unlike
496 493 real shells, quotation does not suppress expansions. Use
497 494 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
498 495 To completely disable these expansions, you can use -G flag.
499 496
500 497 Options:
501 498
502 499 -n
503 500 __name__ is NOT set to '__main__', but to the running file's name
504 501 without extension (as python does under import). This allows running
505 502 scripts and reloading the definitions in them without calling code
506 503 protected by an ``if __name__ == "__main__"`` clause.
507 504
508 505 -i
509 506 run the file in IPython's namespace instead of an empty one. This
510 507 is useful if you are experimenting with code written in a text editor
511 508 which depends on variables defined interactively.
512 509
513 510 -e
514 511 ignore sys.exit() calls or SystemExit exceptions in the script
515 512 being run. This is particularly useful if IPython is being used to
516 513 run unittests, which always exit with a sys.exit() call. In such
517 514 cases you are interested in the output of the test results, not in
518 515 seeing a traceback of the unittest module.
519 516
520 517 -t
521 518 print timing information at the end of the run. IPython will give
522 519 you an estimated CPU time consumption for your script, which under
523 520 Unix uses the resource module to avoid the wraparound problems of
524 521 time.clock(). Under Unix, an estimate of time spent on system tasks
525 522 is also given (for Windows platforms this is reported as 0.0).
526 523
527 524 If -t is given, an additional ``-N<N>`` option can be given, where <N>
528 525 must be an integer indicating how many times you want the script to
529 526 run. The final timing report will include total and per run results.
530 527
531 528 For example (testing the script uniq_stable.py)::
532 529
533 530 In [1]: run -t uniq_stable
534 531
535 532 IPython CPU timings (estimated):
536 533 User : 0.19597 s.
537 534 System: 0.0 s.
538 535
539 536 In [2]: run -t -N5 uniq_stable
540 537
541 538 IPython CPU timings (estimated):
542 539 Total runs performed: 5
543 540 Times : Total Per run
544 541 User : 0.910862 s, 0.1821724 s.
545 542 System: 0.0 s, 0.0 s.
546 543
547 544 -d
548 545 run your program under the control of pdb, the Python debugger.
549 546 This allows you to execute your program step by step, watch variables,
550 547 etc. Internally, what IPython does is similar to calling::
551 548
552 549 pdb.run('execfile("YOURFILENAME")')
553 550
554 551 with a breakpoint set on line 1 of your file. You can change the line
555 552 number for this automatic breakpoint to be <N> by using the -bN option
556 553 (where N must be an integer). For example::
557 554
558 555 %run -d -b40 myscript
559 556
560 557 will set the first breakpoint at line 40 in myscript.py. Note that
561 558 the first breakpoint must be set on a line which actually does
562 559 something (not a comment or docstring) for it to stop execution.
563 560
564 561 Or you can specify a breakpoint in a different file::
565 562
566 563 %run -d -b myotherfile.py:20 myscript
567 564
568 565 When the pdb debugger starts, you will see a (Pdb) prompt. You must
569 566 first enter 'c' (without quotes) to start execution up to the first
570 567 breakpoint.
571 568
572 569 Entering 'help' gives information about the use of the debugger. You
573 570 can easily see pdb's full documentation with "import pdb;pdb.help()"
574 571 at a prompt.
575 572
576 573 -p
577 574 run program under the control of the Python profiler module (which
578 575 prints a detailed report of execution times, function calls, etc).
579 576
580 577 You can pass other options after -p which affect the behavior of the
581 578 profiler itself. See the docs for %prun for details.
582 579
583 580 In this mode, the program's variables do NOT propagate back to the
584 581 IPython interactive namespace (because they remain in the namespace
585 582 where the profiler executes them).
586 583
587 584 Internally this triggers a call to %prun, see its documentation for
588 585 details on the options available specifically for profiling.
589 586
590 587 There is one special usage for which the text above doesn't apply:
591 588 if the filename ends with .ipy[nb], the file is run as ipython script,
592 589 just as if the commands were written on IPython prompt.
593 590
594 591 -m
595 592 specify module name to load instead of script path. Similar to
596 593 the -m option for the python interpreter. Use this option last if you
597 594 want to combine with other %run options. Unlike the python interpreter
598 595 only source modules are allowed no .pyc or .pyo files.
599 596 For example::
600 597
601 598 %run -m example
602 599
603 600 will run the example module.
604 601
605 602 -G
606 603 disable shell-like glob expansion of arguments.
607 604
608 605 """
609 606
610 607 # get arguments and set sys.argv for program to be run.
611 608 opts, arg_lst = self.parse_options(parameter_s,
612 609 'nidtN:b:pD:l:rs:T:em:G',
613 610 mode='list', list_all=1)
614 611 if "m" in opts:
615 612 modulename = opts["m"][0]
616 613 modpath = find_mod(modulename)
617 614 if modpath is None:
618 615 warn('%r is not a valid modulename on sys.path'%modulename)
619 616 return
620 617 arg_lst = [modpath] + arg_lst
621 618 try:
622 619 filename = file_finder(arg_lst[0])
623 620 except IndexError:
624 621 warn('you must provide at least a filename.')
625 622 print('\n%run:\n', oinspect.getdoc(self.run))
626 623 return
627 624 except IOError as e:
628 625 try:
629 626 msg = str(e)
630 627 except UnicodeError:
631 628 msg = e.message
632 629 error(msg)
633 630 return
634 631
635 632 if filename.lower().endswith(('.ipy', '.ipynb')):
636 633 with preserve_keys(self.shell.user_ns, '__file__'):
637 634 self.shell.user_ns['__file__'] = filename
638 635 self.shell.safe_execfile_ipy(filename)
639 636 return
640 637
641 638 # Control the response to exit() calls made by the script being run
642 639 exit_ignore = 'e' in opts
643 640
644 641 # Make sure that the running script gets a proper sys.argv as if it
645 642 # were run from a system shell.
646 643 save_argv = sys.argv # save it for later restoring
647 644
648 645 if 'G' in opts:
649 646 args = arg_lst[1:]
650 647 else:
651 648 # tilde and glob expansion
652 649 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
653 650
654 651 sys.argv = [filename] + args # put in the proper filename
655 # protect sys.argv from potential unicode strings on Python 2:
656 if not py3compat.PY3:
657 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
658 652
659 653 if 'i' in opts:
660 654 # Run in user's interactive namespace
661 655 prog_ns = self.shell.user_ns
662 656 __name__save = self.shell.user_ns['__name__']
663 657 prog_ns['__name__'] = '__main__'
664 658 main_mod = self.shell.user_module
665 659
666 660 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
667 661 # set the __file__ global in the script's namespace
668 662 # TK: Is this necessary in interactive mode?
669 663 prog_ns['__file__'] = filename
670 664 else:
671 665 # Run in a fresh, empty namespace
672 666 if 'n' in opts:
673 667 name = os.path.splitext(os.path.basename(filename))[0]
674 668 else:
675 669 name = '__main__'
676 670
677 671 # The shell MUST hold a reference to prog_ns so after %run
678 672 # exits, the python deletion mechanism doesn't zero it out
679 673 # (leaving dangling references). See interactiveshell for details
680 674 main_mod = self.shell.new_main_mod(filename, name)
681 675 prog_ns = main_mod.__dict__
682 676
683 677 # pickle fix. See interactiveshell for an explanation. But we need to
684 678 # make sure that, if we overwrite __main__, we replace it at the end
685 679 main_mod_name = prog_ns['__name__']
686 680
687 681 if main_mod_name == '__main__':
688 682 restore_main = sys.modules['__main__']
689 683 else:
690 684 restore_main = False
691 685
692 686 # This needs to be undone at the end to prevent holding references to
693 687 # every single object ever created.
694 688 sys.modules[main_mod_name] = main_mod
695 689
696 690 if 'p' in opts or 'd' in opts:
697 691 if 'm' in opts:
698 692 code = 'run_module(modulename, prog_ns)'
699 693 code_ns = {
700 694 'run_module': self.shell.safe_run_module,
701 695 'prog_ns': prog_ns,
702 696 'modulename': modulename,
703 697 }
704 698 else:
705 699 if 'd' in opts:
706 700 # allow exceptions to raise in debug mode
707 701 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
708 702 else:
709 703 code = 'execfile(filename, prog_ns)'
710 704 code_ns = {
711 705 'execfile': self.shell.safe_execfile,
712 706 'prog_ns': prog_ns,
713 707 'filename': get_py_filename(filename),
714 708 }
715 709
716 710 try:
717 711 stats = None
718 712 if 'p' in opts:
719 713 stats = self._run_with_profiler(code, opts, code_ns)
720 714 else:
721 715 if 'd' in opts:
722 716 bp_file, bp_line = parse_breakpoint(
723 717 opts.get('b', ['1'])[0], filename)
724 718 self._run_with_debugger(
725 719 code, code_ns, filename, bp_line, bp_file)
726 720 else:
727 721 if 'm' in opts:
728 722 def run():
729 723 self.shell.safe_run_module(modulename, prog_ns)
730 724 else:
731 725 if runner is None:
732 726 runner = self.default_runner
733 727 if runner is None:
734 728 runner = self.shell.safe_execfile
735 729
736 730 def run():
737 731 runner(filename, prog_ns, prog_ns,
738 732 exit_ignore=exit_ignore)
739 733
740 734 if 't' in opts:
741 735 # timed execution
742 736 try:
743 737 nruns = int(opts['N'][0])
744 738 if nruns < 1:
745 739 error('Number of runs must be >=1')
746 740 return
747 741 except (KeyError):
748 742 nruns = 1
749 743 self._run_with_timing(run, nruns)
750 744 else:
751 745 # regular execution
752 746 run()
753 747
754 748 if 'i' in opts:
755 749 self.shell.user_ns['__name__'] = __name__save
756 750 else:
757 751 # update IPython interactive namespace
758 752
759 753 # Some forms of read errors on the file may mean the
760 754 # __name__ key was never set; using pop we don't have to
761 755 # worry about a possible KeyError.
762 756 prog_ns.pop('__name__', None)
763 757
764 758 with preserve_keys(self.shell.user_ns, '__file__'):
765 759 self.shell.user_ns.update(prog_ns)
766 760 finally:
767 761 # It's a bit of a mystery why, but __builtins__ can change from
768 762 # being a module to becoming a dict missing some key data after
769 763 # %run. As best I can see, this is NOT something IPython is doing
770 764 # at all, and similar problems have been reported before:
771 765 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
772 766 # Since this seems to be done by the interpreter itself, the best
773 767 # we can do is to at least restore __builtins__ for the user on
774 768 # exit.
775 769 self.shell.user_ns['__builtins__'] = builtin_mod
776 770
777 771 # Ensure key global structures are restored
778 772 sys.argv = save_argv
779 773 if restore_main:
780 774 sys.modules['__main__'] = restore_main
781 775 else:
782 776 # Remove from sys.modules the reference to main_mod we'd
783 777 # added. Otherwise it will trap references to objects
784 778 # contained therein.
785 779 del sys.modules[main_mod_name]
786 780
787 781 return stats
788 782
789 783 def _run_with_debugger(self, code, code_ns, filename=None,
790 784 bp_line=None, bp_file=None):
791 785 """
792 786 Run `code` in debugger with a break point.
793 787
794 788 Parameters
795 789 ----------
796 790 code : str
797 791 Code to execute.
798 792 code_ns : dict
799 793 A namespace in which `code` is executed.
800 794 filename : str
801 795 `code` is ran as if it is in `filename`.
802 796 bp_line : int, optional
803 797 Line number of the break point.
804 798 bp_file : str, optional
805 799 Path to the file in which break point is specified.
806 800 `filename` is used if not given.
807 801
808 802 Raises
809 803 ------
810 804 UsageError
811 805 If the break point given by `bp_line` is not valid.
812 806
813 807 """
814 808 deb = self.shell.InteractiveTB.pdb
815 809 if not deb:
816 810 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
817 811 deb = self.shell.InteractiveTB.pdb
818 812
819 813 # deb.checkline() fails if deb.curframe exists but is None; it can
820 814 # handle it not existing. https://github.com/ipython/ipython/issues/10028
821 815 if hasattr(deb, 'curframe'):
822 816 del deb.curframe
823 817
824 818 # reset Breakpoint state, which is moronically kept
825 819 # in a class
826 820 bdb.Breakpoint.next = 1
827 821 bdb.Breakpoint.bplist = {}
828 822 bdb.Breakpoint.bpbynumber = [None]
829 823 if bp_line is not None:
830 824 # Set an initial breakpoint to stop execution
831 825 maxtries = 10
832 826 bp_file = bp_file or filename
833 827 checkline = deb.checkline(bp_file, bp_line)
834 828 if not checkline:
835 829 for bp in range(bp_line + 1, bp_line + maxtries + 1):
836 830 if deb.checkline(bp_file, bp):
837 831 break
838 832 else:
839 833 msg = ("\nI failed to find a valid line to set "
840 834 "a breakpoint\n"
841 835 "after trying up to line: %s.\n"
842 836 "Please set a valid breakpoint manually "
843 837 "with the -b option." % bp)
844 838 raise UsageError(msg)
845 839 # if we find a good linenumber, set the breakpoint
846 840 deb.do_break('%s:%s' % (bp_file, bp_line))
847 841
848 842 if filename:
849 843 # Mimic Pdb._runscript(...)
850 844 deb._wait_for_mainpyfile = True
851 845 deb.mainpyfile = deb.canonic(filename)
852 846
853 847 # Start file run
854 848 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
855 849 try:
856 850 if filename:
857 851 # save filename so it can be used by methods on the deb object
858 852 deb._exec_filename = filename
859 853 while True:
860 854 try:
861 855 deb.run(code, code_ns)
862 856 except Restart:
863 857 print("Restarting")
864 858 if filename:
865 859 deb._wait_for_mainpyfile = True
866 860 deb.mainpyfile = deb.canonic(filename)
867 861 continue
868 862 else:
869 863 break
870 864
871 865
872 866 except:
873 867 etype, value, tb = sys.exc_info()
874 868 # Skip three frames in the traceback: the %run one,
875 869 # one inside bdb.py, and the command-line typed by the
876 870 # user (run by exec in pdb itself).
877 871 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
878 872
879 873 @staticmethod
880 874 def _run_with_timing(run, nruns):
881 875 """
882 876 Run function `run` and print timing information.
883 877
884 878 Parameters
885 879 ----------
886 880 run : callable
887 881 Any callable object which takes no argument.
888 882 nruns : int
889 883 Number of times to execute `run`.
890 884
891 885 """
892 886 twall0 = time.time()
893 887 if nruns == 1:
894 888 t0 = clock2()
895 889 run()
896 890 t1 = clock2()
897 891 t_usr = t1[0] - t0[0]
898 892 t_sys = t1[1] - t0[1]
899 893 print("\nIPython CPU timings (estimated):")
900 894 print(" User : %10.2f s." % t_usr)
901 895 print(" System : %10.2f s." % t_sys)
902 896 else:
903 897 runs = range(nruns)
904 898 t0 = clock2()
905 899 for nr in runs:
906 900 run()
907 901 t1 = clock2()
908 902 t_usr = t1[0] - t0[0]
909 903 t_sys = t1[1] - t0[1]
910 904 print("\nIPython CPU timings (estimated):")
911 905 print("Total runs performed:", nruns)
912 906 print(" Times : %10s %10s" % ('Total', 'Per run'))
913 907 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
914 908 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
915 909 twall1 = time.time()
916 910 print("Wall time: %10.2f s." % (twall1 - twall0))
917 911
918 912 @skip_doctest
919 913 @line_cell_magic
920 914 def timeit(self, line='', cell=None):
921 915 """Time execution of a Python statement or expression
922 916
923 917 Usage, in line mode:
924 918 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
925 919 or in cell mode:
926 920 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
927 921 code
928 922 code...
929 923
930 924 Time execution of a Python statement or expression using the timeit
931 925 module. This function can be used both as a line and cell magic:
932 926
933 927 - In line mode you can time a single-line statement (though multiple
934 928 ones can be chained with using semicolons).
935 929
936 930 - In cell mode, the statement in the first line is used as setup code
937 931 (executed but not timed) and the body of the cell is timed. The cell
938 932 body has access to any variables created in the setup code.
939 933
940 934 Options:
941 935 -n<N>: execute the given statement <N> times in a loop. If this value
942 936 is not given, a fitting value is chosen.
943 937
944 938 -r<R>: repeat the loop iteration <R> times and take the best result.
945 939 Default: 3
946 940
947 941 -t: use time.time to measure the time, which is the default on Unix.
948 942 This function measures wall time.
949 943
950 944 -c: use time.clock to measure the time, which is the default on
951 945 Windows and measures wall time. On Unix, resource.getrusage is used
952 946 instead and returns the CPU user time.
953 947
954 948 -p<P>: use a precision of <P> digits to display the timing result.
955 949 Default: 3
956 950
957 951 -q: Quiet, do not print result.
958 952
959 953 -o: return a TimeitResult that can be stored in a variable to inspect
960 954 the result in more details.
961 955
962 956
963 957 Examples
964 958 --------
965 959 ::
966 960
967 961 In [1]: %timeit pass
968 962 100000000 loops, average of 7: 5.48 ns +- 0.354 ns per loop (using standard deviation)
969 963
970 964 In [2]: u = None
971 965
972 966 In [3]: %timeit u is None
973 967 10000000 loops, average of 7: 22.7 ns +- 2.33 ns per loop (using standard deviation)
974 968
975 969 In [4]: %timeit -r 4 u == None
976 970 10000000 loops, average of 4: 27.5 ns +- 2.91 ns per loop (using standard deviation)
977 971
978 972 In [5]: import time
979 973
980 974 In [6]: %timeit -n1 time.sleep(2)
981 975 1 loop, average of 7: 2 s +- 4.71 Β΅s per loop (using standard deviation)
982 976
983 977
984 978 The times reported by %timeit will be slightly higher than those
985 979 reported by the timeit.py script when variables are accessed. This is
986 980 due to the fact that %timeit executes the statement in the namespace
987 981 of the shell, compared with timeit.py, which uses a single setup
988 982 statement to import function or create variables. Generally, the bias
989 983 does not matter as long as results from timeit.py are not mixed with
990 984 those from %timeit."""
991 985
992 986 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
993 987 posix=False, strict=False)
994 988 if stmt == "" and cell is None:
995 989 return
996 990
997 991 timefunc = timeit.default_timer
998 992 number = int(getattr(opts, "n", 0))
999 993 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1000 994 repeat = int(getattr(opts, "r", default_repeat))
1001 995 precision = int(getattr(opts, "p", 3))
1002 996 quiet = 'q' in opts
1003 997 return_result = 'o' in opts
1004 998 if hasattr(opts, "t"):
1005 999 timefunc = time.time
1006 1000 if hasattr(opts, "c"):
1007 1001 timefunc = clock
1008 1002
1009 1003 timer = Timer(timer=timefunc)
1010 1004 # this code has tight coupling to the inner workings of timeit.Timer,
1011 1005 # but is there a better way to achieve that the code stmt has access
1012 1006 # to the shell namespace?
1013 1007 transform = self.shell.input_splitter.transform_cell
1014 1008
1015 1009 if cell is None:
1016 1010 # called as line magic
1017 1011 ast_setup = self.shell.compile.ast_parse("pass")
1018 1012 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1019 1013 else:
1020 1014 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1021 1015 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1022 1016
1023 1017 ast_setup = self.shell.transform_ast(ast_setup)
1024 1018 ast_stmt = self.shell.transform_ast(ast_stmt)
1025 1019
1026 1020 # This codestring is taken from timeit.template - we fill it in as an
1027 1021 # AST, so that we can apply our AST transformations to the user code
1028 1022 # without affecting the timing code.
1029 1023 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1030 1024 ' setup\n'
1031 1025 ' _t0 = _timer()\n'
1032 1026 ' for _i in _it:\n'
1033 1027 ' stmt\n'
1034 1028 ' _t1 = _timer()\n'
1035 1029 ' return _t1 - _t0\n')
1036 1030
1037 1031 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1038 1032 timeit_ast = ast.fix_missing_locations(timeit_ast)
1039 1033
1040 1034 # Track compilation time so it can be reported if too long
1041 1035 # Minimum time above which compilation time will be reported
1042 1036 tc_min = 0.1
1043 1037
1044 1038 t0 = clock()
1045 1039 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1046 1040 tc = clock()-t0
1047 1041
1048 1042 ns = {}
1049 1043 exec(code, self.shell.user_ns, ns)
1050 1044 timer.inner = ns["inner"]
1051 1045
1052 1046 # This is used to check if there is a huge difference between the
1053 1047 # best and worst timings.
1054 1048 # Issue: https://github.com/ipython/ipython/issues/6471
1055 1049 if number == 0:
1056 1050 # determine number so that 0.2 <= total time < 2.0
1057 1051 for index in range(0, 10):
1058 1052 number = 10 ** index
1059 1053 time_number = timer.timeit(number)
1060 1054 if time_number >= 0.2:
1061 1055 break
1062 1056
1063 1057 all_runs = timer.repeat(repeat, number)
1064 1058 best = min(all_runs) / number
1065 1059 worst = max(all_runs) / number
1066 1060 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1067 1061
1068 1062 if not quiet :
1069 1063 # Check best timing is greater than zero to avoid a
1070 1064 # ZeroDivisionError.
1071 1065 # In cases where the slowest timing is lesser than a micosecond
1072 1066 # we assume that it does not really matter if the fastest
1073 1067 # timing is 4 times faster than the slowest timing or not.
1074 1068 if worst > 4 * best and best > 0 and worst > 1e-6:
1075 1069 print("The slowest run took %0.2f times longer than the "
1076 1070 "fastest. This could mean that an intermediate result "
1077 1071 "is being cached." % (worst / best))
1078 1072
1079 1073 print( timeit_result )
1080 1074
1081 1075 if tc > tc_min:
1082 1076 print("Compiler time: %.2f s" % tc)
1083 1077 if return_result:
1084 1078 return timeit_result
1085 1079
1086 1080 @skip_doctest
1087 1081 @needs_local_scope
1088 1082 @line_cell_magic
1089 1083 def time(self,line='', cell=None, local_ns=None):
1090 1084 """Time execution of a Python statement or expression.
1091 1085
1092 1086 The CPU and wall clock times are printed, and the value of the
1093 1087 expression (if any) is returned. Note that under Win32, system time
1094 1088 is always reported as 0, since it can not be measured.
1095 1089
1096 1090 This function can be used both as a line and cell magic:
1097 1091
1098 1092 - In line mode you can time a single-line statement (though multiple
1099 1093 ones can be chained with using semicolons).
1100 1094
1101 1095 - In cell mode, you can time the cell body (a directly
1102 1096 following statement raises an error).
1103 1097
1104 1098 This function provides very basic timing functionality. Use the timeit
1105 1099 magic for more control over the measurement.
1106 1100
1107 1101 Examples
1108 1102 --------
1109 1103 ::
1110 1104
1111 1105 In [1]: %time 2**128
1112 1106 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1113 1107 Wall time: 0.00
1114 1108 Out[1]: 340282366920938463463374607431768211456L
1115 1109
1116 1110 In [2]: n = 1000000
1117 1111
1118 1112 In [3]: %time sum(range(n))
1119 1113 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1120 1114 Wall time: 1.37
1121 1115 Out[3]: 499999500000L
1122 1116
1123 1117 In [4]: %time print 'hello world'
1124 1118 hello world
1125 1119 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1126 1120 Wall time: 0.00
1127 1121
1128 1122 Note that the time needed by Python to compile the given expression
1129 1123 will be reported if it is more than 0.1s. In this example, the
1130 1124 actual exponentiation is done by Python at compilation time, so while
1131 1125 the expression can take a noticeable amount of time to compute, that
1132 1126 time is purely due to the compilation:
1133 1127
1134 1128 In [5]: %time 3**9999;
1135 1129 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1136 1130 Wall time: 0.00 s
1137 1131
1138 1132 In [6]: %time 3**999999;
1139 1133 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1140 1134 Wall time: 0.00 s
1141 1135 Compiler : 0.78 s
1142 1136 """
1143 1137
1144 1138 # fail immediately if the given expression can't be compiled
1145 1139
1146 1140 if line and cell:
1147 1141 raise UsageError("Can't use statement directly after '%%time'!")
1148 1142
1149 1143 if cell:
1150 1144 expr = self.shell.input_transformer_manager.transform_cell(cell)
1151 1145 else:
1152 1146 expr = self.shell.input_transformer_manager.transform_cell(line)
1153 1147
1154 1148 # Minimum time above which parse time will be reported
1155 1149 tp_min = 0.1
1156 1150
1157 1151 t0 = clock()
1158 1152 expr_ast = self.shell.compile.ast_parse(expr)
1159 1153 tp = clock()-t0
1160 1154
1161 1155 # Apply AST transformations
1162 1156 expr_ast = self.shell.transform_ast(expr_ast)
1163 1157
1164 1158 # Minimum time above which compilation time will be reported
1165 1159 tc_min = 0.1
1166 1160
1167 1161 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1168 1162 mode = 'eval'
1169 1163 source = '<timed eval>'
1170 1164 expr_ast = ast.Expression(expr_ast.body[0].value)
1171 1165 else:
1172 1166 mode = 'exec'
1173 1167 source = '<timed exec>'
1174 1168 t0 = clock()
1175 1169 code = self.shell.compile(expr_ast, source, mode)
1176 1170 tc = clock()-t0
1177 1171
1178 1172 # skew measurement as little as possible
1179 1173 glob = self.shell.user_ns
1180 1174 wtime = time.time
1181 1175 # time execution
1182 1176 wall_st = wtime()
1183 1177 if mode=='eval':
1184 1178 st = clock2()
1185 1179 try:
1186 1180 out = eval(code, glob, local_ns)
1187 1181 except:
1188 1182 self.shell.showtraceback()
1189 1183 return
1190 1184 end = clock2()
1191 1185 else:
1192 1186 st = clock2()
1193 1187 try:
1194 1188 exec(code, glob, local_ns)
1195 1189 except:
1196 1190 self.shell.showtraceback()
1197 1191 return
1198 1192 end = clock2()
1199 1193 out = None
1200 1194 wall_end = wtime()
1201 1195 # Compute actual times and report
1202 1196 wall_time = wall_end-wall_st
1203 1197 cpu_user = end[0]-st[0]
1204 1198 cpu_sys = end[1]-st[1]
1205 1199 cpu_tot = cpu_user+cpu_sys
1206 1200 # On windows cpu_sys is always zero, so no new information to the next print
1207 1201 if sys.platform != 'win32':
1208 1202 print("CPU times: user %s, sys: %s, total: %s" % \
1209 1203 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1210 1204 print("Wall time: %s" % _format_time(wall_time))
1211 1205 if tc > tc_min:
1212 1206 print("Compiler : %s" % _format_time(tc))
1213 1207 if tp > tp_min:
1214 1208 print("Parser : %s" % _format_time(tp))
1215 1209 return out
1216 1210
1217 1211 @skip_doctest
1218 1212 @line_magic
1219 1213 def macro(self, parameter_s=''):
1220 1214 """Define a macro for future re-execution. It accepts ranges of history,
1221 1215 filenames or string objects.
1222 1216
1223 1217 Usage:\\
1224 1218 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1225 1219
1226 1220 Options:
1227 1221
1228 1222 -r: use 'raw' input. By default, the 'processed' history is used,
1229 1223 so that magics are loaded in their transformed version to valid
1230 1224 Python. If this option is given, the raw input as typed at the
1231 1225 command line is used instead.
1232 1226
1233 1227 -q: quiet macro definition. By default, a tag line is printed
1234 1228 to indicate the macro has been created, and then the contents of
1235 1229 the macro are printed. If this option is given, then no printout
1236 1230 is produced once the macro is created.
1237 1231
1238 1232 This will define a global variable called `name` which is a string
1239 1233 made of joining the slices and lines you specify (n1,n2,... numbers
1240 1234 above) from your input history into a single string. This variable
1241 1235 acts like an automatic function which re-executes those lines as if
1242 1236 you had typed them. You just type 'name' at the prompt and the code
1243 1237 executes.
1244 1238
1245 1239 The syntax for indicating input ranges is described in %history.
1246 1240
1247 1241 Note: as a 'hidden' feature, you can also use traditional python slice
1248 1242 notation, where N:M means numbers N through M-1.
1249 1243
1250 1244 For example, if your history contains (print using %hist -n )::
1251 1245
1252 1246 44: x=1
1253 1247 45: y=3
1254 1248 46: z=x+y
1255 1249 47: print x
1256 1250 48: a=5
1257 1251 49: print 'x',x,'y',y
1258 1252
1259 1253 you can create a macro with lines 44 through 47 (included) and line 49
1260 1254 called my_macro with::
1261 1255
1262 1256 In [55]: %macro my_macro 44-47 49
1263 1257
1264 1258 Now, typing `my_macro` (without quotes) will re-execute all this code
1265 1259 in one pass.
1266 1260
1267 1261 You don't need to give the line-numbers in order, and any given line
1268 1262 number can appear multiple times. You can assemble macros with any
1269 1263 lines from your input history in any order.
1270 1264
1271 1265 The macro is a simple object which holds its value in an attribute,
1272 1266 but IPython's display system checks for macros and executes them as
1273 1267 code instead of printing them when you type their name.
1274 1268
1275 1269 You can view a macro's contents by explicitly printing it with::
1276 1270
1277 1271 print macro_name
1278 1272
1279 1273 """
1280 1274 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1281 1275 if not args: # List existing macros
1282 1276 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1283 1277 if len(args) == 1:
1284 1278 raise UsageError(
1285 1279 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1286 1280 name, codefrom = args[0], " ".join(args[1:])
1287 1281
1288 1282 #print 'rng',ranges # dbg
1289 1283 try:
1290 1284 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1291 1285 except (ValueError, TypeError) as e:
1292 1286 print(e.args[0])
1293 1287 return
1294 1288 macro = Macro(lines)
1295 1289 self.shell.define_macro(name, macro)
1296 1290 if not ( 'q' in opts) :
1297 1291 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1298 1292 print('=== Macro contents: ===')
1299 1293 print(macro, end=' ')
1300 1294
1301 1295 @magic_arguments.magic_arguments()
1302 1296 @magic_arguments.argument('output', type=str, default='', nargs='?',
1303 1297 help="""The name of the variable in which to store output.
1304 1298 This is a utils.io.CapturedIO object with stdout/err attributes
1305 1299 for the text of the captured output.
1306 1300
1307 1301 CapturedOutput also has a show() method for displaying the output,
1308 1302 and __call__ as well, so you can use that to quickly display the
1309 1303 output.
1310 1304
1311 1305 If unspecified, captured output is discarded.
1312 1306 """
1313 1307 )
1314 1308 @magic_arguments.argument('--no-stderr', action="store_true",
1315 1309 help="""Don't capture stderr."""
1316 1310 )
1317 1311 @magic_arguments.argument('--no-stdout', action="store_true",
1318 1312 help="""Don't capture stdout."""
1319 1313 )
1320 1314 @magic_arguments.argument('--no-display', action="store_true",
1321 1315 help="""Don't capture IPython's rich display."""
1322 1316 )
1323 1317 @cell_magic
1324 1318 def capture(self, line, cell):
1325 1319 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1326 1320 args = magic_arguments.parse_argstring(self.capture, line)
1327 1321 out = not args.no_stdout
1328 1322 err = not args.no_stderr
1329 1323 disp = not args.no_display
1330 1324 with capture_output(out, err, disp) as io:
1331 1325 self.shell.run_cell(cell)
1332 1326 if args.output:
1333 1327 self.shell.user_ns[args.output] = io
1334 1328
1335 1329 def parse_breakpoint(text, current_file):
1336 1330 '''Returns (file, line) for file:line and (current_file, line) for line'''
1337 1331 colon = text.find(':')
1338 1332 if colon == -1:
1339 1333 return current_file, int(text)
1340 1334 else:
1341 1335 return text[:colon], int(text[colon+1:])
1342 1336
1343 1337 def _format_time(timespan, precision=3):
1344 1338 """Formats the timespan in a human readable form"""
1345 1339
1346 1340 if timespan >= 60.0:
1347 1341 # we have more than a minute, format that in a human readable form
1348 1342 # Idea from http://snipplr.com/view/5713/
1349 1343 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1350 1344 time = []
1351 1345 leftover = timespan
1352 1346 for suffix, length in parts:
1353 1347 value = int(leftover / length)
1354 1348 if value > 0:
1355 1349 leftover = leftover % length
1356 1350 time.append(u'%s%s' % (str(value), suffix))
1357 1351 if leftover < 1:
1358 1352 break
1359 1353 return " ".join(time)
1360 1354
1361 1355
1362 1356 # Unfortunately the unicode 'micro' symbol can cause problems in
1363 1357 # certain terminals.
1364 1358 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1365 1359 # Try to prevent crashes by being more secure than it needs to
1366 1360 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1367 1361 units = [u"s", u"ms",u'us',"ns"] # the save value
1368 1362 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1369 1363 try:
1370 1364 u'\xb5'.encode(sys.stdout.encoding)
1371 1365 units = [u"s", u"ms",u'\xb5s',"ns"]
1372 1366 except:
1373 1367 pass
1374 1368 scaling = [1, 1e3, 1e6, 1e9]
1375 1369
1376 1370 if timespan > 0.0:
1377 1371 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1378 1372 else:
1379 1373 order = 3
1380 1374 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,408 +1,405 b''
1 1 # encoding: utf-8
2 2 """
3 3 A mixin for :class:`~IPython.core.application.Application` classes that
4 4 launch InteractiveShell instances, load extensions, etc.
5 5 """
6 6
7 7 # Copyright (c) IPython Development Team.
8 8 # Distributed under the terms of the Modified BSD License.
9 9
10 10 import glob
11 11 import os
12 12 import sys
13 13
14 14 from traitlets.config.application import boolean_flag
15 15 from traitlets.config.configurable import Configurable
16 16 from traitlets.config.loader import Config
17 17 from IPython.core import pylabtools
18 18 from IPython.utils import py3compat
19 19 from IPython.utils.contexts import preserve_keys
20 20 from IPython.utils.path import filefind
21 21 from traitlets import (
22 22 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
23 23 )
24 24 from IPython.terminal import pt_inputhooks
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Aliases and Flags
28 28 #-----------------------------------------------------------------------------
29 29
30 30 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
31 31
32 32 backend_keys = sorted(pylabtools.backends.keys())
33 33 backend_keys.insert(0, 'auto')
34 34
35 35 shell_flags = {}
36 36
37 37 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
38 38 addflag('autoindent', 'InteractiveShell.autoindent',
39 39 'Turn on autoindenting.', 'Turn off autoindenting.'
40 40 )
41 41 addflag('automagic', 'InteractiveShell.automagic',
42 42 """Turn on the auto calling of magic commands. Type %%magic at the
43 43 IPython prompt for more information.""",
44 44 'Turn off the auto calling of magic commands.'
45 45 )
46 46 addflag('pdb', 'InteractiveShell.pdb',
47 47 "Enable auto calling the pdb debugger after every exception.",
48 48 "Disable auto calling the pdb debugger after every exception."
49 49 )
50 50 addflag('pprint', 'PlainTextFormatter.pprint',
51 51 "Enable auto pretty printing of results.",
52 52 "Disable auto pretty printing of results."
53 53 )
54 54 addflag('color-info', 'InteractiveShell.color_info',
55 55 """IPython can display information about objects via a set of functions,
56 56 and optionally can use colors for this, syntax highlighting
57 57 source code and various other elements. This is on by default, but can cause
58 58 problems with some pagers. If you see such problems, you can disable the
59 59 colours.""",
60 60 "Disable using colors for info related things."
61 61 )
62 62 nosep_config = Config()
63 63 nosep_config.InteractiveShell.separate_in = ''
64 64 nosep_config.InteractiveShell.separate_out = ''
65 65 nosep_config.InteractiveShell.separate_out2 = ''
66 66
67 67 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
68 68 shell_flags['pylab'] = (
69 69 {'InteractiveShellApp' : {'pylab' : 'auto'}},
70 70 """Pre-load matplotlib and numpy for interactive use with
71 71 the default matplotlib backend."""
72 72 )
73 73 shell_flags['matplotlib'] = (
74 74 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
75 75 """Configure matplotlib for interactive use with
76 76 the default matplotlib backend."""
77 77 )
78 78
79 79 # it's possible we don't want short aliases for *all* of these:
80 80 shell_aliases = dict(
81 81 autocall='InteractiveShell.autocall',
82 82 colors='InteractiveShell.colors',
83 83 logfile='InteractiveShell.logfile',
84 84 logappend='InteractiveShell.logappend',
85 85 c='InteractiveShellApp.code_to_run',
86 86 m='InteractiveShellApp.module_to_run',
87 87 ext='InteractiveShellApp.extra_extension',
88 88 gui='InteractiveShellApp.gui',
89 89 pylab='InteractiveShellApp.pylab',
90 90 matplotlib='InteractiveShellApp.matplotlib',
91 91 )
92 92 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
93 93
94 94 #-----------------------------------------------------------------------------
95 95 # Main classes and functions
96 96 #-----------------------------------------------------------------------------
97 97
98 98 class InteractiveShellApp(Configurable):
99 99 """A Mixin for applications that start InteractiveShell instances.
100 100
101 101 Provides configurables for loading extensions and executing files
102 102 as part of configuring a Shell environment.
103 103
104 104 The following methods should be called by the :meth:`initialize` method
105 105 of the subclass:
106 106
107 107 - :meth:`init_path`
108 108 - :meth:`init_shell` (to be implemented by the subclass)
109 109 - :meth:`init_gui_pylab`
110 110 - :meth:`init_extensions`
111 111 - :meth:`init_code`
112 112 """
113 113 extensions = List(Unicode(),
114 114 help="A list of dotted module names of IPython extensions to load."
115 115 ).tag(config=True)
116 116 extra_extension = Unicode('',
117 117 help="dotted module name of an IPython extension to load."
118 118 ).tag(config=True)
119 119
120 120 reraise_ipython_extension_failures = Bool(False,
121 121 help="Reraise exceptions encountered loading IPython extensions?",
122 122 ).tag(config=True)
123 123
124 124 # Extensions that are always loaded (not configurable)
125 125 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
126 126
127 127 hide_initial_ns = Bool(True,
128 128 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
129 129 be hidden from tools like %who?"""
130 130 ).tag(config=True)
131 131
132 132 exec_files = List(Unicode(),
133 133 help="""List of files to run at IPython startup."""
134 134 ).tag(config=True)
135 135 exec_PYTHONSTARTUP = Bool(True,
136 136 help="""Run the file referenced by the PYTHONSTARTUP environment
137 137 variable at IPython startup."""
138 138 ).tag(config=True)
139 139 file_to_run = Unicode('',
140 140 help="""A file to be run""").tag(config=True)
141 141
142 142 exec_lines = List(Unicode(),
143 143 help="""lines of code to run at IPython startup."""
144 144 ).tag(config=True)
145 145 code_to_run = Unicode('',
146 146 help="Execute the given command string."
147 147 ).tag(config=True)
148 148 module_to_run = Unicode('',
149 149 help="Run the module as a script."
150 150 ).tag(config=True)
151 151 gui = CaselessStrEnum(gui_keys, allow_none=True,
152 152 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
153 153 ).tag(config=True)
154 154 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
155 155 help="""Configure matplotlib for interactive use with
156 156 the default matplotlib backend."""
157 157 ).tag(config=True)
158 158 pylab = CaselessStrEnum(backend_keys, allow_none=True,
159 159 help="""Pre-load matplotlib and numpy for interactive use,
160 160 selecting a particular matplotlib backend and loop integration.
161 161 """
162 162 ).tag(config=True)
163 163 pylab_import_all = Bool(True,
164 164 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
165 165 and an ``import *`` is done from numpy and pylab, when using pylab mode.
166 166
167 167 When False, pylab mode should not import any names into the user namespace.
168 168 """
169 169 ).tag(config=True)
170 170 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
171 171 allow_none=True)
172 172 # whether interact-loop should start
173 173 interact = Bool(True)
174 174
175 175 user_ns = Instance(dict, args=None, allow_none=True)
176 176 @observe('user_ns')
177 177 def _user_ns_changed(self, change):
178 178 if self.shell is not None:
179 179 self.shell.user_ns = change['new']
180 180 self.shell.init_user_ns()
181 181
182 182 def init_path(self):
183 183 """Add current working directory, '', to sys.path"""
184 184 if sys.path[0] != '':
185 185 sys.path.insert(0, '')
186 186
187 187 def init_shell(self):
188 188 raise NotImplementedError("Override in subclasses")
189 189
190 190 def init_gui_pylab(self):
191 191 """Enable GUI event loop integration, taking pylab into account."""
192 192 enable = False
193 193 shell = self.shell
194 194 if self.pylab:
195 195 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
196 196 key = self.pylab
197 197 elif self.matplotlib:
198 198 enable = shell.enable_matplotlib
199 199 key = self.matplotlib
200 200 elif self.gui:
201 201 enable = shell.enable_gui
202 202 key = self.gui
203 203
204 204 if not enable:
205 205 return
206 206
207 207 try:
208 208 r = enable(key)
209 209 except ImportError:
210 210 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
211 211 self.shell.showtraceback()
212 212 return
213 213 except Exception:
214 214 self.log.warning("GUI event loop or pylab initialization failed")
215 215 self.shell.showtraceback()
216 216 return
217 217
218 218 if isinstance(r, tuple):
219 219 gui, backend = r[:2]
220 220 self.log.info("Enabling GUI event loop integration, "
221 221 "eventloop=%s, matplotlib=%s", gui, backend)
222 222 if key == "auto":
223 223 print("Using matplotlib backend: %s" % backend)
224 224 else:
225 225 gui = r
226 226 self.log.info("Enabling GUI event loop integration, "
227 227 "eventloop=%s", gui)
228 228
229 229 def init_extensions(self):
230 230 """Load all IPython extensions in IPythonApp.extensions.
231 231
232 232 This uses the :meth:`ExtensionManager.load_extensions` to load all
233 233 the extensions listed in ``self.extensions``.
234 234 """
235 235 try:
236 236 self.log.debug("Loading IPython extensions...")
237 237 extensions = self.default_extensions + self.extensions
238 238 if self.extra_extension:
239 239 extensions.append(self.extra_extension)
240 240 for ext in extensions:
241 241 try:
242 242 self.log.info("Loading IPython extension: %s" % ext)
243 243 self.shell.extension_manager.load_extension(ext)
244 244 except:
245 245 if self.reraise_ipython_extension_failures:
246 246 raise
247 247 msg = ("Error in loading extension: {ext}\n"
248 248 "Check your config files in {location}".format(
249 249 ext=ext,
250 250 location=self.profile_dir.location
251 251 ))
252 252 self.log.warning(msg, exc_info=True)
253 253 except:
254 254 if self.reraise_ipython_extension_failures:
255 255 raise
256 256 self.log.warning("Unknown error in loading extensions:", exc_info=True)
257 257
258 258 def init_code(self):
259 259 """run the pre-flight code, specified via exec_lines"""
260 260 self._run_startup_files()
261 261 self._run_exec_lines()
262 262 self._run_exec_files()
263 263
264 264 # Hide variables defined here from %who etc.
265 265 if self.hide_initial_ns:
266 266 self.shell.user_ns_hidden.update(self.shell.user_ns)
267 267
268 268 # command-line execution (ipython -i script.py, ipython -m module)
269 269 # should *not* be excluded from %whos
270 270 self._run_cmd_line_code()
271 271 self._run_module()
272 272
273 273 # flush output, so itwon't be attached to the first cell
274 274 sys.stdout.flush()
275 275 sys.stderr.flush()
276 276
277 277 def _run_exec_lines(self):
278 278 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
279 279 if not self.exec_lines:
280 280 return
281 281 try:
282 282 self.log.debug("Running code from IPythonApp.exec_lines...")
283 283 for line in self.exec_lines:
284 284 try:
285 285 self.log.info("Running code in user namespace: %s" %
286 286 line)
287 287 self.shell.run_cell(line, store_history=False)
288 288 except:
289 289 self.log.warning("Error in executing line in user "
290 290 "namespace: %s" % line)
291 291 self.shell.showtraceback()
292 292 except:
293 293 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
294 294 self.shell.showtraceback()
295 295
296 296 def _exec_file(self, fname, shell_futures=False):
297 297 try:
298 298 full_filename = filefind(fname, [u'.', self.ipython_dir])
299 299 except IOError:
300 300 self.log.warning("File not found: %r"%fname)
301 301 return
302 302 # Make sure that the running script gets a proper sys.argv as if it
303 303 # were run from a system shell.
304 304 save_argv = sys.argv
305 305 sys.argv = [full_filename] + self.extra_args[1:]
306 # protect sys.argv from potential unicode strings on Python 2:
307 if not py3compat.PY3:
308 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
309 306 try:
310 307 if os.path.isfile(full_filename):
311 308 self.log.info("Running file in user namespace: %s" %
312 309 full_filename)
313 310 # Ensure that __file__ is always defined to match Python
314 311 # behavior.
315 312 with preserve_keys(self.shell.user_ns, '__file__'):
316 313 self.shell.user_ns['__file__'] = fname
317 314 if full_filename.endswith('.ipy'):
318 315 self.shell.safe_execfile_ipy(full_filename,
319 316 shell_futures=shell_futures)
320 317 else:
321 318 # default to python, even without extension
322 319 self.shell.safe_execfile(full_filename,
323 320 self.shell.user_ns,
324 321 shell_futures=shell_futures,
325 322 raise_exceptions=True)
326 323 finally:
327 324 sys.argv = save_argv
328 325
329 326 def _run_startup_files(self):
330 327 """Run files from profile startup directory"""
331 328 startup_dir = self.profile_dir.startup_dir
332 329 startup_files = []
333 330
334 331 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
335 332 not (self.file_to_run or self.code_to_run or self.module_to_run):
336 333 python_startup = os.environ['PYTHONSTARTUP']
337 334 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
338 335 try:
339 336 self._exec_file(python_startup)
340 337 except:
341 338 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
342 339 self.shell.showtraceback()
343 340
344 341 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
345 342 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
346 343 if not startup_files:
347 344 return
348 345
349 346 self.log.debug("Running startup files from %s...", startup_dir)
350 347 try:
351 348 for fname in sorted(startup_files):
352 349 self._exec_file(fname)
353 350 except:
354 351 self.log.warning("Unknown error in handling startup files:")
355 352 self.shell.showtraceback()
356 353
357 354 def _run_exec_files(self):
358 355 """Run files from IPythonApp.exec_files"""
359 356 if not self.exec_files:
360 357 return
361 358
362 359 self.log.debug("Running files in IPythonApp.exec_files...")
363 360 try:
364 361 for fname in self.exec_files:
365 362 self._exec_file(fname)
366 363 except:
367 364 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
368 365 self.shell.showtraceback()
369 366
370 367 def _run_cmd_line_code(self):
371 368 """Run code or file specified at the command-line"""
372 369 if self.code_to_run:
373 370 line = self.code_to_run
374 371 try:
375 372 self.log.info("Running code given at command line (c=): %s" %
376 373 line)
377 374 self.shell.run_cell(line, store_history=False)
378 375 except:
379 376 self.log.warning("Error in executing line in user namespace: %s" %
380 377 line)
381 378 self.shell.showtraceback()
382 379 if not self.interact:
383 380 self.exit(1)
384 381
385 382 # Like Python itself, ignore the second if the first of these is present
386 383 elif self.file_to_run:
387 384 fname = self.file_to_run
388 385 if os.path.isdir(fname):
389 386 fname = os.path.join(fname, "__main__.py")
390 387 try:
391 388 self._exec_file(fname, shell_futures=True)
392 389 except:
393 390 self.shell.showtraceback(tb_offset=4)
394 391 if not self.interact:
395 392 self.exit(1)
396 393
397 394 def _run_module(self):
398 395 """Run module specified at the command-line."""
399 396 if self.module_to_run:
400 397 # Make sure that the module gets a proper sys.argv as if it were
401 398 # run using `python -m`.
402 399 save_argv = sys.argv
403 400 sys.argv = [sys.executable] + self.extra_args
404 401 try:
405 402 self.shell.safe_run_module(self.module_to_run,
406 403 self.shell.user_ns)
407 404 finally:
408 405 sys.argv = save_argv
@@ -1,42 +1,39 b''
1 1 # coding: utf-8
2 2 import nose.tools as nt
3 3
4 4 from IPython.core.splitinput import split_user_input, LineInfo
5 5 from IPython.testing import tools as tt
6 6 from IPython.utils import py3compat
7 7
8 8 tests = [
9 9 ('x=1', ('', '', 'x', '=1')),
10 10 ('?', ('', '?', '', '')),
11 11 ('??', ('', '??', '', '')),
12 12 (' ?', (' ', '?', '', '')),
13 13 (' ??', (' ', '??', '', '')),
14 14 ('??x', ('', '??', 'x', '')),
15 15 ('?x=1', ('', '?', 'x', '=1')),
16 16 ('!ls', ('', '!', 'ls', '')),
17 17 (' !ls', (' ', '!', 'ls', '')),
18 18 ('!!ls', ('', '!!', 'ls', '')),
19 19 (' !!ls', (' ', '!!', 'ls', '')),
20 20 (',ls', ('', ',', 'ls', '')),
21 21 (';ls', ('', ';', 'ls', '')),
22 22 (' ;ls', (' ', ';', 'ls', '')),
23 23 ('f.g(x)', ('', '', 'f.g', '(x)')),
24 24 ('f.g (x)', ('', '', 'f.g', '(x)')),
25 25 ('?%hist1', ('', '?', '%hist1', '')),
26 26 ('?%%hist2', ('', '?', '%%hist2', '')),
27 27 ('??%hist3', ('', '??', '%hist3', '')),
28 28 ('??%%hist4', ('', '??', '%%hist4', '')),
29 29 ('?x*', ('', '?', 'x*', '')),
30 30 ]
31 if py3compat.PY3:
32 31 tests.append((u"PΓ©rez Fernando", (u'', u'', u'PΓ©rez', u'Fernando')))
33 else:
34 tests.append((u"PΓ©rez Fernando", (u'', u'', u'P', u'Γ©rez Fernando')))
35 32
36 33 def test_split_user_input():
37 34 return tt.check_pairs(split_user_input, tests)
38 35
39 36 def test_LineInfo():
40 37 """Simple test for LineInfo construction and str()"""
41 38 linfo = LineInfo(' %cd /home')
42 39 nt.assert_equal(str(linfo), 'LineInfo [ |%|cd|/home]')
@@ -1,1468 +1,1461 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Verbose and colourful traceback formatting.
4 4
5 5 **ColorTB**
6 6
7 7 I've always found it a bit hard to visually parse tracebacks in Python. The
8 8 ColorTB class is a solution to that problem. It colors the different parts of a
9 9 traceback in a manner similar to what you would expect from a syntax-highlighting
10 10 text editor.
11 11
12 12 Installation instructions for ColorTB::
13 13
14 14 import sys,ultratb
15 15 sys.excepthook = ultratb.ColorTB()
16 16
17 17 **VerboseTB**
18 18
19 19 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
20 20 of useful info when a traceback occurs. Ping originally had it spit out HTML
21 21 and intended it for CGI programmers, but why should they have all the fun? I
22 22 altered it to spit out colored text to the terminal. It's a bit overwhelming,
23 23 but kind of neat, and maybe useful for long-running programs that you believe
24 24 are bug-free. If a crash *does* occur in that type of program you want details.
25 25 Give it a shot--you'll love it or you'll hate it.
26 26
27 27 .. note::
28 28
29 29 The Verbose mode prints the variables currently visible where the exception
30 30 happened (shortening their strings if too long). This can potentially be
31 31 very slow, if you happen to have a huge data structure whose string
32 32 representation is complex to compute. Your computer may appear to freeze for
33 33 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
34 34 with Ctrl-C (maybe hitting it more than once).
35 35
36 36 If you encounter this kind of situation often, you may want to use the
37 37 Verbose_novars mode instead of the regular Verbose, which avoids formatting
38 38 variables (but otherwise includes the information and context given by
39 39 Verbose).
40 40
41 41 .. note::
42 42
43 43 The verbose mode print all variables in the stack, which means it can
44 44 potentially leak sensitive information like access keys, or unencryted
45 45 password.
46 46
47 47 Installation instructions for VerboseTB::
48 48
49 49 import sys,ultratb
50 50 sys.excepthook = ultratb.VerboseTB()
51 51
52 52 Note: Much of the code in this module was lifted verbatim from the standard
53 53 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
54 54
55 55 Color schemes
56 56 -------------
57 57
58 58 The colors are defined in the class TBTools through the use of the
59 59 ColorSchemeTable class. Currently the following exist:
60 60
61 61 - NoColor: allows all of this module to be used in any terminal (the color
62 62 escapes are just dummy blank strings).
63 63
64 64 - Linux: is meant to look good in a terminal like the Linux console (black
65 65 or very dark background).
66 66
67 67 - LightBG: similar to Linux but swaps dark/light colors to be more readable
68 68 in light background terminals.
69 69
70 70 - Neutral: a neutral color scheme that should be readable on both light and
71 71 dark background
72 72
73 73 You can implement other color schemes easily, the syntax is fairly
74 74 self-explanatory. Please send back new schemes you develop to the author for
75 75 possible inclusion in future releases.
76 76
77 77 Inheritance diagram:
78 78
79 79 .. inheritance-diagram:: IPython.core.ultratb
80 80 :parts: 3
81 81 """
82 82
83 83 #*****************************************************************************
84 84 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
85 85 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
86 86 #
87 87 # Distributed under the terms of the BSD License. The full license is in
88 88 # the file COPYING, distributed as part of this software.
89 89 #*****************************************************************************
90 90
91 91
92 92 import dis
93 93 import inspect
94 94 import keyword
95 95 import linecache
96 96 import os
97 97 import pydoc
98 98 import re
99 99 import sys
100 100 import time
101 101 import tokenize
102 102 import traceback
103 103 import types
104 104
105 105 try: # Python 2
106 106 generate_tokens = tokenize.generate_tokens
107 107 except AttributeError: # Python 3
108 108 generate_tokens = tokenize.tokenize
109 109
110 110 # For purposes of monkeypatching inspect to fix a bug in it.
111 111 from inspect import getsourcefile, getfile, getmodule, \
112 112 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
113 113
114 114 # IPython's own modules
115 115 from IPython import get_ipython
116 116 from IPython.core import debugger
117 117 from IPython.core.display_trap import DisplayTrap
118 118 from IPython.core.excolors import exception_colors
119 119 from IPython.utils import PyColorize
120 120 from IPython.utils import openpy
121 121 from IPython.utils import path as util_path
122 122 from IPython.utils import py3compat
123 123 from IPython.utils.data import uniq_stable
124 124 from IPython.utils.terminal import get_terminal_size
125 125 from logging import info, error
126 126
127 127 import IPython.utils.colorable as colorable
128 128
129 129 # Globals
130 130 # amount of space to put line numbers before verbose tracebacks
131 131 INDENT_SIZE = 8
132 132
133 133 # Default color scheme. This is used, for example, by the traceback
134 134 # formatter. When running in an actual IPython instance, the user's rc.colors
135 135 # value is used, but having a module global makes this functionality available
136 136 # to users of ultratb who are NOT running inside ipython.
137 137 DEFAULT_SCHEME = 'NoColor'
138 138
139 139 # ---------------------------------------------------------------------------
140 140 # Code begins
141 141
142 142 # Utility functions
143 143 def inspect_error():
144 144 """Print a message about internal inspect errors.
145 145
146 146 These are unfortunately quite common."""
147 147
148 148 error('Internal Python error in the inspect module.\n'
149 149 'Below is the traceback from this internal error.\n')
150 150
151 151
152 152 # This function is a monkeypatch we apply to the Python inspect module. We have
153 153 # now found when it's needed (see discussion on issue gh-1456), and we have a
154 154 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
155 155 # the monkeypatch is not applied. TK, Aug 2012.
156 156 def findsource(object):
157 157 """Return the entire source file and starting line number for an object.
158 158
159 159 The argument may be a module, class, method, function, traceback, frame,
160 160 or code object. The source code is returned as a list of all the lines
161 161 in the file and the line number indexes a line in that list. An IOError
162 162 is raised if the source code cannot be retrieved.
163 163
164 164 FIXED version with which we monkeypatch the stdlib to work around a bug."""
165 165
166 166 file = getsourcefile(object) or getfile(object)
167 167 # If the object is a frame, then trying to get the globals dict from its
168 168 # module won't work. Instead, the frame object itself has the globals
169 169 # dictionary.
170 170 globals_dict = None
171 171 if inspect.isframe(object):
172 172 # XXX: can this ever be false?
173 173 globals_dict = object.f_globals
174 174 else:
175 175 module = getmodule(object, file)
176 176 if module:
177 177 globals_dict = module.__dict__
178 178 lines = linecache.getlines(file, globals_dict)
179 179 if not lines:
180 180 raise IOError('could not get source code')
181 181
182 182 if ismodule(object):
183 183 return lines, 0
184 184
185 185 if isclass(object):
186 186 name = object.__name__
187 187 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
188 188 # make some effort to find the best matching class definition:
189 189 # use the one with the least indentation, which is the one
190 190 # that's most probably not inside a function definition.
191 191 candidates = []
192 192 for i in range(len(lines)):
193 193 match = pat.match(lines[i])
194 194 if match:
195 195 # if it's at toplevel, it's already the best one
196 196 if lines[i][0] == 'c':
197 197 return lines, i
198 198 # else add whitespace to candidate list
199 199 candidates.append((match.group(1), i))
200 200 if candidates:
201 201 # this will sort by whitespace, and by line number,
202 202 # less whitespace first
203 203 candidates.sort()
204 204 return lines, candidates[0][1]
205 205 else:
206 206 raise IOError('could not find class definition')
207 207
208 208 if ismethod(object):
209 209 object = object.__func__
210 210 if isfunction(object):
211 211 object = object.__code__
212 212 if istraceback(object):
213 213 object = object.tb_frame
214 214 if isframe(object):
215 215 object = object.f_code
216 216 if iscode(object):
217 217 if not hasattr(object, 'co_firstlineno'):
218 218 raise IOError('could not find function definition')
219 219 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
220 220 pmatch = pat.match
221 221 # fperez - fix: sometimes, co_firstlineno can give a number larger than
222 222 # the length of lines, which causes an error. Safeguard against that.
223 223 lnum = min(object.co_firstlineno, len(lines)) - 1
224 224 while lnum > 0:
225 225 if pmatch(lines[lnum]):
226 226 break
227 227 lnum -= 1
228 228
229 229 return lines, lnum
230 230 raise IOError('could not find code object')
231 231
232 232
233 233 # This is a patched version of inspect.getargs that applies the (unmerged)
234 234 # patch for http://bugs.python.org/issue14611 by Stefano Taschini. This fixes
235 235 # https://github.com/ipython/ipython/issues/8205 and
236 236 # https://github.com/ipython/ipython/issues/8293
237 237 def getargs(co):
238 238 """Get information about the arguments accepted by a code object.
239 239
240 240 Three things are returned: (args, varargs, varkw), where 'args' is
241 241 a list of argument names (possibly containing nested lists), and
242 242 'varargs' and 'varkw' are the names of the * and ** arguments or None."""
243 243 if not iscode(co):
244 244 raise TypeError('{!r} is not a code object'.format(co))
245 245
246 246 nargs = co.co_argcount
247 247 names = co.co_varnames
248 248 args = list(names[:nargs])
249 249 step = 0
250 250
251 251 # The following acrobatics are for anonymous (tuple) arguments.
252 252 for i in range(nargs):
253 253 if args[i][:1] in ('', '.'):
254 254 stack, remain, count = [], [], []
255 255 while step < len(co.co_code):
256 256 op = ord(co.co_code[step])
257 257 step = step + 1
258 258 if op >= dis.HAVE_ARGUMENT:
259 259 opname = dis.opname[op]
260 260 value = ord(co.co_code[step]) + ord(co.co_code[step+1])*256
261 261 step = step + 2
262 262 if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
263 263 remain.append(value)
264 264 count.append(value)
265 265 elif opname in ('STORE_FAST', 'STORE_DEREF'):
266 266 if op in dis.haslocal:
267 267 stack.append(co.co_varnames[value])
268 268 elif op in dis.hasfree:
269 269 stack.append((co.co_cellvars + co.co_freevars)[value])
270 270 # Special case for sublists of length 1: def foo((bar))
271 271 # doesn't generate the UNPACK_TUPLE bytecode, so if
272 272 # `remain` is empty here, we have such a sublist.
273 273 if not remain:
274 274 stack[0] = [stack[0]]
275 275 break
276 276 else:
277 277 remain[-1] = remain[-1] - 1
278 278 while remain[-1] == 0:
279 279 remain.pop()
280 280 size = count.pop()
281 281 stack[-size:] = [stack[-size:]]
282 282 if not remain:
283 283 break
284 284 remain[-1] = remain[-1] - 1
285 285 if not remain:
286 286 break
287 287 args[i] = stack[0]
288 288
289 289 varargs = None
290 290 if co.co_flags & inspect.CO_VARARGS:
291 291 varargs = co.co_varnames[nargs]
292 292 nargs = nargs + 1
293 293 varkw = None
294 294 if co.co_flags & inspect.CO_VARKEYWORDS:
295 295 varkw = co.co_varnames[nargs]
296 296 return inspect.Arguments(args, varargs, varkw)
297 297
298 298
299 299 # Monkeypatch inspect to apply our bugfix.
300 300 def with_patch_inspect(f):
301 """decorator for monkeypatching inspect.findsource"""
301 """
302 Deprecated since IPython 6.0
303 decorator for monkeypatching inspect.findsource
304 """
302 305
303 306 def wrapped(*args, **kwargs):
304 307 save_findsource = inspect.findsource
305 308 save_getargs = inspect.getargs
306 309 inspect.findsource = findsource
307 310 inspect.getargs = getargs
308 311 try:
309 312 return f(*args, **kwargs)
310 313 finally:
311 314 inspect.findsource = save_findsource
312 315 inspect.getargs = save_getargs
313 316
314 317 return wrapped
315 318
316 319
317 if py3compat.PY3:
318 fixed_getargvalues = inspect.getargvalues
319 else:
320 # Fixes for https://github.com/ipython/ipython/issues/8293
321 # and https://github.com/ipython/ipython/issues/8205.
322 # The relevant bug is caused by failure to correctly handle anonymous tuple
323 # unpacking, which only exists in Python 2.
324 fixed_getargvalues = with_patch_inspect(inspect.getargvalues)
325
326
327 320 def fix_frame_records_filenames(records):
328 321 """Try to fix the filenames in each record from inspect.getinnerframes().
329 322
330 323 Particularly, modules loaded from within zip files have useless filenames
331 324 attached to their code object, and inspect.getinnerframes() just uses it.
332 325 """
333 326 fixed_records = []
334 327 for frame, filename, line_no, func_name, lines, index in records:
335 328 # Look inside the frame's globals dictionary for __file__,
336 329 # which should be better. However, keep Cython filenames since
337 330 # we prefer the source filenames over the compiled .so file.
338 331 filename = py3compat.cast_unicode_py2(filename, "utf-8")
339 332 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
340 333 better_fn = frame.f_globals.get('__file__', None)
341 334 if isinstance(better_fn, str):
342 335 # Check the type just in case someone did something weird with
343 336 # __file__. It might also be None if the error occurred during
344 337 # import.
345 338 filename = better_fn
346 339 fixed_records.append((frame, filename, line_no, func_name, lines, index))
347 340 return fixed_records
348 341
349 342
350 343 @with_patch_inspect
351 344 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
352 345 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
353 346
354 347 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
355 348 # If the error is at the console, don't build any context, since it would
356 349 # otherwise produce 5 blank lines printed out (there is no file at the
357 350 # console)
358 351 rec_check = records[tb_offset:]
359 352 try:
360 353 rname = rec_check[0][1]
361 354 if rname == '<ipython console>' or rname.endswith('<string>'):
362 355 return rec_check
363 356 except IndexError:
364 357 pass
365 358
366 359 aux = traceback.extract_tb(etb)
367 360 assert len(records) == len(aux)
368 361 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
369 362 maybeStart = lnum - 1 - context // 2
370 363 start = max(maybeStart, 0)
371 364 end = start + context
372 365 lines = linecache.getlines(file)[start:end]
373 366 buf = list(records[i])
374 367 buf[LNUM_POS] = lnum
375 368 buf[INDEX_POS] = lnum - 1 - start
376 369 buf[LINES_POS] = lines
377 370 records[i] = tuple(buf)
378 371 return records[tb_offset:]
379 372
380 373 # Helper function -- largely belongs to VerboseTB, but we need the same
381 374 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
382 375 # can be recognized properly by ipython.el's py-traceback-line-re
383 376 # (SyntaxErrors have to be treated specially because they have no traceback)
384 377
385 378
386 379 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, _line_format=(lambda x,_:x,None)):
387 380 numbers_width = INDENT_SIZE - 1
388 381 res = []
389 382 i = lnum - index
390 383
391 384 for line in lines:
392 385 line = py3compat.cast_unicode(line)
393 386
394 387 new_line, err = _line_format(line, 'str')
395 388 if not err: line = new_line
396 389
397 390 if i == lnum:
398 391 # This is the line with the error
399 392 pad = numbers_width - len(str(i))
400 393 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
401 394 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
402 395 Colors.line, line, Colors.Normal)
403 396 else:
404 397 num = '%*s' % (numbers_width, i)
405 398 line = '%s%s%s %s' % (Colors.lineno, num,
406 399 Colors.Normal, line)
407 400
408 401 res.append(line)
409 402 if lvals and i == lnum:
410 403 res.append(lvals + '\n')
411 404 i = i + 1
412 405 return res
413 406
414 407 def is_recursion_error(etype, value, records):
415 408 try:
416 409 # RecursionError is new in Python 3.5
417 410 recursion_error_type = RecursionError
418 411 except NameError:
419 412 recursion_error_type = RuntimeError
420 413
421 414 # The default recursion limit is 1000, but some of that will be taken up
422 415 # by stack frames in IPython itself. >500 frames probably indicates
423 416 # a recursion error.
424 417 return (etype is recursion_error_type) \
425 418 and "recursion" in str(value).lower() \
426 419 and len(records) > 500
427 420
428 421 def find_recursion(etype, value, records):
429 422 """Identify the repeating stack frames from a RecursionError traceback
430 423
431 424 'records' is a list as returned by VerboseTB.get_records()
432 425
433 426 Returns (last_unique, repeat_length)
434 427 """
435 428 # This involves a bit of guesswork - we want to show enough of the traceback
436 429 # to indicate where the recursion is occurring. We guess that the innermost
437 430 # quarter of the traceback (250 frames by default) is repeats, and find the
438 431 # first frame (from in to out) that looks different.
439 432 if not is_recursion_error(etype, value, records):
440 433 return len(records), 0
441 434
442 435 # Select filename, lineno, func_name to track frames with
443 436 records = [r[1:4] for r in records]
444 437 inner_frames = records[-(len(records)//4):]
445 438 frames_repeated = set(inner_frames)
446 439
447 440 last_seen_at = {}
448 441 longest_repeat = 0
449 442 i = len(records)
450 443 for frame in reversed(records):
451 444 i -= 1
452 445 if frame not in frames_repeated:
453 446 last_unique = i
454 447 break
455 448
456 449 if frame in last_seen_at:
457 450 distance = last_seen_at[frame] - i
458 451 longest_repeat = max(longest_repeat, distance)
459 452
460 453 last_seen_at[frame] = i
461 454 else:
462 455 last_unique = 0 # The whole traceback was recursion
463 456
464 457 return last_unique, longest_repeat
465 458
466 459 #---------------------------------------------------------------------------
467 460 # Module classes
468 461 class TBTools(colorable.Colorable):
469 462 """Basic tools used by all traceback printer classes."""
470 463
471 464 # Number of frames to skip when reporting tracebacks
472 465 tb_offset = 0
473 466
474 467 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
475 468 # Whether to call the interactive pdb debugger after printing
476 469 # tracebacks or not
477 470 super(TBTools, self).__init__(parent=parent, config=config)
478 471 self.call_pdb = call_pdb
479 472
480 473 # Output stream to write to. Note that we store the original value in
481 474 # a private attribute and then make the public ostream a property, so
482 475 # that we can delay accessing sys.stdout until runtime. The way
483 476 # things are written now, the sys.stdout object is dynamically managed
484 477 # so a reference to it should NEVER be stored statically. This
485 478 # property approach confines this detail to a single location, and all
486 479 # subclasses can simply access self.ostream for writing.
487 480 self._ostream = ostream
488 481
489 482 # Create color table
490 483 self.color_scheme_table = exception_colors()
491 484
492 485 self.set_colors(color_scheme)
493 486 self.old_scheme = color_scheme # save initial value for toggles
494 487
495 488 if call_pdb:
496 489 self.pdb = debugger.Pdb()
497 490 else:
498 491 self.pdb = None
499 492
500 493 def _get_ostream(self):
501 494 """Output stream that exceptions are written to.
502 495
503 496 Valid values are:
504 497
505 498 - None: the default, which means that IPython will dynamically resolve
506 499 to sys.stdout. This ensures compatibility with most tools, including
507 500 Windows (where plain stdout doesn't recognize ANSI escapes).
508 501
509 502 - Any object with 'write' and 'flush' attributes.
510 503 """
511 504 return sys.stdout if self._ostream is None else self._ostream
512 505
513 506 def _set_ostream(self, val):
514 507 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
515 508 self._ostream = val
516 509
517 510 ostream = property(_get_ostream, _set_ostream)
518 511
519 512 def set_colors(self, *args, **kw):
520 513 """Shorthand access to the color table scheme selector method."""
521 514
522 515 # Set own color table
523 516 self.color_scheme_table.set_active_scheme(*args, **kw)
524 517 # for convenience, set Colors to the active scheme
525 518 self.Colors = self.color_scheme_table.active_colors
526 519 # Also set colors of debugger
527 520 if hasattr(self, 'pdb') and self.pdb is not None:
528 521 self.pdb.set_colors(*args, **kw)
529 522
530 523 def color_toggle(self):
531 524 """Toggle between the currently active color scheme and NoColor."""
532 525
533 526 if self.color_scheme_table.active_scheme_name == 'NoColor':
534 527 self.color_scheme_table.set_active_scheme(self.old_scheme)
535 528 self.Colors = self.color_scheme_table.active_colors
536 529 else:
537 530 self.old_scheme = self.color_scheme_table.active_scheme_name
538 531 self.color_scheme_table.set_active_scheme('NoColor')
539 532 self.Colors = self.color_scheme_table.active_colors
540 533
541 534 def stb2text(self, stb):
542 535 """Convert a structured traceback (a list) to a string."""
543 536 return '\n'.join(stb)
544 537
545 538 def text(self, etype, value, tb, tb_offset=None, context=5):
546 539 """Return formatted traceback.
547 540
548 541 Subclasses may override this if they add extra arguments.
549 542 """
550 543 tb_list = self.structured_traceback(etype, value, tb,
551 544 tb_offset, context)
552 545 return self.stb2text(tb_list)
553 546
554 547 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
555 548 context=5, mode=None):
556 549 """Return a list of traceback frames.
557 550
558 551 Must be implemented by each class.
559 552 """
560 553 raise NotImplementedError()
561 554
562 555
563 556 #---------------------------------------------------------------------------
564 557 class ListTB(TBTools):
565 558 """Print traceback information from a traceback list, with optional color.
566 559
567 560 Calling requires 3 arguments: (etype, evalue, elist)
568 561 as would be obtained by::
569 562
570 563 etype, evalue, tb = sys.exc_info()
571 564 if tb:
572 565 elist = traceback.extract_tb(tb)
573 566 else:
574 567 elist = None
575 568
576 569 It can thus be used by programs which need to process the traceback before
577 570 printing (such as console replacements based on the code module from the
578 571 standard library).
579 572
580 573 Because they are meant to be called without a full traceback (only a
581 574 list), instances of this class can't call the interactive pdb debugger."""
582 575
583 576 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
584 577 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
585 578 ostream=ostream, parent=parent,config=config)
586 579
587 580 def __call__(self, etype, value, elist):
588 581 self.ostream.flush()
589 582 self.ostream.write(self.text(etype, value, elist))
590 583 self.ostream.write('\n')
591 584
592 585 def structured_traceback(self, etype, value, elist, tb_offset=None,
593 586 context=5):
594 587 """Return a color formatted string with the traceback info.
595 588
596 589 Parameters
597 590 ----------
598 591 etype : exception type
599 592 Type of the exception raised.
600 593
601 594 value : object
602 595 Data stored in the exception
603 596
604 597 elist : list
605 598 List of frames, see class docstring for details.
606 599
607 600 tb_offset : int, optional
608 601 Number of frames in the traceback to skip. If not given, the
609 602 instance value is used (set in constructor).
610 603
611 604 context : int, optional
612 605 Number of lines of context information to print.
613 606
614 607 Returns
615 608 -------
616 609 String with formatted exception.
617 610 """
618 611 tb_offset = self.tb_offset if tb_offset is None else tb_offset
619 612 Colors = self.Colors
620 613 out_list = []
621 614 if elist:
622 615
623 616 if tb_offset and len(elist) > tb_offset:
624 617 elist = elist[tb_offset:]
625 618
626 619 out_list.append('Traceback %s(most recent call last)%s:' %
627 620 (Colors.normalEm, Colors.Normal) + '\n')
628 621 out_list.extend(self._format_list(elist))
629 622 # The exception info should be a single entry in the list.
630 623 lines = ''.join(self._format_exception_only(etype, value))
631 624 out_list.append(lines)
632 625
633 626 # Note: this code originally read:
634 627
635 628 ## for line in lines[:-1]:
636 629 ## out_list.append(" "+line)
637 630 ## out_list.append(lines[-1])
638 631
639 632 # This means it was indenting everything but the last line by a little
640 633 # bit. I've disabled this for now, but if we see ugliness somewhere we
641 634 # can restore it.
642 635
643 636 return out_list
644 637
645 638 def _format_list(self, extracted_list):
646 639 """Format a list of traceback entry tuples for printing.
647 640
648 641 Given a list of tuples as returned by extract_tb() or
649 642 extract_stack(), return a list of strings ready for printing.
650 643 Each string in the resulting list corresponds to the item with the
651 644 same index in the argument list. Each string ends in a newline;
652 645 the strings may contain internal newlines as well, for those items
653 646 whose source text line is not None.
654 647
655 648 Lifted almost verbatim from traceback.py
656 649 """
657 650
658 651 Colors = self.Colors
659 652 list = []
660 653 for filename, lineno, name, line in extracted_list[:-1]:
661 654 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
662 655 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
663 656 Colors.lineno, lineno, Colors.Normal,
664 657 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
665 658 if line:
666 659 item += ' %s\n' % line.strip()
667 660 list.append(item)
668 661 # Emphasize the last entry
669 662 filename, lineno, name, line = extracted_list[-1]
670 663 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
671 664 (Colors.normalEm,
672 665 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
673 666 Colors.linenoEm, lineno, Colors.normalEm,
674 667 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
675 668 Colors.Normal)
676 669 if line:
677 670 item += '%s %s%s\n' % (Colors.line, line.strip(),
678 671 Colors.Normal)
679 672 list.append(item)
680 673 return list
681 674
682 675 def _format_exception_only(self, etype, value):
683 676 """Format the exception part of a traceback.
684 677
685 678 The arguments are the exception type and value such as given by
686 679 sys.exc_info()[:2]. The return value is a list of strings, each ending
687 680 in a newline. Normally, the list contains a single string; however,
688 681 for SyntaxError exceptions, it contains several lines that (when
689 682 printed) display detailed information about where the syntax error
690 683 occurred. The message indicating which exception occurred is the
691 684 always last string in the list.
692 685
693 686 Also lifted nearly verbatim from traceback.py
694 687 """
695 688 have_filedata = False
696 689 Colors = self.Colors
697 690 list = []
698 691 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
699 692 if value is None:
700 693 # Not sure if this can still happen in Python 2.6 and above
701 694 list.append(stype + '\n')
702 695 else:
703 696 if issubclass(etype, SyntaxError):
704 697 have_filedata = True
705 698 if not value.filename: value.filename = "<string>"
706 699 if value.lineno:
707 700 lineno = value.lineno
708 701 textline = linecache.getline(value.filename, value.lineno)
709 702 else:
710 703 lineno = 'unknown'
711 704 textline = ''
712 705 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
713 706 (Colors.normalEm,
714 707 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
715 708 Colors.linenoEm, lineno, Colors.Normal ))
716 709 if textline == '':
717 710 textline = py3compat.cast_unicode(value.text, "utf-8")
718 711
719 712 if textline is not None:
720 713 i = 0
721 714 while i < len(textline) and textline[i].isspace():
722 715 i += 1
723 716 list.append('%s %s%s\n' % (Colors.line,
724 717 textline.strip(),
725 718 Colors.Normal))
726 719 if value.offset is not None:
727 720 s = ' '
728 721 for c in textline[i:value.offset - 1]:
729 722 if c.isspace():
730 723 s += c
731 724 else:
732 725 s += ' '
733 726 list.append('%s%s^%s\n' % (Colors.caret, s,
734 727 Colors.Normal))
735 728
736 729 try:
737 730 s = value.msg
738 731 except Exception:
739 732 s = self._some_str(value)
740 733 if s:
741 734 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
742 735 Colors.Normal, s))
743 736 else:
744 737 list.append('%s\n' % stype)
745 738
746 739 # sync with user hooks
747 740 if have_filedata:
748 741 ipinst = get_ipython()
749 742 if ipinst is not None:
750 743 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
751 744
752 745 return list
753 746
754 747 def get_exception_only(self, etype, value):
755 748 """Only print the exception type and message, without a traceback.
756 749
757 750 Parameters
758 751 ----------
759 752 etype : exception type
760 753 value : exception value
761 754 """
762 755 return ListTB.structured_traceback(self, etype, value, [])
763 756
764 757 def show_exception_only(self, etype, evalue):
765 758 """Only print the exception type and message, without a traceback.
766 759
767 760 Parameters
768 761 ----------
769 762 etype : exception type
770 763 value : exception value
771 764 """
772 765 # This method needs to use __call__ from *this* class, not the one from
773 766 # a subclass whose signature or behavior may be different
774 767 ostream = self.ostream
775 768 ostream.flush()
776 769 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
777 770 ostream.flush()
778 771
779 772 def _some_str(self, value):
780 773 # Lifted from traceback.py
781 774 try:
782 775 return py3compat.cast_unicode(str(value))
783 776 except:
784 777 return u'<unprintable %s object>' % type(value).__name__
785 778
786 779
787 780 #----------------------------------------------------------------------------
788 781 class VerboseTB(TBTools):
789 782 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
790 783 of HTML. Requires inspect and pydoc. Crazy, man.
791 784
792 785 Modified version which optionally strips the topmost entries from the
793 786 traceback, to be used with alternate interpreters (because their own code
794 787 would appear in the traceback)."""
795 788
796 789 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
797 790 tb_offset=0, long_header=False, include_vars=True,
798 791 check_cache=None, debugger_cls = None,
799 792 parent=None, config=None):
800 793 """Specify traceback offset, headers and color scheme.
801 794
802 795 Define how many frames to drop from the tracebacks. Calling it with
803 796 tb_offset=1 allows use of this handler in interpreters which will have
804 797 their own code at the top of the traceback (VerboseTB will first
805 798 remove that frame before printing the traceback info)."""
806 799 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
807 800 ostream=ostream, parent=parent, config=config)
808 801 self.tb_offset = tb_offset
809 802 self.long_header = long_header
810 803 self.include_vars = include_vars
811 804 # By default we use linecache.checkcache, but the user can provide a
812 805 # different check_cache implementation. This is used by the IPython
813 806 # kernel to provide tracebacks for interactive code that is cached,
814 807 # by a compiler instance that flushes the linecache but preserves its
815 808 # own code cache.
816 809 if check_cache is None:
817 810 check_cache = linecache.checkcache
818 811 self.check_cache = check_cache
819 812
820 813 self.debugger_cls = debugger_cls or debugger.Pdb
821 814
822 815 def format_records(self, records, last_unique, recursion_repeat):
823 816 """Format the stack frames of the traceback"""
824 817 frames = []
825 818 for r in records[:last_unique+recursion_repeat+1]:
826 819 #print '*** record:',file,lnum,func,lines,index # dbg
827 820 frames.append(self.format_record(*r))
828 821
829 822 if recursion_repeat:
830 823 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
831 824 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
832 825
833 826 return frames
834 827
835 828 def format_record(self, frame, file, lnum, func, lines, index):
836 829 """Format a single stack frame"""
837 830 Colors = self.Colors # just a shorthand + quicker name lookup
838 831 ColorsNormal = Colors.Normal # used a lot
839 832 col_scheme = self.color_scheme_table.active_scheme_name
840 833 indent = ' ' * INDENT_SIZE
841 834 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
842 835 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
843 836 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
844 837 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
845 838 ColorsNormal)
846 839 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
847 840 (Colors.vName, Colors.valEm, ColorsNormal)
848 841 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
849 842 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
850 843 Colors.vName, ColorsNormal)
851 844 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
852 845
853 846 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
854 847 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
855 848 ColorsNormal)
856 849
857 850 abspath = os.path.abspath
858 851
859 852
860 853 if not file:
861 854 file = '?'
862 855 elif file.startswith(str("<")) and file.endswith(str(">")):
863 856 # Not a real filename, no problem...
864 857 pass
865 858 elif not os.path.isabs(file):
866 859 # Try to make the filename absolute by trying all
867 860 # sys.path entries (which is also what linecache does)
868 861 for dirname in sys.path:
869 862 try:
870 863 fullname = os.path.join(dirname, file)
871 864 if os.path.isfile(fullname):
872 865 file = os.path.abspath(fullname)
873 866 break
874 867 except Exception:
875 868 # Just in case that sys.path contains very
876 869 # strange entries...
877 870 pass
878 871
879 872 file = py3compat.cast_unicode(file, util_path.fs_encoding)
880 873 link = tpl_link % file
881 args, varargs, varkw, locals = fixed_getargvalues(frame)
874 args, varargs, varkw, locals = inspect.getargvalues(frame)
882 875
883 876 if func == '?':
884 877 call = ''
885 878 else:
886 879 # Decide whether to include variable details or not
887 880 var_repr = self.include_vars and eqrepr or nullrepr
888 881 try:
889 882 call = tpl_call % (func, inspect.formatargvalues(args,
890 883 varargs, varkw,
891 884 locals, formatvalue=var_repr))
892 885 except KeyError:
893 886 # This happens in situations like errors inside generator
894 887 # expressions, where local variables are listed in the
895 888 # line, but can't be extracted from the frame. I'm not
896 889 # 100% sure this isn't actually a bug in inspect itself,
897 890 # but since there's no info for us to compute with, the
898 891 # best we can do is report the failure and move on. Here
899 892 # we must *not* call any traceback construction again,
900 893 # because that would mess up use of %debug later on. So we
901 894 # simply report the failure and move on. The only
902 895 # limitation will be that this frame won't have locals
903 896 # listed in the call signature. Quite subtle problem...
904 897 # I can't think of a good way to validate this in a unit
905 898 # test, but running a script consisting of:
906 899 # dict( (k,v.strip()) for (k,v) in range(10) )
907 900 # will illustrate the error, if this exception catch is
908 901 # disabled.
909 902 call = tpl_call_fail % func
910 903
911 904 # Don't attempt to tokenize binary files.
912 905 if file.endswith(('.so', '.pyd', '.dll')):
913 906 return '%s %s\n' % (link, call)
914 907
915 908 elif file.endswith(('.pyc', '.pyo')):
916 909 # Look up the corresponding source file.
917 910 try:
918 911 file = openpy.source_from_cache(file)
919 912 except ValueError:
920 913 # Failed to get the source file for some reason
921 914 # E.g. https://github.com/ipython/ipython/issues/9486
922 915 return '%s %s\n' % (link, call)
923 916
924 917 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
925 918 line = getline(file, lnum[0])
926 919 lnum[0] += 1
927 920 return line
928 921
929 922 # Build the list of names on this line of code where the exception
930 923 # occurred.
931 924 try:
932 925 names = []
933 926 name_cont = False
934 927
935 928 for token_type, token, start, end, line in generate_tokens(linereader):
936 929 # build composite names
937 930 if token_type == tokenize.NAME and token not in keyword.kwlist:
938 931 if name_cont:
939 932 # Continuation of a dotted name
940 933 try:
941 934 names[-1].append(token)
942 935 except IndexError:
943 936 names.append([token])
944 937 name_cont = False
945 938 else:
946 939 # Regular new names. We append everything, the caller
947 940 # will be responsible for pruning the list later. It's
948 941 # very tricky to try to prune as we go, b/c composite
949 942 # names can fool us. The pruning at the end is easy
950 943 # to do (or the caller can print a list with repeated
951 944 # names if so desired.
952 945 names.append([token])
953 946 elif token == '.':
954 947 name_cont = True
955 948 elif token_type == tokenize.NEWLINE:
956 949 break
957 950
958 951 except (IndexError, UnicodeDecodeError, SyntaxError):
959 952 # signals exit of tokenizer
960 953 # SyntaxError can occur if the file is not actually Python
961 954 # - see gh-6300
962 955 pass
963 956 except tokenize.TokenError as msg:
964 957 _m = ("An unexpected error occurred while tokenizing input\n"
965 958 "The following traceback may be corrupted or invalid\n"
966 959 "The error message is: %s\n" % msg)
967 960 error(_m)
968 961
969 962 # Join composite names (e.g. "dict.fromkeys")
970 963 names = ['.'.join(n) for n in names]
971 964 # prune names list of duplicates, but keep the right order
972 965 unique_names = uniq_stable(names)
973 966
974 967 # Start loop over vars
975 968 lvals = []
976 969 if self.include_vars:
977 970 for name_full in unique_names:
978 971 name_base = name_full.split('.', 1)[0]
979 972 if name_base in frame.f_code.co_varnames:
980 973 if name_base in locals:
981 974 try:
982 975 value = repr(eval(name_full, locals))
983 976 except:
984 977 value = undefined
985 978 else:
986 979 value = undefined
987 980 name = tpl_local_var % name_full
988 981 else:
989 982 if name_base in frame.f_globals:
990 983 try:
991 984 value = repr(eval(name_full, frame.f_globals))
992 985 except:
993 986 value = undefined
994 987 else:
995 988 value = undefined
996 989 name = tpl_global_var % name_full
997 990 lvals.append(tpl_name_val % (name, value))
998 991 if lvals:
999 992 lvals = '%s%s' % (indent, em_normal.join(lvals))
1000 993 else:
1001 994 lvals = ''
1002 995
1003 996 level = '%s %s\n' % (link, call)
1004 997
1005 998 if index is None:
1006 999 return level
1007 1000 else:
1008 1001 _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2
1009 1002 return '%s%s' % (level, ''.join(
1010 1003 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1011 1004 _line_format)))
1012 1005
1013 1006 def prepare_chained_exception_message(self, cause):
1014 1007 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1015 1008 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1016 1009
1017 1010 if cause:
1018 1011 message = [[direct_cause]]
1019 1012 else:
1020 1013 message = [[exception_during_handling]]
1021 1014 return message
1022 1015
1023 1016 def prepare_header(self, etype, long_version=False):
1024 1017 colors = self.Colors # just a shorthand + quicker name lookup
1025 1018 colorsnormal = colors.Normal # used a lot
1026 1019 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1027 1020 width = min(75, get_terminal_size()[0])
1028 1021 if long_version:
1029 1022 # Header with the exception type, python version, and date
1030 1023 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1031 1024 date = time.ctime(time.time())
1032 1025
1033 1026 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
1034 1027 exc, ' ' * (width - len(str(etype)) - len(pyver)),
1035 1028 pyver, date.rjust(width) )
1036 1029 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1037 1030 "\ncalls leading up to the error, with the most recent (innermost) call last."
1038 1031 else:
1039 1032 # Simplified header
1040 1033 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1041 1034 rjust(width - len(str(etype))) )
1042 1035
1043 1036 return head
1044 1037
1045 1038 def format_exception(self, etype, evalue):
1046 1039 colors = self.Colors # just a shorthand + quicker name lookup
1047 1040 colorsnormal = colors.Normal # used a lot
1048 1041 indent = ' ' * INDENT_SIZE
1049 1042 # Get (safely) a string form of the exception info
1050 1043 try:
1051 1044 etype_str, evalue_str = map(str, (etype, evalue))
1052 1045 except:
1053 1046 # User exception is improperly defined.
1054 1047 etype, evalue = str, sys.exc_info()[:2]
1055 1048 etype_str, evalue_str = map(str, (etype, evalue))
1056 1049 # ... and format it
1057 1050 return ['%s%s%s: %s' % (colors.excName, etype_str,
1058 1051 colorsnormal, py3compat.cast_unicode(evalue_str))]
1059 1052
1060 1053 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1061 1054 """Formats the header, traceback and exception message for a single exception.
1062 1055
1063 1056 This may be called multiple times by Python 3 exception chaining
1064 1057 (PEP 3134).
1065 1058 """
1066 1059 # some locals
1067 1060 orig_etype = etype
1068 1061 try:
1069 1062 etype = etype.__name__
1070 1063 except AttributeError:
1071 1064 pass
1072 1065
1073 1066 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1074 1067 head = self.prepare_header(etype, self.long_header)
1075 1068 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1076 1069
1077 1070 if records is None:
1078 1071 return ""
1079 1072
1080 1073 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1081 1074
1082 1075 frames = self.format_records(records, last_unique, recursion_repeat)
1083 1076
1084 1077 formatted_exception = self.format_exception(etype, evalue)
1085 1078 if records:
1086 1079 filepath, lnum = records[-1][1:3]
1087 1080 filepath = os.path.abspath(filepath)
1088 1081 ipinst = get_ipython()
1089 1082 if ipinst is not None:
1090 1083 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1091 1084
1092 1085 return [[head] + frames + [''.join(formatted_exception[0])]]
1093 1086
1094 1087 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1095 1088 try:
1096 1089 # Try the default getinnerframes and Alex's: Alex's fixes some
1097 1090 # problems, but it generates empty tracebacks for console errors
1098 1091 # (5 blanks lines) where none should be returned.
1099 1092 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1100 1093 except UnicodeDecodeError:
1101 1094 # This can occur if a file's encoding magic comment is wrong.
1102 1095 # I can't see a way to recover without duplicating a bunch of code
1103 1096 # from the stdlib traceback module. --TK
1104 1097 error('\nUnicodeDecodeError while processing traceback.\n')
1105 1098 return None
1106 1099 except:
1107 1100 # FIXME: I've been getting many crash reports from python 2.3
1108 1101 # users, traceable to inspect.py. If I can find a small test-case
1109 1102 # to reproduce this, I should either write a better workaround or
1110 1103 # file a bug report against inspect (if that's the real problem).
1111 1104 # So far, I haven't been able to find an isolated example to
1112 1105 # reproduce the problem.
1113 1106 inspect_error()
1114 1107 traceback.print_exc(file=self.ostream)
1115 1108 info('\nUnfortunately, your original traceback can not be constructed.\n')
1116 1109 return None
1117 1110
1118 1111 def get_parts_of_chained_exception(self, evalue):
1119 1112 def get_chained_exception(exception_value):
1120 1113 cause = getattr(exception_value, '__cause__', None)
1121 1114 if cause:
1122 1115 return cause
1123 1116 if getattr(exception_value, '__suppress_context__', False):
1124 1117 return None
1125 1118 return getattr(exception_value, '__context__', None)
1126 1119
1127 1120 chained_evalue = get_chained_exception(evalue)
1128 1121
1129 1122 if chained_evalue:
1130 1123 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1131 1124
1132 1125 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1133 1126 number_of_lines_of_context=5):
1134 1127 """Return a nice text document describing the traceback."""
1135 1128
1136 1129 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1137 1130 tb_offset)
1138 1131
1139 1132 colors = self.Colors # just a shorthand + quicker name lookup
1140 1133 colorsnormal = colors.Normal # used a lot
1141 1134 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1142 1135 structured_traceback_parts = [head]
1143 1136 if py3compat.PY3:
1144 1137 chained_exceptions_tb_offset = 0
1145 1138 lines_of_context = 3
1146 1139 formatted_exceptions = formatted_exception
1147 1140 exception = self.get_parts_of_chained_exception(evalue)
1148 1141 if exception:
1149 1142 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1150 1143 etype, evalue, etb = exception
1151 1144 else:
1152 1145 evalue = None
1153 1146 chained_exc_ids = set()
1154 1147 while evalue:
1155 1148 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1156 1149 chained_exceptions_tb_offset)
1157 1150 exception = self.get_parts_of_chained_exception(evalue)
1158 1151
1159 1152 if exception and not id(exception[1]) in chained_exc_ids:
1160 1153 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1161 1154 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1162 1155 etype, evalue, etb = exception
1163 1156 else:
1164 1157 evalue = None
1165 1158
1166 1159 # we want to see exceptions in a reversed order:
1167 1160 # the first exception should be on top
1168 1161 for formatted_exception in reversed(formatted_exceptions):
1169 1162 structured_traceback_parts += formatted_exception
1170 1163 else:
1171 1164 structured_traceback_parts += formatted_exception[0]
1172 1165
1173 1166 return structured_traceback_parts
1174 1167
1175 1168 def debugger(self, force=False):
1176 1169 """Call up the pdb debugger if desired, always clean up the tb
1177 1170 reference.
1178 1171
1179 1172 Keywords:
1180 1173
1181 1174 - force(False): by default, this routine checks the instance call_pdb
1182 1175 flag and does not actually invoke the debugger if the flag is false.
1183 1176 The 'force' option forces the debugger to activate even if the flag
1184 1177 is false.
1185 1178
1186 1179 If the call_pdb flag is set, the pdb interactive debugger is
1187 1180 invoked. In all cases, the self.tb reference to the current traceback
1188 1181 is deleted to prevent lingering references which hamper memory
1189 1182 management.
1190 1183
1191 1184 Note that each call to pdb() does an 'import readline', so if your app
1192 1185 requires a special setup for the readline completers, you'll have to
1193 1186 fix that by hand after invoking the exception handler."""
1194 1187
1195 1188 if force or self.call_pdb:
1196 1189 if self.pdb is None:
1197 1190 self.pdb = self.debugger_cls()
1198 1191 # the system displayhook may have changed, restore the original
1199 1192 # for pdb
1200 1193 display_trap = DisplayTrap(hook=sys.__displayhook__)
1201 1194 with display_trap:
1202 1195 self.pdb.reset()
1203 1196 # Find the right frame so we don't pop up inside ipython itself
1204 1197 if hasattr(self, 'tb') and self.tb is not None:
1205 1198 etb = self.tb
1206 1199 else:
1207 1200 etb = self.tb = sys.last_traceback
1208 1201 while self.tb is not None and self.tb.tb_next is not None:
1209 1202 self.tb = self.tb.tb_next
1210 1203 if etb and etb.tb_next:
1211 1204 etb = etb.tb_next
1212 1205 self.pdb.botframe = etb.tb_frame
1213 1206 self.pdb.interaction(self.tb.tb_frame, self.tb)
1214 1207
1215 1208 if hasattr(self, 'tb'):
1216 1209 del self.tb
1217 1210
1218 1211 def handler(self, info=None):
1219 1212 (etype, evalue, etb) = info or sys.exc_info()
1220 1213 self.tb = etb
1221 1214 ostream = self.ostream
1222 1215 ostream.flush()
1223 1216 ostream.write(self.text(etype, evalue, etb))
1224 1217 ostream.write('\n')
1225 1218 ostream.flush()
1226 1219
1227 1220 # Changed so an instance can just be called as VerboseTB_inst() and print
1228 1221 # out the right info on its own.
1229 1222 def __call__(self, etype=None, evalue=None, etb=None):
1230 1223 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1231 1224 if etb is None:
1232 1225 self.handler()
1233 1226 else:
1234 1227 self.handler((etype, evalue, etb))
1235 1228 try:
1236 1229 self.debugger()
1237 1230 except KeyboardInterrupt:
1238 1231 print("\nKeyboardInterrupt")
1239 1232
1240 1233
1241 1234 #----------------------------------------------------------------------------
1242 1235 class FormattedTB(VerboseTB, ListTB):
1243 1236 """Subclass ListTB but allow calling with a traceback.
1244 1237
1245 1238 It can thus be used as a sys.excepthook for Python > 2.1.
1246 1239
1247 1240 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1248 1241
1249 1242 Allows a tb_offset to be specified. This is useful for situations where
1250 1243 one needs to remove a number of topmost frames from the traceback (such as
1251 1244 occurs with python programs that themselves execute other python code,
1252 1245 like Python shells). """
1253 1246
1254 1247 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1255 1248 ostream=None,
1256 1249 tb_offset=0, long_header=False, include_vars=False,
1257 1250 check_cache=None, debugger_cls=None,
1258 1251 parent=None, config=None):
1259 1252
1260 1253 # NEVER change the order of this list. Put new modes at the end:
1261 1254 self.valid_modes = ['Plain', 'Context', 'Verbose']
1262 1255 self.verbose_modes = self.valid_modes[1:3]
1263 1256
1264 1257 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1265 1258 ostream=ostream, tb_offset=tb_offset,
1266 1259 long_header=long_header, include_vars=include_vars,
1267 1260 check_cache=check_cache, debugger_cls=debugger_cls,
1268 1261 parent=parent, config=config)
1269 1262
1270 1263 # Different types of tracebacks are joined with different separators to
1271 1264 # form a single string. They are taken from this dict
1272 1265 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1273 1266 # set_mode also sets the tb_join_char attribute
1274 1267 self.set_mode(mode)
1275 1268
1276 1269 def _extract_tb(self, tb):
1277 1270 if tb:
1278 1271 return traceback.extract_tb(tb)
1279 1272 else:
1280 1273 return None
1281 1274
1282 1275 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1283 1276 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1284 1277 mode = self.mode
1285 1278 if mode in self.verbose_modes:
1286 1279 # Verbose modes need a full traceback
1287 1280 return VerboseTB.structured_traceback(
1288 1281 self, etype, value, tb, tb_offset, number_of_lines_of_context
1289 1282 )
1290 1283 else:
1291 1284 # We must check the source cache because otherwise we can print
1292 1285 # out-of-date source code.
1293 1286 self.check_cache()
1294 1287 # Now we can extract and format the exception
1295 1288 elist = self._extract_tb(tb)
1296 1289 return ListTB.structured_traceback(
1297 1290 self, etype, value, elist, tb_offset, number_of_lines_of_context
1298 1291 )
1299 1292
1300 1293 def stb2text(self, stb):
1301 1294 """Convert a structured traceback (a list) to a string."""
1302 1295 return self.tb_join_char.join(stb)
1303 1296
1304 1297
1305 1298 def set_mode(self, mode=None):
1306 1299 """Switch to the desired mode.
1307 1300
1308 1301 If mode is not specified, cycles through the available modes."""
1309 1302
1310 1303 if not mode:
1311 1304 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1312 1305 len(self.valid_modes)
1313 1306 self.mode = self.valid_modes[new_idx]
1314 1307 elif mode not in self.valid_modes:
1315 1308 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1316 1309 'Valid modes: ' + str(self.valid_modes))
1317 1310 else:
1318 1311 self.mode = mode
1319 1312 # include variable details only in 'Verbose' mode
1320 1313 self.include_vars = (self.mode == self.valid_modes[2])
1321 1314 # Set the join character for generating text tracebacks
1322 1315 self.tb_join_char = self._join_chars[self.mode]
1323 1316
1324 1317 # some convenient shortcuts
1325 1318 def plain(self):
1326 1319 self.set_mode(self.valid_modes[0])
1327 1320
1328 1321 def context(self):
1329 1322 self.set_mode(self.valid_modes[1])
1330 1323
1331 1324 def verbose(self):
1332 1325 self.set_mode(self.valid_modes[2])
1333 1326
1334 1327
1335 1328 #----------------------------------------------------------------------------
1336 1329 class AutoFormattedTB(FormattedTB):
1337 1330 """A traceback printer which can be called on the fly.
1338 1331
1339 1332 It will find out about exceptions by itself.
1340 1333
1341 1334 A brief example::
1342 1335
1343 1336 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1344 1337 try:
1345 1338 ...
1346 1339 except:
1347 1340 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1348 1341 """
1349 1342
1350 1343 def __call__(self, etype=None, evalue=None, etb=None,
1351 1344 out=None, tb_offset=None):
1352 1345 """Print out a formatted exception traceback.
1353 1346
1354 1347 Optional arguments:
1355 1348 - out: an open file-like object to direct output to.
1356 1349
1357 1350 - tb_offset: the number of frames to skip over in the stack, on a
1358 1351 per-call basis (this overrides temporarily the instance's tb_offset
1359 1352 given at initialization time. """
1360 1353
1361 1354 if out is None:
1362 1355 out = self.ostream
1363 1356 out.flush()
1364 1357 out.write(self.text(etype, evalue, etb, tb_offset))
1365 1358 out.write('\n')
1366 1359 out.flush()
1367 1360 # FIXME: we should remove the auto pdb behavior from here and leave
1368 1361 # that to the clients.
1369 1362 try:
1370 1363 self.debugger()
1371 1364 except KeyboardInterrupt:
1372 1365 print("\nKeyboardInterrupt")
1373 1366
1374 1367 def structured_traceback(self, etype=None, value=None, tb=None,
1375 1368 tb_offset=None, number_of_lines_of_context=5):
1376 1369 if etype is None:
1377 1370 etype, value, tb = sys.exc_info()
1378 1371 self.tb = tb
1379 1372 return FormattedTB.structured_traceback(
1380 1373 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1381 1374
1382 1375
1383 1376 #---------------------------------------------------------------------------
1384 1377
1385 1378 # A simple class to preserve Nathan's original functionality.
1386 1379 class ColorTB(FormattedTB):
1387 1380 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1388 1381
1389 1382 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1390 1383 FormattedTB.__init__(self, color_scheme=color_scheme,
1391 1384 call_pdb=call_pdb, **kwargs)
1392 1385
1393 1386
1394 1387 class SyntaxTB(ListTB):
1395 1388 """Extension which holds some state: the last exception value"""
1396 1389
1397 1390 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1398 1391 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1399 1392 self.last_syntax_error = None
1400 1393
1401 1394 def __call__(self, etype, value, elist):
1402 1395 self.last_syntax_error = value
1403 1396
1404 1397 ListTB.__call__(self, etype, value, elist)
1405 1398
1406 1399 def structured_traceback(self, etype, value, elist, tb_offset=None,
1407 1400 context=5):
1408 1401 # If the source file has been edited, the line in the syntax error can
1409 1402 # be wrong (retrieved from an outdated cache). This replaces it with
1410 1403 # the current value.
1411 1404 if isinstance(value, SyntaxError) \
1412 1405 and isinstance(value.filename, str) \
1413 1406 and isinstance(value.lineno, int):
1414 1407 linecache.checkcache(value.filename)
1415 1408 newtext = linecache.getline(value.filename, value.lineno)
1416 1409 if newtext:
1417 1410 value.text = newtext
1418 1411 self.last_syntax_error = value
1419 1412 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1420 1413 tb_offset=tb_offset, context=context)
1421 1414
1422 1415 def clear_err_state(self):
1423 1416 """Return the current error state and clear it"""
1424 1417 e = self.last_syntax_error
1425 1418 self.last_syntax_error = None
1426 1419 return e
1427 1420
1428 1421 def stb2text(self, stb):
1429 1422 """Convert a structured traceback (a list) to a string."""
1430 1423 return ''.join(stb)
1431 1424
1432 1425
1433 1426 # some internal-use functions
1434 1427 def text_repr(value):
1435 1428 """Hopefully pretty robust repr equivalent."""
1436 1429 # this is pretty horrible but should always return *something*
1437 1430 try:
1438 1431 return pydoc.text.repr(value)
1439 1432 except KeyboardInterrupt:
1440 1433 raise
1441 1434 except:
1442 1435 try:
1443 1436 return repr(value)
1444 1437 except KeyboardInterrupt:
1445 1438 raise
1446 1439 except:
1447 1440 try:
1448 1441 # all still in an except block so we catch
1449 1442 # getattr raising
1450 1443 name = getattr(value, '__name__', None)
1451 1444 if name:
1452 1445 # ick, recursion
1453 1446 return text_repr(name)
1454 1447 klass = getattr(value, '__class__', None)
1455 1448 if klass:
1456 1449 return '%s instance' % text_repr(klass)
1457 1450 except KeyboardInterrupt:
1458 1451 raise
1459 1452 except:
1460 1453 return 'UNRECOVERABLE REPR FAILURE'
1461 1454
1462 1455
1463 1456 def eqrepr(value, repr=text_repr):
1464 1457 return '=%s' % repr(value)
1465 1458
1466 1459
1467 1460 def nullrepr(value, repr=text_repr):
1468 1461 return ''
@@ -1,108 +1,106 b''
1 1 """prompt-toolkit utilities
2 2
3 3 Everything in this module is a private API,
4 4 not to be used outside IPython.
5 5 """
6 6
7 7 # Copyright (c) IPython Development Team.
8 8 # Distributed under the terms of the Modified BSD License.
9 9
10 10 import unicodedata
11 11 from wcwidth import wcwidth
12 12
13 from IPython.utils.py3compat import PY3
14
15 13 from IPython.core.completer import IPCompleter
16 14 from prompt_toolkit.completion import Completer, Completion
17 15 from prompt_toolkit.layout.lexers import Lexer
18 16 from prompt_toolkit.layout.lexers import PygmentsLexer
19 17
20 18 import pygments.lexers as pygments_lexers
21 19
22 20
23 21 class IPythonPTCompleter(Completer):
24 22 """Adaptor to provide IPython completions to prompt_toolkit"""
25 23 def __init__(self, ipy_completer=None, shell=None):
26 24 if shell is None and ipy_completer is None:
27 25 raise TypeError("Please pass shell=an InteractiveShell instance.")
28 26 self._ipy_completer = ipy_completer
29 27 self.shell = shell
30 28
31 29 @property
32 30 def ipy_completer(self):
33 31 if self._ipy_completer:
34 32 return self._ipy_completer
35 33 else:
36 34 return self.shell.Completer
37 35
38 36 def get_completions(self, document, complete_event):
39 37 if not document.current_line.strip():
40 38 return
41 39
42 40 used, matches = self.ipy_completer.complete(
43 41 line_buffer=document.current_line,
44 42 cursor_pos=document.cursor_position_col
45 43 )
46 44 start_pos = -len(used)
47 45 for m in matches:
48 46 if not m:
49 47 # Guard against completion machinery giving us an empty string.
50 48 continue
51 49
52 50 m = unicodedata.normalize('NFC', m)
53 51
54 52 # When the first character of the completion has a zero length,
55 53 # then it's probably a decomposed unicode character. E.g. caused by
56 54 # the "\dot" completion. Try to compose again with the previous
57 55 # character.
58 56 if wcwidth(m[0]) == 0:
59 57 if document.cursor_position + start_pos > 0:
60 58 char_before = document.text[document.cursor_position + start_pos - 1]
61 59 m = unicodedata.normalize('NFC', char_before + m)
62 60
63 61 # Yield the modified completion instead, if this worked.
64 62 if wcwidth(m[0:1]) == 1:
65 63 yield Completion(m, start_position=start_pos - 1)
66 64 continue
67 65
68 66 # TODO: Use Jedi to determine meta_text
69 67 # (Jedi currently has a bug that results in incorrect information.)
70 68 # meta_text = ''
71 69 # yield Completion(m, start_position=start_pos,
72 70 # display_meta=meta_text)
73 71 yield Completion(m, start_position=start_pos)
74 72
75 73 class IPythonPTLexer(Lexer):
76 74 """
77 75 Wrapper around PythonLexer and BashLexer.
78 76 """
79 77 def __init__(self):
80 78 l = pygments_lexers
81 self.python_lexer = PygmentsLexer(l.Python3Lexer if PY3 else l.PythonLexer)
79 self.python_lexer = PygmentsLexer(l.Python3Lexer)
82 80 self.shell_lexer = PygmentsLexer(l.BashLexer)
83 81
84 82 self.magic_lexers = {
85 83 'HTML': PygmentsLexer(l.HtmlLexer),
86 84 'html': PygmentsLexer(l.HtmlLexer),
87 85 'javascript': PygmentsLexer(l.JavascriptLexer),
88 86 'js': PygmentsLexer(l.JavascriptLexer),
89 87 'perl': PygmentsLexer(l.PerlLexer),
90 88 'ruby': PygmentsLexer(l.RubyLexer),
91 89 'latex': PygmentsLexer(l.TexLexer),
92 90 }
93 91
94 92 def lex_document(self, cli, document):
95 93 text = document.text.lstrip()
96 94
97 95 lexer = self.python_lexer
98 96
99 97 if text.startswith('!') or text.startswith('%%bash'):
100 98 lexer = self.shell_lexer
101 99
102 100 elif text.startswith('%%'):
103 101 for magic, l in self.magic_lexers.items():
104 102 if text.startswith('%%' + magic):
105 103 lexer = l
106 104 break
107 105
108 106 return lexer.lex_document(cli, document)
@@ -1,324 +1,318 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Class and program to colorize python source code for ANSI terminals.
4 4
5 5 Based on an HTML code highlighter by Jurgen Hermann found at:
6 6 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
7 7
8 8 Modifications by Fernando Perez (fperez@colorado.edu).
9 9
10 10 Information on the original HTML highlighter follows:
11 11
12 12 MoinMoin - Python Source Parser
13 13
14 14 Title: Colorize Python source using the built-in tokenizer
15 15
16 16 Submitter: Jurgen Hermann
17 17 Last Updated:2001/04/06
18 18
19 19 Version no:1.2
20 20
21 21 Description:
22 22
23 23 This code is part of MoinMoin (http://moin.sourceforge.net/) and converts
24 24 Python source code to HTML markup, rendering comments, keywords,
25 25 operators, numeric and string literals in different colors.
26 26
27 27 It shows how to use the built-in keyword, token and tokenize modules to
28 28 scan Python source code and re-emit it with no changes to its original
29 29 formatting (which is the hard part).
30 30 """
31 31
32 32 __all__ = ['ANSICodeColors','Parser']
33 33
34 34 _scheme_default = 'Linux'
35 35
36 36
37 37 # Imports
38 38 import keyword
39 39 import os
40 40 import sys
41 41 import token
42 42 import tokenize
43 43
44 44 generate_tokens = tokenize.generate_tokens
45 45
46 46 from IPython.utils.coloransi import TermColors, InputTermColors ,ColorScheme, ColorSchemeTable
47 from IPython.utils.py3compat import PY3
48
49 47 from .colorable import Colorable
50
51 if PY3:
52 48 from io import StringIO
53 else:
54 from StringIO import StringIO
55 49
56 50 #############################################################################
57 51 ### Python Source Parser (does Highlighting)
58 52 #############################################################################
59 53
60 54 _KEYWORD = token.NT_OFFSET + 1
61 55 _TEXT = token.NT_OFFSET + 2
62 56
63 57 #****************************************************************************
64 58 # Builtin color schemes
65 59
66 60 Colors = TermColors # just a shorthand
67 61
68 62 # Build a few color schemes
69 63 NoColor = ColorScheme(
70 64 'NoColor',{
71 65 'header' : Colors.NoColor,
72 66 token.NUMBER : Colors.NoColor,
73 67 token.OP : Colors.NoColor,
74 68 token.STRING : Colors.NoColor,
75 69 tokenize.COMMENT : Colors.NoColor,
76 70 token.NAME : Colors.NoColor,
77 71 token.ERRORTOKEN : Colors.NoColor,
78 72
79 73 _KEYWORD : Colors.NoColor,
80 74 _TEXT : Colors.NoColor,
81 75
82 76 'in_prompt' : InputTermColors.NoColor, # Input prompt
83 77 'in_number' : InputTermColors.NoColor, # Input prompt number
84 78 'in_prompt2' : InputTermColors.NoColor, # Continuation prompt
85 79 'in_normal' : InputTermColors.NoColor, # color off (usu. Colors.Normal)
86 80
87 81 'out_prompt' : Colors.NoColor, # Output prompt
88 82 'out_number' : Colors.NoColor, # Output prompt number
89 83
90 84 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
91 85 } )
92 86
93 87 LinuxColors = ColorScheme(
94 88 'Linux',{
95 89 'header' : Colors.LightRed,
96 90 token.NUMBER : Colors.LightCyan,
97 91 token.OP : Colors.Yellow,
98 92 token.STRING : Colors.LightBlue,
99 93 tokenize.COMMENT : Colors.LightRed,
100 94 token.NAME : Colors.Normal,
101 95 token.ERRORTOKEN : Colors.Red,
102 96
103 97 _KEYWORD : Colors.LightGreen,
104 98 _TEXT : Colors.Yellow,
105 99
106 100 'in_prompt' : InputTermColors.Green,
107 101 'in_number' : InputTermColors.LightGreen,
108 102 'in_prompt2' : InputTermColors.Green,
109 103 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
110 104
111 105 'out_prompt' : Colors.Red,
112 106 'out_number' : Colors.LightRed,
113 107
114 108 'normal' : Colors.Normal # color off (usu. Colors.Normal)
115 109 } )
116 110
117 111 NeutralColors = ColorScheme(
118 112 'Neutral',{
119 113 'header' : Colors.Red,
120 114 token.NUMBER : Colors.Cyan,
121 115 token.OP : Colors.Blue,
122 116 token.STRING : Colors.Blue,
123 117 tokenize.COMMENT : Colors.Red,
124 118 token.NAME : Colors.Normal,
125 119 token.ERRORTOKEN : Colors.Red,
126 120
127 121 _KEYWORD : Colors.Green,
128 122 _TEXT : Colors.Blue,
129 123
130 124 'in_prompt' : InputTermColors.Blue,
131 125 'in_number' : InputTermColors.LightBlue,
132 126 'in_prompt2' : InputTermColors.Blue,
133 127 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
134 128
135 129 'out_prompt' : Colors.Red,
136 130 'out_number' : Colors.LightRed,
137 131
138 132 'normal' : Colors.Normal # color off (usu. Colors.Normal)
139 133 } )
140 134
141 135 # Hack: the 'neutral' colours are not very visible on a dark background on
142 136 # Windows. Since Windows command prompts have a dark background by default, and
143 137 # relatively few users are likely to alter that, we will use the 'Linux' colours,
144 138 # designed for a dark background, as the default on Windows. Changing it here
145 139 # avoids affecting the prompt colours rendered by prompt_toolkit, where the
146 140 # neutral defaults do work OK.
147 141
148 142 if os.name == 'nt':
149 143 NeutralColors = LinuxColors.copy(name='Neutral')
150 144
151 145 LightBGColors = ColorScheme(
152 146 'LightBG',{
153 147 'header' : Colors.Red,
154 148 token.NUMBER : Colors.Cyan,
155 149 token.OP : Colors.Blue,
156 150 token.STRING : Colors.Blue,
157 151 tokenize.COMMENT : Colors.Red,
158 152 token.NAME : Colors.Normal,
159 153 token.ERRORTOKEN : Colors.Red,
160 154
161 155
162 156 _KEYWORD : Colors.Green,
163 157 _TEXT : Colors.Blue,
164 158
165 159 'in_prompt' : InputTermColors.Blue,
166 160 'in_number' : InputTermColors.LightBlue,
167 161 'in_prompt2' : InputTermColors.Blue,
168 162 'in_normal' : InputTermColors.Normal, # color off (usu. Colors.Normal)
169 163
170 164 'out_prompt' : Colors.Red,
171 165 'out_number' : Colors.LightRed,
172 166
173 167 'normal' : Colors.Normal # color off (usu. Colors.Normal)
174 168 } )
175 169
176 170 # Build table of color schemes (needed by the parser)
177 171 ANSICodeColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors, NeutralColors],
178 172 _scheme_default)
179 173
180 174 Undefined = object()
181 175
182 176 class Parser(Colorable):
183 177 """ Format colored Python source.
184 178 """
185 179
186 180 def __init__(self, color_table=None, out = sys.stdout, parent=None, style=None):
187 181 """ Create a parser with a specified color table and output channel.
188 182
189 183 Call format() to process code.
190 184 """
191 185
192 186 super(Parser, self).__init__(parent=parent)
193 187
194 188 self.color_table = color_table and color_table or ANSICodeColors
195 189 self.out = out
196 190 if not style:
197 191 self.style = self.default_style
198 192 else:
199 193 self.style = style
200 194
201 195
202 196 def format(self, raw, out=None, scheme=Undefined):
203 197 import warnings
204 198 if scheme is not Undefined:
205 199 warnings.warn('The `scheme` argument of IPython.utils.PyColorize:Parser.format is deprecated since IPython 6.0.'
206 200 'It will have no effect. Set the parser `style` directly.',
207 201 stacklevel=2)
208 202 return self.format2(raw, out)[0]
209 203
210 204 def format2(self, raw, out = None):
211 205 """ Parse and send the colored source.
212 206
213 207 If out and scheme are not specified, the defaults (given to
214 208 constructor) are used.
215 209
216 210 out should be a file-type object. Optionally, out can be given as the
217 211 string 'str' and the parser will automatically return the output in a
218 212 string."""
219 213
220 214 string_output = 0
221 215 if out == 'str' or self.out == 'str' or \
222 216 isinstance(self.out,StringIO):
223 217 # XXX - I don't really like this state handling logic, but at this
224 218 # point I don't want to make major changes, so adding the
225 219 # isinstance() check is the simplest I can do to ensure correct
226 220 # behavior.
227 221 out_old = self.out
228 222 self.out = StringIO()
229 223 string_output = 1
230 224 elif out is not None:
231 225 self.out = out
232 226
233 227 # Fast return of the unmodified input for NoColor scheme
234 228 if self.style == 'NoColor':
235 229 error = False
236 230 self.out.write(raw)
237 231 if string_output:
238 232 return raw,error
239 233 else:
240 234 return None,error
241 235
242 236 # local shorthands
243 237 colors = self.color_table[self.style].colors
244 238 self.colors = colors # put in object so __call__ sees it
245 239
246 240 # Remove trailing whitespace and normalize tabs
247 241 self.raw = raw.expandtabs().rstrip()
248 242
249 243 # store line offsets in self.lines
250 244 self.lines = [0, 0]
251 245 pos = 0
252 246 raw_find = self.raw.find
253 247 lines_append = self.lines.append
254 248 while 1:
255 249 pos = raw_find('\n', pos) + 1
256 250 if not pos: break
257 251 lines_append(pos)
258 252 lines_append(len(self.raw))
259 253
260 254 # parse the source and write it
261 255 self.pos = 0
262 256 text = StringIO(self.raw)
263 257
264 258 error = False
265 259 try:
266 260 for atoken in generate_tokens(text.readline):
267 261 self(*atoken)
268 262 except tokenize.TokenError as ex:
269 263 msg = ex.args[0]
270 264 line = ex.args[1][0]
271 265 self.out.write("%s\n\n*** ERROR: %s%s%s\n" %
272 266 (colors[token.ERRORTOKEN],
273 267 msg, self.raw[self.lines[line]:],
274 268 colors.normal)
275 269 )
276 270 error = True
277 271 self.out.write(colors.normal+'\n')
278 272 if string_output:
279 273 output = self.out.getvalue()
280 274 self.out = out_old
281 275 return (output, error)
282 276 return (None, error)
283 277
284 278 def __call__(self, toktype, toktext, start_pos, end_pos, line):
285 279 """ Token handler, with syntax highlighting."""
286 280 (srow,scol) = start_pos
287 281 (erow,ecol) = end_pos
288 282 colors = self.colors
289 283 owrite = self.out.write
290 284
291 285 # line separator, so this works across platforms
292 286 linesep = os.linesep
293 287
294 288 # calculate new positions
295 289 oldpos = self.pos
296 290 newpos = self.lines[srow] + scol
297 291 self.pos = newpos + len(toktext)
298 292
299 293 # send the original whitespace, if needed
300 294 if newpos > oldpos:
301 295 owrite(self.raw[oldpos:newpos])
302 296
303 297 # skip indenting tokens
304 298 if toktype in [token.INDENT, token.DEDENT]:
305 299 self.pos = newpos
306 300 return
307 301
308 302 # map token type to a color group
309 303 if token.LPAR <= toktype <= token.OP:
310 304 toktype = token.OP
311 305 elif toktype == token.NAME and keyword.iskeyword(toktext):
312 306 toktype = _KEYWORD
313 307 color = colors.get(toktype, colors[_TEXT])
314 308
315 309 #print '<%s>' % toktext, # dbg
316 310
317 311 # Triple quoted strings must be handled carefully so that backtracking
318 312 # in pagers works correctly. We need color terminators on _each_ line.
319 313 if linesep in toktext:
320 314 toktext = toktext.replace(linesep, '%s%s%s' %
321 315 (colors.normal,linesep,color))
322 316
323 317 # send text
324 318 owrite('%s%s%s' % (color,toktext,colors.normal))
@@ -1,172 +1,166 b''
1 1 # encoding: utf-8
2 2 """IO capturing utilities."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 import sys
9
10 from IPython.utils.py3compat import PY3
11
12 if PY3:
13 9 from io import StringIO
14 else:
15 from StringIO import StringIO
16 10
17 11 #-----------------------------------------------------------------------------
18 12 # Classes and functions
19 13 #-----------------------------------------------------------------------------
20 14
21 15
22 16 class RichOutput(object):
23 17 def __init__(self, data=None, metadata=None):
24 18 self.data = data or {}
25 19 self.metadata = metadata or {}
26 20
27 21 def display(self):
28 22 from IPython.display import publish_display_data
29 23 publish_display_data(data=self.data, metadata=self.metadata)
30 24
31 25 def _repr_mime_(self, mime):
32 26 if mime not in self.data:
33 27 return
34 28 data = self.data[mime]
35 29 if mime in self.metadata:
36 30 return data, self.metadata[mime]
37 31 else:
38 32 return data
39 33
40 34 def _repr_html_(self):
41 35 return self._repr_mime_("text/html")
42 36
43 37 def _repr_latex_(self):
44 38 return self._repr_mime_("text/latex")
45 39
46 40 def _repr_json_(self):
47 41 return self._repr_mime_("application/json")
48 42
49 43 def _repr_javascript_(self):
50 44 return self._repr_mime_("application/javascript")
51 45
52 46 def _repr_png_(self):
53 47 return self._repr_mime_("image/png")
54 48
55 49 def _repr_jpeg_(self):
56 50 return self._repr_mime_("image/jpeg")
57 51
58 52 def _repr_svg_(self):
59 53 return self._repr_mime_("image/svg+xml")
60 54
61 55
62 56 class CapturedIO(object):
63 57 """Simple object for containing captured stdout/err and rich display StringIO objects
64 58
65 59 Each instance `c` has three attributes:
66 60
67 61 - ``c.stdout`` : standard output as a string
68 62 - ``c.stderr`` : standard error as a string
69 63 - ``c.outputs``: a list of rich display outputs
70 64
71 65 Additionally, there's a ``c.show()`` method which will print all of the
72 66 above in the same order, and can be invoked simply via ``c()``.
73 67 """
74 68
75 69 def __init__(self, stdout, stderr, outputs=None):
76 70 self._stdout = stdout
77 71 self._stderr = stderr
78 72 if outputs is None:
79 73 outputs = []
80 74 self._outputs = outputs
81 75
82 76 def __str__(self):
83 77 return self.stdout
84 78
85 79 @property
86 80 def stdout(self):
87 81 "Captured standard output"
88 82 if not self._stdout:
89 83 return ''
90 84 return self._stdout.getvalue()
91 85
92 86 @property
93 87 def stderr(self):
94 88 "Captured standard error"
95 89 if not self._stderr:
96 90 return ''
97 91 return self._stderr.getvalue()
98 92
99 93 @property
100 94 def outputs(self):
101 95 """A list of the captured rich display outputs, if any.
102 96
103 97 If you have a CapturedIO object ``c``, these can be displayed in IPython
104 98 using::
105 99
106 100 from IPython.display import display
107 101 for o in c.outputs:
108 102 display(o)
109 103 """
110 104 return [ RichOutput(d, md) for d, md in self._outputs ]
111 105
112 106 def show(self):
113 107 """write my output to sys.stdout/err as appropriate"""
114 108 sys.stdout.write(self.stdout)
115 109 sys.stderr.write(self.stderr)
116 110 sys.stdout.flush()
117 111 sys.stderr.flush()
118 112 for data, metadata in self._outputs:
119 113 RichOutput(data, metadata).display()
120 114
121 115 __call__ = show
122 116
123 117
124 118 class capture_output(object):
125 119 """context manager for capturing stdout/err"""
126 120 stdout = True
127 121 stderr = True
128 122 display = True
129 123
130 124 def __init__(self, stdout=True, stderr=True, display=True):
131 125 self.stdout = stdout
132 126 self.stderr = stderr
133 127 self.display = display
134 128 self.shell = None
135 129
136 130 def __enter__(self):
137 131 from IPython.core.getipython import get_ipython
138 132 from IPython.core.displaypub import CapturingDisplayPublisher
139 133 from IPython.core.displayhook import CapturingDisplayHook
140 134
141 135 self.sys_stdout = sys.stdout
142 136 self.sys_stderr = sys.stderr
143 137
144 138 if self.display:
145 139 self.shell = get_ipython()
146 140 if self.shell is None:
147 141 self.save_display_pub = None
148 142 self.display = False
149 143
150 144 stdout = stderr = outputs = None
151 145 if self.stdout:
152 146 stdout = sys.stdout = StringIO()
153 147 if self.stderr:
154 148 stderr = sys.stderr = StringIO()
155 149 if self.display:
156 150 self.save_display_pub = self.shell.display_pub
157 151 self.shell.display_pub = CapturingDisplayPublisher()
158 152 outputs = self.shell.display_pub.outputs
159 153 self.save_display_hook = sys.displayhook
160 154 sys.displayhook = CapturingDisplayHook(shell=self.shell,
161 155 outputs=outputs)
162 156
163 157 return CapturedIO(stdout, stderr, outputs)
164 158
165 159 def __exit__(self, exc_type, exc_value, traceback):
166 160 sys.stdout = self.sys_stdout
167 161 sys.stderr = self.sys_stderr
168 162 if self.display and self.shell:
169 163 self.shell.display_pub = self.save_display_pub
170 164 sys.displayhook = self.save_display_hook
171 165
172 166
@@ -1,240 +1,240 b''
1 1 # encoding: utf-8
2 2 """
3 3 IO related utilities.
4 4 """
5 5
6 6 # Copyright (c) IPython Development Team.
7 7 # Distributed under the terms of the Modified BSD License.
8 8
9 9
10 10
11 11 import atexit
12 12 import os
13 13 import sys
14 14 import tempfile
15 15 import warnings
16 16 from warnings import warn
17 17
18 18 from IPython.utils.decorators import undoc
19 19 from .capture import CapturedIO, capture_output
20 from .py3compat import input, PY3
20 from .py3compat import input
21 21
22 22 @undoc
23 23 class IOStream:
24 24
25 25 def __init__(self, stream, fallback=None):
26 26 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
27 27 DeprecationWarning, stacklevel=2)
28 28 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
29 29 if fallback is not None:
30 30 stream = fallback
31 31 else:
32 32 raise ValueError("fallback required, but not specified")
33 33 self.stream = stream
34 34 self._swrite = stream.write
35 35
36 36 # clone all methods not overridden:
37 37 def clone(meth):
38 38 return not hasattr(self, meth) and not meth.startswith('_')
39 39 for meth in filter(clone, dir(stream)):
40 40 setattr(self, meth, getattr(stream, meth))
41 41
42 42 def __repr__(self):
43 43 cls = self.__class__
44 44 tpl = '{mod}.{cls}({args})'
45 45 return tpl.format(mod=cls.__module__, cls=cls.__name__, args=self.stream)
46 46
47 47 def write(self,data):
48 48 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
49 49 DeprecationWarning, stacklevel=2)
50 50 try:
51 51 self._swrite(data)
52 52 except:
53 53 try:
54 54 # print handles some unicode issues which may trip a plain
55 55 # write() call. Emulate write() by using an empty end
56 56 # argument.
57 57 print(data, end='', file=self.stream)
58 58 except:
59 59 # if we get here, something is seriously broken.
60 60 print('ERROR - failed to write data to stream:', self.stream,
61 61 file=sys.stderr)
62 62
63 63 def writelines(self, lines):
64 64 warn('IOStream is deprecated since IPython 5.0, use sys.{stdin,stdout,stderr} instead',
65 65 DeprecationWarning, stacklevel=2)
66 66 if isinstance(lines, str):
67 67 lines = [lines]
68 68 for line in lines:
69 69 self.write(line)
70 70
71 71 # This class used to have a writeln method, but regular files and streams
72 72 # in Python don't have this method. We need to keep this completely
73 73 # compatible so we removed it.
74 74
75 75 @property
76 76 def closed(self):
77 77 return self.stream.closed
78 78
79 79 def close(self):
80 80 pass
81 81
82 82 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
83 83 devnull = open(os.devnull, 'w')
84 84 atexit.register(devnull.close)
85 85
86 86 # io.std* are deprecated, but don't show our own deprecation warnings
87 87 # during initialization of the deprecated API.
88 88 with warnings.catch_warnings():
89 89 warnings.simplefilter('ignore', DeprecationWarning)
90 90 stdin = IOStream(sys.stdin, fallback=devnull)
91 91 stdout = IOStream(sys.stdout, fallback=devnull)
92 92 stderr = IOStream(sys.stderr, fallback=devnull)
93 93
94 94 class Tee(object):
95 95 """A class to duplicate an output stream to stdout/err.
96 96
97 97 This works in a manner very similar to the Unix 'tee' command.
98 98
99 99 When the object is closed or deleted, it closes the original file given to
100 100 it for duplication.
101 101 """
102 102 # Inspired by:
103 103 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
104 104
105 105 def __init__(self, file_or_name, mode="w", channel='stdout'):
106 106 """Construct a new Tee object.
107 107
108 108 Parameters
109 109 ----------
110 110 file_or_name : filename or open filehandle (writable)
111 111 File that will be duplicated
112 112
113 113 mode : optional, valid mode for open().
114 114 If a filename was give, open with this mode.
115 115
116 116 channel : str, one of ['stdout', 'stderr']
117 117 """
118 118 if channel not in ['stdout', 'stderr']:
119 119 raise ValueError('Invalid channel spec %s' % channel)
120 120
121 121 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
122 122 self.file = file_or_name
123 123 else:
124 124 self.file = open(file_or_name, mode)
125 125 self.channel = channel
126 126 self.ostream = getattr(sys, channel)
127 127 setattr(sys, channel, self)
128 128 self._closed = False
129 129
130 130 def close(self):
131 131 """Close the file and restore the channel."""
132 132 self.flush()
133 133 setattr(sys, self.channel, self.ostream)
134 134 self.file.close()
135 135 self._closed = True
136 136
137 137 def write(self, data):
138 138 """Write data to both channels."""
139 139 self.file.write(data)
140 140 self.ostream.write(data)
141 141 self.ostream.flush()
142 142
143 143 def flush(self):
144 144 """Flush both channels."""
145 145 self.file.flush()
146 146 self.ostream.flush()
147 147
148 148 def __del__(self):
149 149 if not self._closed:
150 150 self.close()
151 151
152 152
153 153 def ask_yes_no(prompt, default=None, interrupt=None):
154 154 """Asks a question and returns a boolean (y/n) answer.
155 155
156 156 If default is given (one of 'y','n'), it is used if the user input is
157 157 empty. If interrupt is given (one of 'y','n'), it is used if the user
158 158 presses Ctrl-C. Otherwise the question is repeated until an answer is
159 159 given.
160 160
161 161 An EOF is treated as the default answer. If there is no default, an
162 162 exception is raised to prevent infinite loops.
163 163
164 164 Valid answers are: y/yes/n/no (match is not case sensitive)."""
165 165
166 166 answers = {'y':True,'n':False,'yes':True,'no':False}
167 167 ans = None
168 168 while ans not in answers.keys():
169 169 try:
170 170 ans = input(prompt+' ').lower()
171 171 if not ans: # response was an empty string
172 172 ans = default
173 173 except KeyboardInterrupt:
174 174 if interrupt:
175 175 ans = interrupt
176 176 print("\r")
177 177 except EOFError:
178 178 if default in answers.keys():
179 179 ans = default
180 180 print()
181 181 else:
182 182 raise
183 183
184 184 return answers[ans]
185 185
186 186
187 187 def temp_pyfile(src, ext='.py'):
188 188 """Make a temporary python file, return filename and filehandle.
189 189
190 190 Parameters
191 191 ----------
192 192 src : string or list of strings (no need for ending newlines if list)
193 193 Source code to be written to the file.
194 194
195 195 ext : optional, string
196 196 Extension for the generated file.
197 197
198 198 Returns
199 199 -------
200 200 (filename, open filehandle)
201 201 It is the caller's responsibility to close the open file and unlink it.
202 202 """
203 203 fname = tempfile.mkstemp(ext)[1]
204 204 f = open(fname,'w')
205 205 f.write(src)
206 206 f.flush()
207 207 return fname, f
208 208
209 209 def atomic_writing(*args, **kwargs):
210 210 """DEPRECATED: moved to notebook.services.contents.fileio"""
211 211 warn("IPython.utils.io.atomic_writing has moved to notebook.services.contents.fileio", stacklevel=2)
212 212 from notebook.services.contents.fileio import atomic_writing
213 213 return atomic_writing(*args, **kwargs)
214 214
215 215 def raw_print(*args, **kw):
216 216 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
217 217
218 218 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
219 219 file=sys.__stdout__)
220 220 sys.__stdout__.flush()
221 221
222 222
223 223 def raw_print_err(*args, **kw):
224 224 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
225 225
226 226 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
227 227 file=sys.__stderr__)
228 228 sys.__stderr__.flush()
229 229
230 230
231 231 # Short aliases for quick debugging, do NOT use these in production code.
232 232 rprint = raw_print
233 233 rprinte = raw_print_err
234 234
235 235
236 236 def unicode_std_stream(stream='stdout'):
237 237 """DEPRECATED, moved to nbconvert.utils.io"""
238 238 warn("IPython.utils.io.unicode_std_stream has moved to nbconvert.utils.io", stacklevel=2)
239 239 from nbconvert.utils.io import unicode_std_stream
240 240 return unicode_std_stream(stream)
@@ -1,85 +1,81 b''
1 1 # encoding: utf-8
2 2 """Tests for io.py"""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7
8 8 import io as stdlib_io
9 9 import os.path
10 10 import stat
11 11 import sys
12 from io import StringIO
12 13
13 14 from subprocess import Popen, PIPE
14 15 import unittest
15 16
16 17 import nose.tools as nt
17 18
18 19 from IPython.testing.decorators import skipif, skip_win32
19 20 from IPython.utils.io import Tee, capture_output
20 from IPython.utils.py3compat import doctest_refactor_print, PY3
21 from IPython.utils.py3compat import doctest_refactor_print
21 22 from IPython.utils.tempdir import TemporaryDirectory
22 23
23 if PY3:
24 from io import StringIO
25 else:
26 from StringIO import StringIO
27
28 24
29 25 def test_tee_simple():
30 26 "Very simple check with stdout only"
31 27 chan = StringIO()
32 28 text = 'Hello'
33 29 tee = Tee(chan, channel='stdout')
34 30 print(text, file=chan)
35 31 nt.assert_equal(chan.getvalue(), text+"\n")
36 32
37 33
38 34 class TeeTestCase(unittest.TestCase):
39 35
40 36 def tchan(self, channel, check='close'):
41 37 trap = StringIO()
42 38 chan = StringIO()
43 39 text = 'Hello'
44 40
45 41 std_ori = getattr(sys, channel)
46 42 setattr(sys, channel, trap)
47 43
48 44 tee = Tee(chan, channel=channel)
49 45 print(text, end='', file=chan)
50 46 setattr(sys, channel, std_ori)
51 47 trap_val = trap.getvalue()
52 48 nt.assert_equal(chan.getvalue(), text)
53 49 if check=='close':
54 50 tee.close()
55 51 else:
56 52 del tee
57 53
58 54 def test(self):
59 55 for chan in ['stdout', 'stderr']:
60 56 for check in ['close', 'del']:
61 57 self.tchan(chan, check)
62 58
63 59 def test_io_init():
64 60 """Test that io.stdin/out/err exist at startup"""
65 61 for name in ('stdin', 'stdout', 'stderr'):
66 62 cmd = doctest_refactor_print("from IPython.utils import io;print io.%s.__class__"%name)
67 63 p = Popen([sys.executable, '-c', cmd],
68 64 stdout=PIPE)
69 65 p.wait()
70 66 classname = p.stdout.read().strip().decode('ascii')
71 67 # __class__ is a reference to the class object in Python 3, so we can't
72 68 # just test for string equality.
73 69 assert 'IPython.utils.io.IOStream' in classname, classname
74 70
75 71 def test_capture_output():
76 72 """capture_output() context works"""
77 73
78 74 with capture_output() as io:
79 75 print('hi, stdout')
80 76 print('hi, stderr', file=sys.stderr)
81 77
82 78 nt.assert_equal(io.stdout, 'hi, stdout\n')
83 79 nt.assert_equal(io.stderr, 'hi, stderr\n')
84 80
85 81
@@ -1,44 +1,25 b''
1 """Wrapper around linecache which decodes files to unicode according to PEP 263.
1 """
2 This module has been deprecated since IPython 6.0.
2 3
3 This is only needed for Python 2 - linecache in Python 3 does the same thing
4 itself.
4 Wrapper around linecache which decodes files to unicode according to PEP 263.
5 5 """
6 6 import functools
7 7 import linecache
8 8 import sys
9 from warnings import warn
9 10
10 11 from IPython.utils import py3compat
11 12 from IPython.utils import openpy
12 13
13 if py3compat.PY3:
14 14 getline = linecache.getline
15 15
16 16 # getlines has to be looked up at runtime, because doctests monkeypatch it.
17 17 @functools.wraps(linecache.getlines)
18 18 def getlines(filename, module_globals=None):
19 """
20 Deprecated since IPython 6.0
21 """
22 warn(("`IPython.utils.ulinecache.getlines` is deprecated since"
23 " IPython 6.0 and will be removed in future versions."),
24 DeprecationWarning, stacklevel=2)
19 25 return linecache.getlines(filename, module_globals=module_globals)
20
21 else:
22 def getlines(filename, module_globals=None):
23 """Get the lines (as unicode) for a file from the cache.
24 Update the cache if it doesn't contain an entry for this file already."""
25 filename = py3compat.cast_bytes(filename, sys.getfilesystemencoding())
26 lines = linecache.getlines(filename, module_globals=module_globals)
27
28 if (not lines) or isinstance(lines[0], str):
29 return lines
30
31 readline = openpy._list_readline(lines)
32 try:
33 encoding, _ = openpy.detect_encoding(readline)
34 except SyntaxError:
35 encoding = 'ascii'
36 return [l.decode(encoding, 'replace') for l in lines]
37
38 # This is a straight copy of linecache.getline
39 def getline(filename, lineno, module_globals=None):
40 lines = getlines(filename, module_globals)
41 if 1 <= lineno <= len(lines):
42 return lines[lineno-1]
43 else:
44 return ''
General Comments 0
You need to be logged in to leave comments. Login now