##// END OF EJS Templates
remove python2 specific cast_unicode_py2 function
Srinivas Reddy Thatiparthy -
Show More
@@ -1,1934 +1,1933 b''
1 1 # encoding: utf-8
2 2 """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 This module now support a wide variety of completion mechanism both available
9 9 for normal classic Python code, as well as completer for IPython specific
10 10 Syntax like magics.
11 11
12 12 Latex and Unicode completion
13 13 ============================
14 14
15 15 IPython and compatible frontends not only can complete your code, but can help
16 16 you to input a wide range of characters. In particular we allow you to insert
17 17 a unicode character using the tab completion mechanism.
18 18
19 19 Forward latex/unicode completion
20 20 --------------------------------
21 21
22 22 Forward completion allows you to easily type a unicode character using its latex
23 23 name, or unicode long description. To do so type a backslash follow by the
24 24 relevant name and press tab:
25 25
26 26
27 27 Using latex completion:
28 28
29 29 .. code::
30 30
31 31 \\alpha<tab>
32 32 Ξ±
33 33
34 34 or using unicode completion:
35 35
36 36
37 37 .. code::
38 38
39 39 \\greek small letter alpha<tab>
40 40 Ξ±
41 41
42 42
43 43 Only valid Python identifiers will complete. Combining characters (like arrow or
44 44 dots) are also available, unlike latex they need to be put after the their
45 45 counterpart that is to say, `F\\\\vec<tab>` is correct, not `\\\\vec<tab>F`.
46 46
47 47 Some browsers are known to display combining characters incorrectly.
48 48
49 49 Backward latex completion
50 50 -------------------------
51 51
52 52 It is sometime challenging to know how to type a character, if you are using
53 53 IPython, or any compatible frontend you can prepend backslash to the character
54 54 and press `<tab>` to expand it to its latex form.
55 55
56 56 .. code::
57 57
58 58 \\Ξ±<tab>
59 59 \\alpha
60 60
61 61
62 62 Both forward and backward completions can be deactivated by setting the
63 63 ``Completer.backslash_combining_completions`` option to ``False``.
64 64
65 65
66 66 Experimental
67 67 ============
68 68
69 69 Starting with IPython 6.0, this module can make use of the Jedi library to
70 70 generate completions both using static analysis of the code, and dynamically
71 71 inspecting multiple namespaces. The APIs attached to this new mechanism is
72 72 unstable and will raise unless use in an :any:`provisionalcompleter` context
73 73 manager.
74 74
75 75 You will find that the following are experimental:
76 76
77 77 - :any:`provisionalcompleter`
78 78 - :any:`IPCompleter.completions`
79 79 - :any:`Completion`
80 80 - :any:`rectify_completions`
81 81
82 82 .. note::
83 83
84 84 better name for :any:`rectify_completions` ?
85 85
86 86 We welcome any feedback on these new API, and we also encourage you to try this
87 87 module in debug mode (start IPython with ``--Completer.debug=True``) in order
88 88 to have extra logging information is :any:`jedi` is crashing, or if current
89 89 IPython completer pending deprecations are returning results not yet handled
90 90 by :any:`jedi`.
91 91
92 92 Using Jedi for tab completion allow snippets like the following to work without
93 93 having to execute any code:
94 94
95 95 >>> myvar = ['hello', 42]
96 96 ... myvar[1].bi<tab>
97 97
98 98 Tab completion will be able to infer that ``myvar[1]`` is a real number without
99 99 executing any code unlike the previously available ``IPCompleter.greedy``
100 100 option.
101 101
102 102 Be sure to update :any:`jedi` to the latest stable version or to try the
103 103 current development version to get better completions.
104 104 """
105 105
106 106 # skip module docstests
107 107 skip_doctest = True
108 108
109 109 # Copyright (c) IPython Development Team.
110 110 # Distributed under the terms of the Modified BSD License.
111 111 #
112 112 # Some of this code originated from rlcompleter in the Python standard library
113 113 # Copyright (C) 2001 Python Software Foundation, www.python.org
114 114
115 115
116 116 import __main__
117 117 import builtins as builtin_mod
118 118 import glob
119 119 import time
120 120 import inspect
121 121 import itertools
122 122 import keyword
123 123 import os
124 124 import re
125 125 import sys
126 126 import unicodedata
127 127 import string
128 128 import warnings
129 129
130 130 from contextlib import contextmanager
131 131 from importlib import import_module
132 132 from typing import Iterator, List
133 133 from types import SimpleNamespace
134 134
135 135 from traitlets.config.configurable import Configurable
136 136 from IPython.core.error import TryNext
137 137 from IPython.core.inputsplitter import ESC_MAGIC
138 138 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
139 139 from IPython.utils import generics
140 140 from IPython.utils.dir2 import dir2, get_real_method
141 141 from IPython.utils.process import arg_split
142 from IPython.utils.py3compat import cast_unicode_py2
143 142 from traitlets import Bool, Enum, observe, Int
144 143
145 144 try:
146 145 import jedi
147 146 import jedi.api.helpers
148 147 JEDI_INSTALLED = True
149 148 except ImportError:
150 149 JEDI_INSTALLED = False
151 150 #-----------------------------------------------------------------------------
152 151 # Globals
153 152 #-----------------------------------------------------------------------------
154 153
155 154 # Public API
156 155 __all__ = ['Completer','IPCompleter']
157 156
158 157 if sys.platform == 'win32':
159 158 PROTECTABLES = ' '
160 159 else:
161 160 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
162 161
163 162
164 163 _deprecation_readline_sentinel = object()
165 164
166 165
167 166 class ProvisionalCompleterWarning(FutureWarning):
168 167 """
169 168 Exception raise by an experimental feature in this module.
170 169
171 170 Wrap code in :any:`provisionalcompleter` context manager if you
172 171 are certain you want to use an unstable feature.
173 172 """
174 173 pass
175 174
176 175 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
177 176
178 177 @contextmanager
179 178 def provisionalcompleter(action='ignore'):
180 179 """
181 180
182 181
183 182 This contest manager has to be used in any place where unstable completer
184 183 behavior and API may be called.
185 184
186 185 >>> with provisionalcompleter():
187 186 ... completer.do_experimetal_things() # works
188 187
189 188 >>> completer.do_experimental_things() # raises.
190 189
191 190 .. note:: Unstable
192 191
193 192 By using this context manager you agree that the API in use may change
194 193 without warning, and that you won't complain if they do so.
195 194
196 195 You also understand that if the API is not to you liking you should report
197 196 a bug to explain your use case upstream and improve the API and will loose
198 197 credibility if you complain after the API is make stable.
199 198
200 199 We'll be happy to get your feedback , feature request and improvement on
201 200 any of the unstable APIs !
202 201 """
203 202 with warnings.catch_warnings():
204 203 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
205 204 yield
206 205
207 206
208 207 def has_open_quotes(s):
209 208 """Return whether a string has open quotes.
210 209
211 210 This simply counts whether the number of quote characters of either type in
212 211 the string is odd.
213 212
214 213 Returns
215 214 -------
216 215 If there is an open quote, the quote character is returned. Else, return
217 216 False.
218 217 """
219 218 # We check " first, then ', so complex cases with nested quotes will get
220 219 # the " to take precedence.
221 220 if s.count('"') % 2:
222 221 return '"'
223 222 elif s.count("'") % 2:
224 223 return "'"
225 224 else:
226 225 return False
227 226
228 227
229 228 def protect_filename(s, protectables=PROTECTABLES):
230 229 """Escape a string to protect certain characters."""
231 230 if set(s) & set(protectables):
232 231 if sys.platform == "win32":
233 232 return '"' + s + '"'
234 233 else:
235 234 return "".join(("\\" + c if c in protectables else c) for c in s)
236 235 else:
237 236 return s
238 237
239 238
240 239 def expand_user(path):
241 240 """Expand ``~``-style usernames in strings.
242 241
243 242 This is similar to :func:`os.path.expanduser`, but it computes and returns
244 243 extra information that will be useful if the input was being used in
245 244 computing completions, and you wish to return the completions with the
246 245 original '~' instead of its expanded value.
247 246
248 247 Parameters
249 248 ----------
250 249 path : str
251 250 String to be expanded. If no ~ is present, the output is the same as the
252 251 input.
253 252
254 253 Returns
255 254 -------
256 255 newpath : str
257 256 Result of ~ expansion in the input path.
258 257 tilde_expand : bool
259 258 Whether any expansion was performed or not.
260 259 tilde_val : str
261 260 The value that ~ was replaced with.
262 261 """
263 262 # Default values
264 263 tilde_expand = False
265 264 tilde_val = ''
266 265 newpath = path
267 266
268 267 if path.startswith('~'):
269 268 tilde_expand = True
270 269 rest = len(path)-1
271 270 newpath = os.path.expanduser(path)
272 271 if rest:
273 272 tilde_val = newpath[:-rest]
274 273 else:
275 274 tilde_val = newpath
276 275
277 276 return newpath, tilde_expand, tilde_val
278 277
279 278
280 279 def compress_user(path, tilde_expand, tilde_val):
281 280 """Does the opposite of expand_user, with its outputs.
282 281 """
283 282 if tilde_expand:
284 283 return path.replace(tilde_val, '~')
285 284 else:
286 285 return path
287 286
288 287
289 288 def completions_sorting_key(word):
290 289 """key for sorting completions
291 290
292 291 This does several things:
293 292
294 293 - Lowercase all completions, so they are sorted alphabetically with
295 294 upper and lower case words mingled
296 295 - Demote any completions starting with underscores to the end
297 296 - Insert any %magic and %%cellmagic completions in the alphabetical order
298 297 by their name
299 298 """
300 299 # Case insensitive sort
301 300 word = word.lower()
302 301
303 302 prio1, prio2 = 0, 0
304 303
305 304 if word.startswith('__'):
306 305 prio1 = 2
307 306 elif word.startswith('_'):
308 307 prio1 = 1
309 308
310 309 if word.endswith('='):
311 310 prio1 = -1
312 311
313 312 if word.startswith('%%'):
314 313 # If there's another % in there, this is something else, so leave it alone
315 314 if not "%" in word[2:]:
316 315 word = word[2:]
317 316 prio2 = 2
318 317 elif word.startswith('%'):
319 318 if not "%" in word[1:]:
320 319 word = word[1:]
321 320 prio2 = 1
322 321
323 322 return prio1, word, prio2
324 323
325 324
326 325 class _FakeJediCompletion:
327 326 """
328 327 This is a workaround to communicate to the UI that Jedi has crashed and to
329 328 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
330 329
331 330 Added in IPython 6.0 so should likely be removed for 7.0
332 331
333 332 """
334 333
335 334 def __init__(self, name):
336 335
337 336 self.name = name
338 337 self.complete = name
339 338 self.type = 'crashed'
340 339 self.name_with_symbols = name
341 340
342 341 def __repr__(self):
343 342 return '<Fake completion object jedi has crashed>'
344 343
345 344
346 345 class Completion:
347 346 """
348 347 Completion object used and return by IPython completers.
349 348
350 349 .. warning:: Unstable
351 350
352 351 This function is unstable, API may change without warning.
353 352 It will also raise unless use in proper context manager.
354 353
355 354 This act as a middle ground :any:`Completion` object between the
356 355 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
357 356 object. While Jedi need a lot of information about evaluator and how the
358 357 code should be ran/inspected, PromptToolkit (and other frontend) mostly
359 358 need user facing information.
360 359
361 360 - Which range should be replaced replaced by what.
362 361 - Some metadata (like completion type), or meta informations to displayed to
363 362 the use user.
364 363
365 364 For debugging purpose we can also store the origin of the completion (``jedi``,
366 365 ``IPython.python_matches``, ``IPython.magics_matches``...).
367 366 """
368 367
369 368 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin=''):
370 369 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
371 370 "It may change without warnings. "
372 371 "Use in corresponding context manager.",
373 372 category=ProvisionalCompleterWarning, stacklevel=2)
374 373
375 374 self.start = start
376 375 self.end = end
377 376 self.text = text
378 377 self.type = type
379 378 self._origin = _origin
380 379
381 380 def __repr__(self):
382 381 return '<Completion start=%s end=%s text=%r type=%r>' % (self.start, self.end, self.text, self.type or '?')
383 382
384 383 def __eq__(self, other)->Bool:
385 384 """
386 385 Equality and hash do not hash the type (as some completer may not be
387 386 able to infer the type), but are use to (partially) de-duplicate
388 387 completion.
389 388
390 389 Completely de-duplicating completion is a bit tricker that just
391 390 comparing as it depends on surrounding text, which Completions are not
392 391 aware of.
393 392 """
394 393 return self.start == other.start and \
395 394 self.end == other.end and \
396 395 self.text == other.text
397 396
398 397 def __hash__(self):
399 398 return hash((self.start, self.end, self.text))
400 399
401 400
402 401 _IC = Iterator[Completion]
403 402
404 403
405 404 def _deduplicate_completions(text: str, completions: _IC)-> _IC:
406 405 """
407 406 Deduplicate a set of completions.
408 407
409 408 .. warning:: Unstable
410 409
411 410 This function is unstable, API may change without warning.
412 411
413 412 Parameters
414 413 ----------
415 414 text: str
416 415 text that should be completed.
417 416 completions: Iterator[Completion]
418 417 iterator over the completions to deduplicate
419 418
420 419
421 420 Completions coming from multiple sources, may be different but end up having
422 421 the same effect when applied to ``text``. If this is the case, this will
423 422 consider completions as equal and only emit the first encountered.
424 423
425 424 Not folded in `completions()` yet for debugging purpose, and to detect when
426 425 the IPython completer does return things that Jedi does not, but should be
427 426 at some point.
428 427 """
429 428 completions = list(completions)
430 429 if not completions:
431 430 return
432 431
433 432 new_start = min(c.start for c in completions)
434 433 new_end = max(c.end for c in completions)
435 434
436 435 seen = set()
437 436 for c in completions:
438 437 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
439 438 if new_text not in seen:
440 439 yield c
441 440 seen.add(new_text)
442 441
443 442
444 443 def rectify_completions(text: str, completions: _IC, *, _debug=False)->_IC:
445 444 """
446 445 Rectify a set of completions to all have the same ``start`` and ``end``
447 446
448 447 .. warning:: Unstable
449 448
450 449 This function is unstable, API may change without warning.
451 450 It will also raise unless use in proper context manager.
452 451
453 452 Parameters
454 453 ----------
455 454 text: str
456 455 text that should be completed.
457 456 completions: Iterator[Completion]
458 457 iterator over the completions to rectify
459 458
460 459
461 460 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
462 461 the Jupyter Protocol requires them to behave like so. This will readjust
463 462 the completion to have the same ``start`` and ``end`` by padding both
464 463 extremities with surrounding text.
465 464
466 465 During stabilisation should support a ``_debug`` option to log which
467 466 completion are return by the IPython completer and not found in Jedi in
468 467 order to make upstream bug report.
469 468 """
470 469 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
471 470 "It may change without warnings. "
472 471 "Use in corresponding context manager.",
473 472 category=ProvisionalCompleterWarning, stacklevel=2)
474 473
475 474 completions = list(completions)
476 475 if not completions:
477 476 return
478 477 starts = (c.start for c in completions)
479 478 ends = (c.end for c in completions)
480 479
481 480 new_start = min(starts)
482 481 new_end = max(ends)
483 482
484 483 seen_jedi = set()
485 484 seen_python_matches = set()
486 485 for c in completions:
487 486 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
488 487 if c._origin == 'jedi':
489 488 seen_jedi.add(new_text)
490 489 elif c._origin == 'IPCompleter.python_matches':
491 490 seen_python_matches.add(new_text)
492 491 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin)
493 492 diff = seen_python_matches.difference(seen_jedi)
494 493 if diff and _debug:
495 494 print('IPython.python matches have extras:', diff)
496 495
497 496
498 497 if sys.platform == 'win32':
499 498 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
500 499 else:
501 500 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
502 501
503 502 GREEDY_DELIMS = ' =\r\n'
504 503
505 504
506 505 class CompletionSplitter(object):
507 506 """An object to split an input line in a manner similar to readline.
508 507
509 508 By having our own implementation, we can expose readline-like completion in
510 509 a uniform manner to all frontends. This object only needs to be given the
511 510 line of text to be split and the cursor position on said line, and it
512 511 returns the 'word' to be completed on at the cursor after splitting the
513 512 entire line.
514 513
515 514 What characters are used as splitting delimiters can be controlled by
516 515 setting the ``delims`` attribute (this is a property that internally
517 516 automatically builds the necessary regular expression)"""
518 517
519 518 # Private interface
520 519
521 520 # A string of delimiter characters. The default value makes sense for
522 521 # IPython's most typical usage patterns.
523 522 _delims = DELIMS
524 523
525 524 # The expression (a normal string) to be compiled into a regular expression
526 525 # for actual splitting. We store it as an attribute mostly for ease of
527 526 # debugging, since this type of code can be so tricky to debug.
528 527 _delim_expr = None
529 528
530 529 # The regular expression that does the actual splitting
531 530 _delim_re = None
532 531
533 532 def __init__(self, delims=None):
534 533 delims = CompletionSplitter._delims if delims is None else delims
535 534 self.delims = delims
536 535
537 536 @property
538 537 def delims(self):
539 538 """Return the string of delimiter characters."""
540 539 return self._delims
541 540
542 541 @delims.setter
543 542 def delims(self, delims):
544 543 """Set the delimiters for line splitting."""
545 544 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
546 545 self._delim_re = re.compile(expr)
547 546 self._delims = delims
548 547 self._delim_expr = expr
549 548
550 549 def split_line(self, line, cursor_pos=None):
551 550 """Split a line of text with a cursor at the given position.
552 551 """
553 552 l = line if cursor_pos is None else line[:cursor_pos]
554 553 return self._delim_re.split(l)[-1]
555 554
556 555
557 556
558 557 class Completer(Configurable):
559 558
560 559 greedy = Bool(False,
561 560 help="""Activate greedy completion
562 561 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
563 562
564 563 This will enable completion on elements of lists, results of function calls, etc.,
565 564 but can be unsafe because the code is actually evaluated on TAB.
566 565 """
567 566 ).tag(config=True)
568 567
569 568 use_jedi = Bool(default_value=JEDI_INSTALLED,
570 569 help="Experimental: Use Jedi to generate autocompletions. "
571 570 "Default to True if jedi is installed").tag(config=True)
572 571
573 572 jedi_compute_type_timeout = Int(default_value=400,
574 573 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
575 574 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
576 575 performance by preventing jedi to build its cache.
577 576 """).tag(config=True)
578 577
579 578 debug = Bool(default_value=False,
580 579 help='Enable debug for the Completer. Mostly print extra '
581 580 'information for experimental jedi integration.')\
582 581 .tag(config=True)
583 582
584 583 backslash_combining_completions = Bool(True,
585 584 help="Enable unicode completions, e.g. \\alpha<tab> . "
586 585 "Includes completion of latex commands, unicode names, and expanding "
587 586 "unicode characters back to latex commands.").tag(config=True)
588 587
589 588
590 589
591 590 def __init__(self, namespace=None, global_namespace=None, **kwargs):
592 591 """Create a new completer for the command line.
593 592
594 593 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
595 594
596 595 If unspecified, the default namespace where completions are performed
597 596 is __main__ (technically, __main__.__dict__). Namespaces should be
598 597 given as dictionaries.
599 598
600 599 An optional second namespace can be given. This allows the completer
601 600 to handle cases where both the local and global scopes need to be
602 601 distinguished.
603 602 """
604 603
605 604 # Don't bind to namespace quite yet, but flag whether the user wants a
606 605 # specific namespace or to use __main__.__dict__. This will allow us
607 606 # to bind to __main__.__dict__ at completion time, not now.
608 607 if namespace is None:
609 608 self.use_main_ns = True
610 609 else:
611 610 self.use_main_ns = False
612 611 self.namespace = namespace
613 612
614 613 # The global namespace, if given, can be bound directly
615 614 if global_namespace is None:
616 615 self.global_namespace = {}
617 616 else:
618 617 self.global_namespace = global_namespace
619 618
620 619 super(Completer, self).__init__(**kwargs)
621 620
622 621 def complete(self, text, state):
623 622 """Return the next possible completion for 'text'.
624 623
625 624 This is called successively with state == 0, 1, 2, ... until it
626 625 returns None. The completion should begin with 'text'.
627 626
628 627 """
629 628 if self.use_main_ns:
630 629 self.namespace = __main__.__dict__
631 630
632 631 if state == 0:
633 632 if "." in text:
634 633 self.matches = self.attr_matches(text)
635 634 else:
636 635 self.matches = self.global_matches(text)
637 636 try:
638 637 return self.matches[state]
639 638 except IndexError:
640 639 return None
641 640
642 641 def global_matches(self, text):
643 642 """Compute matches when text is a simple name.
644 643
645 644 Return a list of all keywords, built-in functions and names currently
646 645 defined in self.namespace or self.global_namespace that match.
647 646
648 647 """
649 648 matches = []
650 649 match_append = matches.append
651 650 n = len(text)
652 651 for lst in [keyword.kwlist,
653 652 builtin_mod.__dict__.keys(),
654 653 self.namespace.keys(),
655 654 self.global_namespace.keys()]:
656 655 for word in lst:
657 656 if word[:n] == text and word != "__builtins__":
658 657 match_append(word)
659 658
660 659 snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
661 660 for lst in [self.namespace.keys(),
662 661 self.global_namespace.keys()]:
663 662 shortened = {"_".join([sub[0] for sub in word.split('_')]) : word
664 663 for word in lst if snake_case_re.match(word)}
665 664 for word in shortened.keys():
666 665 if word[:n] == text and word != "__builtins__":
667 666 match_append(shortened[word])
668 return [cast_unicode_py2(m) for m in matches]
667 return matches
669 668
670 669 def attr_matches(self, text):
671 670 """Compute matches when text contains a dot.
672 671
673 672 Assuming the text is of the form NAME.NAME....[NAME], and is
674 673 evaluatable in self.namespace or self.global_namespace, it will be
675 674 evaluated and its attributes (as revealed by dir()) are used as
676 675 possible completions. (For class instances, class members are are
677 676 also considered.)
678 677
679 678 WARNING: this can still invoke arbitrary C code, if an object
680 679 with a __getattr__ hook is evaluated.
681 680
682 681 """
683 682
684 683 # Another option, seems to work great. Catches things like ''.<tab>
685 684 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
686 685
687 686 if m:
688 687 expr, attr = m.group(1, 3)
689 688 elif self.greedy:
690 689 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
691 690 if not m2:
692 691 return []
693 692 expr, attr = m2.group(1,2)
694 693 else:
695 694 return []
696 695
697 696 try:
698 697 obj = eval(expr, self.namespace)
699 698 except:
700 699 try:
701 700 obj = eval(expr, self.global_namespace)
702 701 except:
703 702 return []
704 703
705 704 if self.limit_to__all__ and hasattr(obj, '__all__'):
706 705 words = get__all__entries(obj)
707 706 else:
708 707 words = dir2(obj)
709 708
710 709 try:
711 710 words = generics.complete_object(obj, words)
712 711 except TryNext:
713 712 pass
714 713 except AssertionError:
715 714 raise
716 715 except Exception:
717 716 # Silence errors from completion function
718 717 #raise # dbg
719 718 pass
720 719 # Build match list to return
721 720 n = len(attr)
722 721 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
723 722
724 723
725 724 def get__all__entries(obj):
726 725 """returns the strings in the __all__ attribute"""
727 726 try:
728 727 words = getattr(obj, '__all__')
729 728 except:
730 729 return []
731 730
732 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
731 return [w for w in words if isinstance(w, str)]
733 732
734 733
735 734 def match_dict_keys(keys: List[str], prefix: str, delims: str):
736 735 """Used by dict_key_matches, matching the prefix to a list of keys
737 736
738 737 Parameters
739 738 ==========
740 739 keys:
741 740 list of keys in dictionary currently being completed.
742 741 prefix:
743 742 Part of the text already typed by the user. e.g. `mydict[b'fo`
744 743 delims:
745 744 String of delimiters to consider when finding the current key.
746 745
747 746 Returns
748 747 =======
749 748
750 749 A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
751 750 ``quote`` being the quote that need to be used to close current string.
752 751 ``token_start`` the position where the replacement should start occurring,
753 752 ``matches`` a list of replacement/completion
754 753
755 754 """
756 755 if not prefix:
757 756 return None, 0, [repr(k) for k in keys
758 757 if isinstance(k, (str, bytes))]
759 758 quote_match = re.search('["\']', prefix)
760 759 quote = quote_match.group()
761 760 try:
762 761 prefix_str = eval(prefix + quote, {})
763 762 except Exception:
764 763 return None, 0, []
765 764
766 765 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
767 766 token_match = re.search(pattern, prefix, re.UNICODE)
768 767 token_start = token_match.start()
769 768 token_prefix = token_match.group()
770 769
771 770 matched = []
772 771 for key in keys:
773 772 try:
774 773 if not key.startswith(prefix_str):
775 774 continue
776 775 except (AttributeError, TypeError, UnicodeError):
777 776 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
778 777 continue
779 778
780 779 # reformat remainder of key to begin with prefix
781 780 rem = key[len(prefix_str):]
782 781 # force repr wrapped in '
783 782 rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
784 783 if rem_repr.startswith('u') and prefix[0] not in 'uU':
785 784 # Found key is unicode, but prefix is Py2 string.
786 785 # Therefore attempt to interpret key as string.
787 786 try:
788 787 rem_repr = repr(rem.encode('ascii') + '"')
789 788 except UnicodeEncodeError:
790 789 continue
791 790
792 791 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
793 792 if quote == '"':
794 793 # The entered prefix is quoted with ",
795 794 # but the match is quoted with '.
796 795 # A contained " hence needs escaping for comparison:
797 796 rem_repr = rem_repr.replace('"', '\\"')
798 797
799 798 # then reinsert prefix from start of token
800 799 matched.append('%s%s' % (token_prefix, rem_repr))
801 800 return quote, token_start, matched
802 801
803 802
804 803 def cursor_to_position(text:int, line:int, column:int)->int:
805 804 """
806 805
807 806 Convert the (line,column) position of the cursor in text to an offset in a
808 807 string.
809 808
810 809 Parameters
811 810 ----------
812 811
813 812 text : str
814 813 The text in which to calculate the cursor offset
815 814 line : int
816 815 Line of the cursor; 0-indexed
817 816 column : int
818 817 Column of the cursor 0-indexed
819 818
820 819 Return
821 820 ------
822 821 Position of the cursor in ``text``, 0-indexed.
823 822
824 823 See Also
825 824 --------
826 825 position_to_cursor: reciprocal of this function
827 826
828 827 """
829 828 lines = text.split('\n')
830 829 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
831 830
832 831 return sum(len(l) + 1 for l in lines[:line]) + column
833 832
834 833 def position_to_cursor(text:str, offset:int)->(int, int):
835 834 """
836 835 Convert the position of the cursor in text (0 indexed) to a line
837 836 number(0-indexed) and a column number (0-indexed) pair
838 837
839 838 Position should be a valid position in ``text``.
840 839
841 840 Parameters
842 841 ----------
843 842
844 843 text : str
845 844 The text in which to calculate the cursor offset
846 845 offset : int
847 846 Position of the cursor in ``text``, 0-indexed.
848 847
849 848 Return
850 849 ------
851 850 (line, column) : (int, int)
852 851 Line of the cursor; 0-indexed, column of the cursor 0-indexed
853 852
854 853
855 854 See Also
856 855 --------
857 856 cursor_to_position : reciprocal of this function
858 857
859 858
860 859 """
861 860
862 861 assert 0 < offset <= len(text) , "0 < %s <= %s" % (offset , len(text))
863 862
864 863 before = text[:offset]
865 864 blines = before.split('\n') # ! splitnes trim trailing \n
866 865 line = before.count('\n')
867 866 col = len(blines[-1])
868 867 return line, col
869 868
870 869
871 870 def _safe_isinstance(obj, module, class_name):
872 871 """Checks if obj is an instance of module.class_name if loaded
873 872 """
874 873 return (module in sys.modules and
875 874 isinstance(obj, getattr(import_module(module), class_name)))
876 875
877 876
878 877 def back_unicode_name_matches(text):
879 878 u"""Match unicode characters back to unicode name
880 879
881 880 This does ``β˜ƒ`` -> ``\\snowman``
882 881
883 882 Note that snowman is not a valid python3 combining character but will be expanded.
884 883 Though it will not recombine back to the snowman character by the completion machinery.
885 884
886 885 This will not either back-complete standard sequences like \\n, \\b ...
887 886
888 887 Used on Python 3 only.
889 888 """
890 889 if len(text)<2:
891 890 return u'', ()
892 891 maybe_slash = text[-2]
893 892 if maybe_slash != '\\':
894 893 return u'', ()
895 894
896 895 char = text[-1]
897 896 # no expand on quote for completion in strings.
898 897 # nor backcomplete standard ascii keys
899 898 if char in string.ascii_letters or char in ['"',"'"]:
900 899 return u'', ()
901 900 try :
902 901 unic = unicodedata.name(char)
903 902 return '\\'+char,['\\'+unic]
904 903 except KeyError:
905 904 pass
906 905 return u'', ()
907 906
908 907 def back_latex_name_matches(text:str):
909 908 """Match latex characters back to unicode name
910 909
911 910 This does ``\\β„΅`` -> ``\\aleph``
912 911
913 912 Used on Python 3 only.
914 913 """
915 914 if len(text)<2:
916 915 return u'', ()
917 916 maybe_slash = text[-2]
918 917 if maybe_slash != '\\':
919 918 return u'', ()
920 919
921 920
922 921 char = text[-1]
923 922 # no expand on quote for completion in strings.
924 923 # nor backcomplete standard ascii keys
925 924 if char in string.ascii_letters or char in ['"',"'"]:
926 925 return u'', ()
927 926 try :
928 927 latex = reverse_latex_symbol[char]
929 928 # '\\' replace the \ as well
930 929 return '\\'+char,[latex]
931 930 except KeyError:
932 931 pass
933 932 return u'', ()
934 933
935 934
936 935 class IPCompleter(Completer):
937 936 """Extension of the completer class with IPython-specific features"""
938 937
939 938 @observe('greedy')
940 939 def _greedy_changed(self, change):
941 940 """update the splitter and readline delims when greedy is changed"""
942 941 if change['new']:
943 942 self.splitter.delims = GREEDY_DELIMS
944 943 else:
945 944 self.splitter.delims = DELIMS
946 945
947 946 merge_completions = Bool(True,
948 947 help="""Whether to merge completion results into a single list
949 948
950 949 If False, only the completion results from the first non-empty
951 950 completer will be returned.
952 951 """
953 952 ).tag(config=True)
954 953 omit__names = Enum((0,1,2), default_value=2,
955 954 help="""Instruct the completer to omit private method names
956 955
957 956 Specifically, when completing on ``object.<tab>``.
958 957
959 958 When 2 [default]: all names that start with '_' will be excluded.
960 959
961 960 When 1: all 'magic' names (``__foo__``) will be excluded.
962 961
963 962 When 0: nothing will be excluded.
964 963 """
965 964 ).tag(config=True)
966 965 limit_to__all__ = Bool(False,
967 966 help="""
968 967 DEPRECATED as of version 5.0.
969 968
970 969 Instruct the completer to use __all__ for the completion
971 970
972 971 Specifically, when completing on ``object.<tab>``.
973 972
974 973 When True: only those names in obj.__all__ will be included.
975 974
976 975 When False [default]: the __all__ attribute is ignored
977 976 """,
978 977 ).tag(config=True)
979 978
980 979 @observe('limit_to__all__')
981 980 def _limit_to_all_changed(self, change):
982 981 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
983 982 'value has been deprecated since IPython 5.0, will be made to have '
984 983 'no effects and then removed in future version of IPython.',
985 984 UserWarning)
986 985
987 986 def __init__(self, shell=None, namespace=None, global_namespace=None,
988 987 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
989 988 """IPCompleter() -> completer
990 989
991 990 Return a completer object.
992 991
993 992 Parameters
994 993 ----------
995 994
996 995 shell
997 996 a pointer to the ipython shell itself. This is needed
998 997 because this completer knows about magic functions, and those can
999 998 only be accessed via the ipython instance.
1000 999
1001 1000 namespace : dict, optional
1002 1001 an optional dict where completions are performed.
1003 1002
1004 1003 global_namespace : dict, optional
1005 1004 secondary optional dict for completions, to
1006 1005 handle cases (such as IPython embedded inside functions) where
1007 1006 both Python scopes are visible.
1008 1007
1009 1008 use_readline : bool, optional
1010 1009 DEPRECATED, ignored since IPython 6.0, will have no effects
1011 1010 """
1012 1011
1013 1012 self.magic_escape = ESC_MAGIC
1014 1013 self.splitter = CompletionSplitter()
1015 1014
1016 1015 if use_readline is not _deprecation_readline_sentinel:
1017 1016 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
1018 1017 DeprecationWarning, stacklevel=2)
1019 1018
1020 1019 # _greedy_changed() depends on splitter and readline being defined:
1021 1020 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
1022 1021 config=config, **kwargs)
1023 1022
1024 1023 # List where completion matches will be stored
1025 1024 self.matches = []
1026 1025 self.shell = shell
1027 1026 # Regexp to split filenames with spaces in them
1028 1027 self.space_name_re = re.compile(r'([^\\] )')
1029 1028 # Hold a local ref. to glob.glob for speed
1030 1029 self.glob = glob.glob
1031 1030
1032 1031 # Determine if we are running on 'dumb' terminals, like (X)Emacs
1033 1032 # buffers, to avoid completion problems.
1034 1033 term = os.environ.get('TERM','xterm')
1035 1034 self.dumb_terminal = term in ['dumb','emacs']
1036 1035
1037 1036 # Special handling of backslashes needed in win32 platforms
1038 1037 if sys.platform == "win32":
1039 1038 self.clean_glob = self._clean_glob_win32
1040 1039 else:
1041 1040 self.clean_glob = self._clean_glob
1042 1041
1043 1042 #regexp to parse docstring for function signature
1044 1043 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1045 1044 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1046 1045 #use this if positional argument name is also needed
1047 1046 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
1048 1047
1049 1048 # All active matcher routines for completion
1050 1049 self.matchers = [
1051 1050 self.python_matches,
1052 1051 self.file_matches,
1053 1052 self.magic_config_matches,
1054 1053 self.magic_matches,
1055 1054 self.python_func_kw_matches,
1056 1055 self.dict_key_matches,
1057 1056 ]
1058 1057
1059 1058 # This is set externally by InteractiveShell
1060 1059 self.custom_completers = None
1061 1060
1062 1061 def all_completions(self, text):
1063 1062 """
1064 1063 Wrapper around the complete method for the benefit of emacs.
1065 1064 """
1066 1065 return self.complete(text)[1]
1067 1066
1068 1067 def _clean_glob(self, text):
1069 1068 return self.glob("%s*" % text)
1070 1069
1071 1070 def _clean_glob_win32(self,text):
1072 1071 return [f.replace("\\","/")
1073 1072 for f in self.glob("%s*" % text)]
1074 1073
1075 1074 def file_matches(self, text):
1076 1075 """Match filenames, expanding ~USER type strings.
1077 1076
1078 1077 Most of the seemingly convoluted logic in this completer is an
1079 1078 attempt to handle filenames with spaces in them. And yet it's not
1080 1079 quite perfect, because Python's readline doesn't expose all of the
1081 1080 GNU readline details needed for this to be done correctly.
1082 1081
1083 1082 For a filename with a space in it, the printed completions will be
1084 1083 only the parts after what's already been typed (instead of the
1085 1084 full completions, as is normally done). I don't think with the
1086 1085 current (as of Python 2.3) Python readline it's possible to do
1087 1086 better."""
1088 1087
1089 1088 # chars that require escaping with backslash - i.e. chars
1090 1089 # that readline treats incorrectly as delimiters, but we
1091 1090 # don't want to treat as delimiters in filename matching
1092 1091 # when escaped with backslash
1093 1092 if text.startswith('!'):
1094 1093 text = text[1:]
1095 1094 text_prefix = u'!'
1096 1095 else:
1097 1096 text_prefix = u''
1098 1097
1099 1098 text_until_cursor = self.text_until_cursor
1100 1099 # track strings with open quotes
1101 1100 open_quotes = has_open_quotes(text_until_cursor)
1102 1101
1103 1102 if '(' in text_until_cursor or '[' in text_until_cursor:
1104 1103 lsplit = text
1105 1104 else:
1106 1105 try:
1107 1106 # arg_split ~ shlex.split, but with unicode bugs fixed by us
1108 1107 lsplit = arg_split(text_until_cursor)[-1]
1109 1108 except ValueError:
1110 1109 # typically an unmatched ", or backslash without escaped char.
1111 1110 if open_quotes:
1112 1111 lsplit = text_until_cursor.split(open_quotes)[-1]
1113 1112 else:
1114 1113 return []
1115 1114 except IndexError:
1116 1115 # tab pressed on empty line
1117 1116 lsplit = ""
1118 1117
1119 1118 if not open_quotes and lsplit != protect_filename(lsplit):
1120 1119 # if protectables are found, do matching on the whole escaped name
1121 1120 has_protectables = True
1122 1121 text0,text = text,lsplit
1123 1122 else:
1124 1123 has_protectables = False
1125 1124 text = os.path.expanduser(text)
1126 1125
1127 1126 if text == "":
1128 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
1127 return [text_prefix + protect_filename(f) for f in self.glob("*")]
1129 1128
1130 1129 # Compute the matches from the filesystem
1131 1130 if sys.platform == 'win32':
1132 1131 m0 = self.clean_glob(text)
1133 1132 else:
1134 1133 m0 = self.clean_glob(text.replace('\\', ''))
1135 1134
1136 1135 if has_protectables:
1137 1136 # If we had protectables, we need to revert our changes to the
1138 1137 # beginning of filename so that we don't double-write the part
1139 1138 # of the filename we have so far
1140 1139 len_lsplit = len(lsplit)
1141 1140 matches = [text_prefix + text0 +
1142 1141 protect_filename(f[len_lsplit:]) for f in m0]
1143 1142 else:
1144 1143 if open_quotes:
1145 1144 # if we have a string with an open quote, we don't need to
1146 1145 # protect the names beyond the quote (and we _shouldn't_, as
1147 1146 # it would cause bugs when the filesystem call is made).
1148 1147 matches = m0 if sys.platform == "win32" else\
1149 1148 [protect_filename(f, open_quotes) for f in m0]
1150 1149 else:
1151 1150 matches = [text_prefix +
1152 1151 protect_filename(f) for f in m0]
1153 1152
1154 1153 # Mark directories in input list by appending '/' to their names.
1155 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
1154 return [x+'/' if os.path.isdir(x) else x for x in matches]
1156 1155
1157 1156 def magic_matches(self, text):
1158 1157 """Match magics"""
1159 1158 # Get all shell magics now rather than statically, so magics loaded at
1160 1159 # runtime show up too.
1161 1160 lsm = self.shell.magics_manager.lsmagic()
1162 1161 line_magics = lsm['line']
1163 1162 cell_magics = lsm['cell']
1164 1163 pre = self.magic_escape
1165 1164 pre2 = pre+pre
1166 1165
1167 1166 # Completion logic:
1168 1167 # - user gives %%: only do cell magics
1169 1168 # - user gives %: do both line and cell magics
1170 1169 # - no prefix: do both
1171 1170 # In other words, line magics are skipped if the user gives %% explicitly
1172 1171 #
1173 1172 # We also exclude magics that match any currently visible names:
1174 1173 # https://github.com/ipython/ipython/issues/4877
1175 1174 bare_text = text.lstrip(pre)
1176 1175 global_matches = self.global_matches(bare_text)
1177 1176 matches = lambda magic: magic.startswith(bare_text) \
1178 1177 and magic not in global_matches
1179 1178 comp = [ pre2+m for m in cell_magics if matches(m)]
1180 1179 if not text.startswith(pre2):
1181 1180 comp += [ pre+m for m in line_magics if matches(m)]
1182 1181
1183 return [cast_unicode_py2(c) for c in comp]
1182 return comp
1184 1183
1185 1184 def magic_config_matches(self, text):
1186 1185 """ Match class names and attributes for %config magic """
1187 1186 # use line buffer instead of text (which is a word)
1188 1187 texts = self.line_buffer.strip().split()
1189 1188
1190 1189 if len(texts) > 0 and \
1191 1190 ('config'.startswith(texts[0]) or '%config'.startswith(texts[0])):
1192 1191 # get all configuration classes
1193 1192 classes = sorted(set([ c for c in self.shell.configurables
1194 1193 if c.__class__.class_traits(config=True)
1195 1194 ]), key=lambda x: x.__class__.__name__)
1196 1195 classnames = [ c.__class__.__name__ for c in classes ]
1197 1196
1198 1197 # return all classnames if config or %config is given
1199 1198 if len(texts) == 1:
1200 1199 return classnames
1201 1200
1202 1201 # match classname
1203 1202 classname_texts = texts[1].split('.')
1204 1203 classname = classname_texts[0]
1205 1204 classname_matches = [ c for c in classnames
1206 1205 if c.startswith(classname) ]
1207 1206
1208 1207 # return matched classes or the matched class with attributes
1209 1208 if texts[1].find('.') < 0:
1210 1209 return classname_matches
1211 1210 elif len(classname_matches) == 1 and \
1212 1211 classname_matches[0] == classname:
1213 1212 cls = classes[classnames.index(classname)].__class__
1214 1213 help = cls.class_get_help()
1215 1214 # strip leading '--' from cl-args:
1216 1215 help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
1217 1216 return [ attr.split('=')[0]
1218 1217 for attr in help.strip().splitlines()
1219 1218 if attr.startswith(texts[1]) ]
1220 1219 return []
1221 1220
1222 1221 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1223 1222 """
1224 1223
1225 1224 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1226 1225 cursor position.
1227 1226
1228 1227 Parameters
1229 1228 ----------
1230 1229 cursor_column : int
1231 1230 column position of the cursor in ``text``, 0-indexed.
1232 1231 cursor_line : int
1233 1232 line position of the cursor in ``text``, 0-indexed
1234 1233 text : str
1235 1234 text to complete
1236 1235
1237 1236 Debugging
1238 1237 ---------
1239 1238
1240 1239 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1241 1240 object containing a string with the Jedi debug information attached.
1242 1241 """
1243 1242 namespaces = [self.namespace]
1244 1243 if self.global_namespace is not None:
1245 1244 namespaces.append(self.global_namespace)
1246 1245
1247 1246 completion_filter = lambda x:x
1248 1247 # cursor_pos is an it, jedi wants line and column
1249 1248 offset = cursor_to_position(text, cursor_line, cursor_column)
1250 1249 # filter output if we are completing for object members
1251 1250 if offset:
1252 1251 pre = text[offset-1]
1253 1252 if pre == '.':
1254 1253 if self.omit__names == 2:
1255 1254 completion_filter = lambda c:not c.name.startswith('_')
1256 1255 elif self.omit__names == 1:
1257 1256 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1258 1257 elif self.omit__names == 0:
1259 1258 completion_filter = lambda x:x
1260 1259 else:
1261 1260 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1262 1261
1263 1262 interpreter = jedi.Interpreter(
1264 1263 text, namespaces, column=cursor_column, line=cursor_line + 1)
1265 1264
1266 1265 try_jedi = False
1267 1266
1268 1267 try:
1269 1268 # should we check the type of the node is Error ?
1270 1269 from jedi.parser.tree import ErrorLeaf
1271 1270 next_to_last_tree = interpreter._get_module().tree_node.children[-2]
1272 1271 completing_string = False
1273 1272 if isinstance(next_to_last_tree, ErrorLeaf):
1274 1273 completing_string = interpreter._get_module().tree_node.children[-2].value[0] in {'"', "'"}
1275 1274 # if we are in a string jedi is likely not the right candidate for
1276 1275 # now. Skip it.
1277 1276 try_jedi = not completing_string
1278 1277 except Exception as e:
1279 1278 # many of things can go wrong, we are using private API just don't crash.
1280 1279 if self.debug:
1281 1280 print("Error detecting if completing a non-finished string :", e, '|')
1282 1281
1283 1282 if not try_jedi:
1284 1283 return []
1285 1284 try:
1286 1285 return filter(completion_filter, interpreter.completions())
1287 1286 except Exception as e:
1288 1287 if self.debug:
1289 1288 return [_FakeJediCompletion('Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1290 1289 else:
1291 1290 return []
1292 1291
1293 1292 def python_matches(self, text):
1294 1293 """Match attributes or global python names"""
1295 1294 if "." in text:
1296 1295 try:
1297 1296 matches = self.attr_matches(text)
1298 1297 if text.endswith('.') and self.omit__names:
1299 1298 if self.omit__names == 1:
1300 1299 # true if txt is _not_ a __ name, false otherwise:
1301 1300 no__name = (lambda txt:
1302 1301 re.match(r'.*\.__.*?__',txt) is None)
1303 1302 else:
1304 1303 # true if txt is _not_ a _ name, false otherwise:
1305 1304 no__name = (lambda txt:
1306 1305 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1307 1306 matches = filter(no__name, matches)
1308 1307 except NameError:
1309 1308 # catches <undefined attributes>.<tab>
1310 1309 matches = []
1311 1310 else:
1312 1311 matches = self.global_matches(text)
1313 1312 return matches
1314 1313
1315 1314 def _default_arguments_from_docstring(self, doc):
1316 1315 """Parse the first line of docstring for call signature.
1317 1316
1318 1317 Docstring should be of the form 'min(iterable[, key=func])\n'.
1319 1318 It can also parse cython docstring of the form
1320 1319 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1321 1320 """
1322 1321 if doc is None:
1323 1322 return []
1324 1323
1325 1324 #care only the firstline
1326 1325 line = doc.lstrip().splitlines()[0]
1327 1326
1328 1327 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1329 1328 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1330 1329 sig = self.docstring_sig_re.search(line)
1331 1330 if sig is None:
1332 1331 return []
1333 1332 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1334 1333 sig = sig.groups()[0].split(',')
1335 1334 ret = []
1336 1335 for s in sig:
1337 1336 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1338 1337 ret += self.docstring_kwd_re.findall(s)
1339 1338 return ret
1340 1339
1341 1340 def _default_arguments(self, obj):
1342 1341 """Return the list of default arguments of obj if it is callable,
1343 1342 or empty list otherwise."""
1344 1343 call_obj = obj
1345 1344 ret = []
1346 1345 if inspect.isbuiltin(obj):
1347 1346 pass
1348 1347 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1349 1348 if inspect.isclass(obj):
1350 1349 #for cython embededsignature=True the constructor docstring
1351 1350 #belongs to the object itself not __init__
1352 1351 ret += self._default_arguments_from_docstring(
1353 1352 getattr(obj, '__doc__', ''))
1354 1353 # for classes, check for __init__,__new__
1355 1354 call_obj = (getattr(obj, '__init__', None) or
1356 1355 getattr(obj, '__new__', None))
1357 1356 # for all others, check if they are __call__able
1358 1357 elif hasattr(obj, '__call__'):
1359 1358 call_obj = obj.__call__
1360 1359 ret += self._default_arguments_from_docstring(
1361 1360 getattr(call_obj, '__doc__', ''))
1362 1361
1363 1362 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1364 1363 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1365 1364
1366 1365 try:
1367 1366 sig = inspect.signature(call_obj)
1368 1367 ret.extend(k for k, v in sig.parameters.items() if
1369 1368 v.kind in _keeps)
1370 1369 except ValueError:
1371 1370 pass
1372 1371
1373 1372 return list(set(ret))
1374 1373
1375 1374 def python_func_kw_matches(self,text):
1376 1375 """Match named parameters (kwargs) of the last open function"""
1377 1376
1378 1377 if "." in text: # a parameter cannot be dotted
1379 1378 return []
1380 1379 try: regexp = self.__funcParamsRegex
1381 1380 except AttributeError:
1382 1381 regexp = self.__funcParamsRegex = re.compile(r'''
1383 1382 '.*?(?<!\\)' | # single quoted strings or
1384 1383 ".*?(?<!\\)" | # double quoted strings or
1385 1384 \w+ | # identifier
1386 1385 \S # other characters
1387 1386 ''', re.VERBOSE | re.DOTALL)
1388 1387 # 1. find the nearest identifier that comes before an unclosed
1389 1388 # parenthesis before the cursor
1390 1389 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1391 1390 tokens = regexp.findall(self.text_until_cursor)
1392 1391 iterTokens = reversed(tokens); openPar = 0
1393 1392
1394 1393 for token in iterTokens:
1395 1394 if token == ')':
1396 1395 openPar -= 1
1397 1396 elif token == '(':
1398 1397 openPar += 1
1399 1398 if openPar > 0:
1400 1399 # found the last unclosed parenthesis
1401 1400 break
1402 1401 else:
1403 1402 return []
1404 1403 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1405 1404 ids = []
1406 1405 isId = re.compile(r'\w+$').match
1407 1406
1408 1407 while True:
1409 1408 try:
1410 1409 ids.append(next(iterTokens))
1411 1410 if not isId(ids[-1]):
1412 1411 ids.pop(); break
1413 1412 if not next(iterTokens) == '.':
1414 1413 break
1415 1414 except StopIteration:
1416 1415 break
1417 1416
1418 1417 # Find all named arguments already assigned to, as to avoid suggesting
1419 1418 # them again
1420 1419 usedNamedArgs = set()
1421 1420 par_level = -1
1422 1421 for token, next_token in zip(tokens, tokens[1:]):
1423 1422 if token == '(':
1424 1423 par_level += 1
1425 1424 elif token == ')':
1426 1425 par_level -= 1
1427 1426
1428 1427 if par_level != 0:
1429 1428 continue
1430 1429
1431 1430 if next_token != '=':
1432 1431 continue
1433 1432
1434 1433 usedNamedArgs.add(token)
1435 1434
1436 1435 # lookup the candidate callable matches either using global_matches
1437 1436 # or attr_matches for dotted names
1438 1437 if len(ids) == 1:
1439 1438 callableMatches = self.global_matches(ids[0])
1440 1439 else:
1441 1440 callableMatches = self.attr_matches('.'.join(ids[::-1]))
1442 1441 argMatches = []
1443 1442 for callableMatch in callableMatches:
1444 1443 try:
1445 1444 namedArgs = self._default_arguments(eval(callableMatch,
1446 1445 self.namespace))
1447 1446 except:
1448 1447 continue
1449 1448
1450 1449 # Remove used named arguments from the list, no need to show twice
1451 1450 for namedArg in set(namedArgs) - usedNamedArgs:
1452 1451 if namedArg.startswith(text):
1453 1452 argMatches.append(u"%s=" %namedArg)
1454 1453 return argMatches
1455 1454
1456 1455 def dict_key_matches(self, text):
1457 1456 "Match string keys in a dictionary, after e.g. 'foo[' "
1458 1457 def get_keys(obj):
1459 1458 # Objects can define their own completions by defining an
1460 1459 # _ipy_key_completions_() method.
1461 1460 method = get_real_method(obj, '_ipython_key_completions_')
1462 1461 if method is not None:
1463 1462 return method()
1464 1463
1465 1464 # Special case some common in-memory dict-like types
1466 1465 if isinstance(obj, dict) or\
1467 1466 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1468 1467 try:
1469 1468 return list(obj.keys())
1470 1469 except Exception:
1471 1470 return []
1472 1471 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1473 1472 _safe_isinstance(obj, 'numpy', 'void'):
1474 1473 return obj.dtype.names or []
1475 1474 return []
1476 1475
1477 1476 try:
1478 1477 regexps = self.__dict_key_regexps
1479 1478 except AttributeError:
1480 1479 dict_key_re_fmt = r'''(?x)
1481 1480 ( # match dict-referring expression wrt greedy setting
1482 1481 %s
1483 1482 )
1484 1483 \[ # open bracket
1485 1484 \s* # and optional whitespace
1486 1485 ([uUbB]? # string prefix (r not handled)
1487 1486 (?: # unclosed string
1488 1487 '(?:[^']|(?<!\\)\\')*
1489 1488 |
1490 1489 "(?:[^"]|(?<!\\)\\")*
1491 1490 )
1492 1491 )?
1493 1492 $
1494 1493 '''
1495 1494 regexps = self.__dict_key_regexps = {
1496 1495 False: re.compile(dict_key_re_fmt % '''
1497 1496 # identifiers separated by .
1498 1497 (?!\d)\w+
1499 1498 (?:\.(?!\d)\w+)*
1500 1499 '''),
1501 1500 True: re.compile(dict_key_re_fmt % '''
1502 1501 .+
1503 1502 ''')
1504 1503 }
1505 1504
1506 1505 match = regexps[self.greedy].search(self.text_until_cursor)
1507 1506 if match is None:
1508 1507 return []
1509 1508
1510 1509 expr, prefix = match.groups()
1511 1510 try:
1512 1511 obj = eval(expr, self.namespace)
1513 1512 except Exception:
1514 1513 try:
1515 1514 obj = eval(expr, self.global_namespace)
1516 1515 except Exception:
1517 1516 return []
1518 1517
1519 1518 keys = get_keys(obj)
1520 1519 if not keys:
1521 1520 return keys
1522 1521 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1523 1522 if not matches:
1524 1523 return matches
1525 1524
1526 1525 # get the cursor position of
1527 1526 # - the text being completed
1528 1527 # - the start of the key text
1529 1528 # - the start of the completion
1530 1529 text_start = len(self.text_until_cursor) - len(text)
1531 1530 if prefix:
1532 1531 key_start = match.start(2)
1533 1532 completion_start = key_start + token_offset
1534 1533 else:
1535 1534 key_start = completion_start = match.end()
1536 1535
1537 1536 # grab the leading prefix, to make sure all completions start with `text`
1538 1537 if text_start > key_start:
1539 1538 leading = ''
1540 1539 else:
1541 1540 leading = text[text_start:completion_start]
1542 1541
1543 1542 # the index of the `[` character
1544 1543 bracket_idx = match.end(1)
1545 1544
1546 1545 # append closing quote and bracket as appropriate
1547 1546 # this is *not* appropriate if the opening quote or bracket is outside
1548 1547 # the text given to this method
1549 1548 suf = ''
1550 1549 continuation = self.line_buffer[len(self.text_until_cursor):]
1551 1550 if key_start > text_start and closing_quote:
1552 1551 # quotes were opened inside text, maybe close them
1553 1552 if continuation.startswith(closing_quote):
1554 1553 continuation = continuation[len(closing_quote):]
1555 1554 else:
1556 1555 suf += closing_quote
1557 1556 if bracket_idx > text_start:
1558 1557 # brackets were opened inside text, maybe close them
1559 1558 if not continuation.startswith(']'):
1560 1559 suf += ']'
1561 1560
1562 1561 return [leading + k + suf for k in matches]
1563 1562
1564 1563 def unicode_name_matches(self, text):
1565 1564 u"""Match Latex-like syntax for unicode characters base
1566 1565 on the name of the character.
1567 1566
1568 1567 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1569 1568
1570 1569 Works only on valid python 3 identifier, or on combining characters that
1571 1570 will combine to form a valid identifier.
1572 1571
1573 1572 Used on Python 3 only.
1574 1573 """
1575 1574 slashpos = text.rfind('\\')
1576 1575 if slashpos > -1:
1577 1576 s = text[slashpos+1:]
1578 1577 try :
1579 1578 unic = unicodedata.lookup(s)
1580 1579 # allow combining chars
1581 1580 if ('a'+unic).isidentifier():
1582 1581 return '\\'+s,[unic]
1583 1582 except KeyError:
1584 1583 pass
1585 1584 return u'', []
1586 1585
1587 1586
1588 1587 def latex_matches(self, text):
1589 1588 u"""Match Latex syntax for unicode characters.
1590 1589
1591 1590 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1592 1591
1593 1592 Used on Python 3 only.
1594 1593 """
1595 1594 slashpos = text.rfind('\\')
1596 1595 if slashpos > -1:
1597 1596 s = text[slashpos:]
1598 1597 if s in latex_symbols:
1599 1598 # Try to complete a full latex symbol to unicode
1600 1599 # \\alpha -> Ξ±
1601 1600 return s, [latex_symbols[s]]
1602 1601 else:
1603 1602 # If a user has partially typed a latex symbol, give them
1604 1603 # a full list of options \al -> [\aleph, \alpha]
1605 1604 matches = [k for k in latex_symbols if k.startswith(s)]
1606 1605 return s, matches
1607 1606 return u'', []
1608 1607
1609 1608 def dispatch_custom_completer(self, text):
1610 1609 if not self.custom_completers:
1611 1610 return
1612 1611
1613 1612 line = self.line_buffer
1614 1613 if not line.strip():
1615 1614 return None
1616 1615
1617 1616 # Create a little structure to pass all the relevant information about
1618 1617 # the current completion to any custom completer.
1619 1618 event = SimpleNamespace()
1620 1619 event.line = line
1621 1620 event.symbol = text
1622 1621 cmd = line.split(None,1)[0]
1623 1622 event.command = cmd
1624 1623 event.text_until_cursor = self.text_until_cursor
1625 1624
1626 1625 # for foo etc, try also to find completer for %foo
1627 1626 if not cmd.startswith(self.magic_escape):
1628 1627 try_magic = self.custom_completers.s_matches(
1629 1628 self.magic_escape + cmd)
1630 1629 else:
1631 1630 try_magic = []
1632 1631
1633 1632 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1634 1633 try_magic,
1635 1634 self.custom_completers.flat_matches(self.text_until_cursor)):
1636 1635 try:
1637 1636 res = c(event)
1638 1637 if res:
1639 1638 # first, try case sensitive match
1640 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1639 withcase = [r for r in res if r.startswith(text)]
1641 1640 if withcase:
1642 1641 return withcase
1643 1642 # if none, then case insensitive ones are ok too
1644 1643 text_low = text.lower()
1645 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1644 return [r for r in res if r.lower().startswith(text_low)]
1646 1645 except TryNext:
1647 1646 pass
1648 1647
1649 1648 return None
1650 1649
1651 1650 def completions(self, text: str, offset: int)->Iterator[Completion]:
1652 1651 """
1653 1652 Returns an iterator over the possible completions
1654 1653
1655 1654 .. warning:: Unstable
1656 1655
1657 1656 This function is unstable, API may change without warning.
1658 1657 It will also raise unless use in proper context manager.
1659 1658
1660 1659 Parameters
1661 1660 ----------
1662 1661
1663 1662 text:str
1664 1663 Full text of the current input, multi line string.
1665 1664 offset:int
1666 1665 Integer representing the position of the cursor in ``text``. Offset
1667 1666 is 0-based indexed.
1668 1667
1669 1668 Yields
1670 1669 ------
1671 1670 :any:`Completion` object
1672 1671
1673 1672
1674 1673 The cursor on a text can either be seen as being "in between"
1675 1674 characters or "On" a character depending on the interface visible to
1676 1675 the user. For consistency the cursor being on "in between" characters X
1677 1676 and Y is equivalent to the cursor being "on" character Y, that is to say
1678 1677 the character the cursor is on is considered as being after the cursor.
1679 1678
1680 1679 Combining characters may span more that one position in the
1681 1680 text.
1682 1681
1683 1682
1684 1683 .. note::
1685 1684
1686 1685 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1687 1686 fake Completion token to distinguish completion returned by Jedi
1688 1687 and usual IPython completion.
1689 1688
1690 1689 .. note::
1691 1690
1692 1691 Completions are not completely deduplicated yet. If identical
1693 1692 completions are coming from different sources this function does not
1694 1693 ensure that each completion object will only be present once.
1695 1694 """
1696 1695 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1697 1696 "It may change without warnings. "
1698 1697 "Use in corresponding context manager.",
1699 1698 category=ProvisionalCompleterWarning, stacklevel=2)
1700 1699
1701 1700 seen = set()
1702 1701 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1703 1702 if c and (c in seen):
1704 1703 continue
1705 1704 yield c
1706 1705 seen.add(c)
1707 1706
1708 1707 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1709 1708 """
1710 1709 Core completion module.Same signature as :any:`completions`, with the
1711 1710 extra `timeout` parameter (in seconds).
1712 1711
1713 1712
1714 1713 Computing jedi's completion ``.type`` can be quite expensive (it is a
1715 1714 lazy property) and can require some warm-up, more warm up than just
1716 1715 computing the ``name`` of a completion. The warm-up can be :
1717 1716
1718 1717 - Long warm-up the first time a module is encountered after
1719 1718 install/update: actually build parse/inference tree.
1720 1719
1721 1720 - first time the module is encountered in a session: load tree from
1722 1721 disk.
1723 1722
1724 1723 We don't want to block completions for tens of seconds so we give the
1725 1724 completer a "budget" of ``_timeout`` seconds per invocation to compute
1726 1725 completions types, the completions that have not yet been computed will
1727 1726 be marked as "unknown" an will have a chance to be computed next round
1728 1727 are things get cached.
1729 1728
1730 1729 Keep in mind that Jedi is not the only thing treating the completion so
1731 1730 keep the timeout short-ish as if we take more than 0.3 second we still
1732 1731 have lots of processing to do.
1733 1732
1734 1733 """
1735 1734 deadline = time.monotonic() + _timeout
1736 1735
1737 1736
1738 1737 before = full_text[:offset]
1739 1738 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1740 1739
1741 1740 matched_text, matches, matches_origin, jedi_matches = self._complete(
1742 1741 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1743 1742
1744 1743 iter_jm = iter(jedi_matches)
1745 1744 if _timeout:
1746 1745 for jm in iter_jm:
1747 1746 try:
1748 1747 type_ = jm.type
1749 1748 except Exception:
1750 1749 if self.debug:
1751 1750 print("Error in Jedi getting type of ", jm)
1752 1751 type_ = None
1753 1752 delta = len(jm.name_with_symbols) - len(jm.complete)
1754 1753 yield Completion(start=offset - delta,
1755 1754 end=offset,
1756 1755 text=jm.name_with_symbols,
1757 1756 type=type_,
1758 1757 _origin='jedi')
1759 1758
1760 1759 if time.monotonic() > deadline:
1761 1760 break
1762 1761
1763 1762 for jm in iter_jm:
1764 1763 delta = len(jm.name_with_symbols) - len(jm.complete)
1765 1764 yield Completion(start=offset - delta,
1766 1765 end=offset,
1767 1766 text=jm.name_with_symbols,
1768 1767 type='<unknown>', # don't compute type for speed
1769 1768 _origin='jedi')
1770 1769
1771 1770
1772 1771 start_offset = before.rfind(matched_text)
1773 1772
1774 1773 # TODO:
1775 1774 # Supress this, right now just for debug.
1776 1775 if jedi_matches and matches and self.debug:
1777 1776 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--', _origin='debug')
1778 1777
1779 1778 # I'm unsure if this is always true, so let's assert and see if it
1780 1779 # crash
1781 1780 assert before.endswith(matched_text)
1782 1781 for m, t in zip(matches, matches_origin):
1783 1782 yield Completion(start=start_offset, end=offset, text=m, _origin=t)
1784 1783
1785 1784
1786 1785 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1787 1786 """Find completions for the given text and line context.
1788 1787
1789 1788 Note that both the text and the line_buffer are optional, but at least
1790 1789 one of them must be given.
1791 1790
1792 1791 Parameters
1793 1792 ----------
1794 1793 text : string, optional
1795 1794 Text to perform the completion on. If not given, the line buffer
1796 1795 is split using the instance's CompletionSplitter object.
1797 1796
1798 1797 line_buffer : string, optional
1799 1798 If not given, the completer attempts to obtain the current line
1800 1799 buffer via readline. This keyword allows clients which are
1801 1800 requesting for text completions in non-readline contexts to inform
1802 1801 the completer of the entire text.
1803 1802
1804 1803 cursor_pos : int, optional
1805 1804 Index of the cursor in the full line buffer. Should be provided by
1806 1805 remote frontends where kernel has no access to frontend state.
1807 1806
1808 1807 Returns
1809 1808 -------
1810 1809 text : str
1811 1810 Text that was actually used in the completion.
1812 1811
1813 1812 matches : list
1814 1813 A list of completion matches.
1815 1814
1816 1815
1817 1816 .. note::
1818 1817
1819 1818 This API is likely to be deprecated and replaced by
1820 1819 :any:`IPCompleter.completions` in the future.
1821 1820
1822 1821
1823 1822 """
1824 1823 warnings.warn('`Completer.complete` is pending deprecation since '
1825 1824 'IPython 6.0 and will be replaced by `Completer.completions`.',
1826 1825 PendingDeprecationWarning)
1827 1826 # potential todo, FOLD the 3rd throw away argument of _complete
1828 1827 # into the first 2 one.
1829 1828 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1830 1829
1831 1830 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1832 1831 full_text=None, return_jedi_results=True) -> (str, List[str], List[object]):
1833 1832 """
1834 1833
1835 1834 Like complete but can also returns raw jedi completions as well as the
1836 1835 origin of the completion text. This could (and should) be made much
1837 1836 cleaner but that will be simpler once we drop the old (and stateful)
1838 1837 :any:`complete` API.
1839 1838
1840 1839
1841 1840 With current provisional API, cursor_pos act both (depending on the
1842 1841 caller) as the offset in the ``text`` or ``line_buffer``, or as the
1843 1842 ``column`` when passing multiline strings this could/should be renamed
1844 1843 but would add extra noise.
1845 1844 """
1846 1845
1847 1846 # if the cursor position isn't given, the only sane assumption we can
1848 1847 # make is that it's at the end of the line (the common case)
1849 1848 if cursor_pos is None:
1850 1849 cursor_pos = len(line_buffer) if text is None else len(text)
1851 1850
1852 1851 if self.use_main_ns:
1853 1852 self.namespace = __main__.__dict__
1854 1853
1855 1854 # if text is either None or an empty string, rely on the line buffer
1856 1855 if (not line_buffer) and full_text:
1857 1856 line_buffer = full_text.split('\n')[cursor_line]
1858 1857 if not text:
1859 1858 text = self.splitter.split_line(line_buffer, cursor_pos)
1860 1859
1861 1860 if self.backslash_combining_completions:
1862 1861 # allow deactivation of these on windows.
1863 1862 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1864 1863 latex_text, latex_matches = self.latex_matches(base_text)
1865 1864 if latex_matches:
1866 1865 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
1867 1866 name_text = ''
1868 1867 name_matches = []
1869 1868 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1870 1869 name_text, name_matches = meth(base_text)
1871 1870 if name_text:
1872 1871 return name_text, name_matches, [meth.__qualname__]*len(name_matches), {}
1873 1872
1874 1873
1875 1874 # If no line buffer is given, assume the input text is all there was
1876 1875 if line_buffer is None:
1877 1876 line_buffer = text
1878 1877
1879 1878 self.line_buffer = line_buffer
1880 1879 self.text_until_cursor = self.line_buffer[:cursor_pos]
1881 1880
1882 1881 # Start with a clean slate of completions
1883 1882 matches = []
1884 1883 custom_res = self.dispatch_custom_completer(text)
1885 1884 # FIXME: we should extend our api to return a dict with completions for
1886 1885 # different types of objects. The rlcomplete() method could then
1887 1886 # simply collapse the dict into a list for readline, but we'd have
1888 1887 # richer completion semantics in other evironments.
1889 1888 completions = ()
1890 1889 if self.use_jedi and return_jedi_results:
1891 1890 if not full_text:
1892 1891 full_text = line_buffer
1893 1892 completions = self._jedi_matches(
1894 1893 cursor_pos, cursor_line, full_text)
1895 1894 if custom_res is not None:
1896 1895 # did custom completers produce something?
1897 1896 matches = [(m, 'custom') for m in custom_res]
1898 1897 else:
1899 1898 # Extend the list of completions with the results of each
1900 1899 # matcher, so we return results to the user from all
1901 1900 # namespaces.
1902 1901 if self.merge_completions:
1903 1902 matches = []
1904 1903 for matcher in self.matchers:
1905 1904 try:
1906 1905 matches.extend([(m, matcher.__qualname__)
1907 1906 for m in matcher(text)])
1908 1907 except:
1909 1908 # Show the ugly traceback if the matcher causes an
1910 1909 # exception, but do NOT crash the kernel!
1911 1910 sys.excepthook(*sys.exc_info())
1912 1911 else:
1913 1912 for matcher in self.matchers:
1914 1913 matches = [(m, matcher.__qualname__)
1915 1914 for m in matcher(text)]
1916 1915 if matches:
1917 1916 break
1918 1917 seen = set()
1919 1918 filtered_matches = set()
1920 1919 for m in matches:
1921 1920 t, c = m
1922 1921 if t not in seen:
1923 1922 filtered_matches.add(m)
1924 1923 seen.add(t)
1925 1924
1926 1925 filtered_matches = sorted(
1927 1926 set(filtered_matches), key=lambda x: completions_sorting_key(x[0]))
1928 1927
1929 1928 matches = [m[0] for m in filtered_matches]
1930 1929 origins = [m[1] for m in filtered_matches]
1931 1930
1932 1931 self.matches = matches
1933 1932
1934 1933 return text, matches, origins, completions
@@ -1,321 +1,320 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Displayhook for IPython.
3 3
4 4 This defines a callable class that IPython uses for `sys.displayhook`.
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 builtins as builtin_mod
11 11 import sys
12 12 import io as _io
13 13 import tokenize
14 14
15 15 from traitlets.config.configurable import Configurable
16 from IPython.utils.py3compat import cast_unicode_py2
17 16 from traitlets import Instance, Float
18 17 from warnings import warn
19 18
20 19 # TODO: Move the various attributes (cache_size, [others now moved]). Some
21 20 # of these are also attributes of InteractiveShell. They should be on ONE object
22 21 # only and the other objects should ask that one object for their values.
23 22
24 23 class DisplayHook(Configurable):
25 24 """The custom IPython displayhook to replace sys.displayhook.
26 25
27 26 This class does many things, but the basic idea is that it is a callable
28 27 that gets called anytime user code returns a value.
29 28 """
30 29
31 30 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
32 31 allow_none=True)
33 32 exec_result = Instance('IPython.core.interactiveshell.ExecutionResult',
34 33 allow_none=True)
35 34 cull_fraction = Float(0.2)
36 35
37 36 def __init__(self, shell=None, cache_size=1000, **kwargs):
38 37 super(DisplayHook, self).__init__(shell=shell, **kwargs)
39 38 cache_size_min = 3
40 39 if cache_size <= 0:
41 40 self.do_full_cache = 0
42 41 cache_size = 0
43 42 elif cache_size < cache_size_min:
44 43 self.do_full_cache = 0
45 44 cache_size = 0
46 45 warn('caching was disabled (min value for cache size is %s).' %
47 46 cache_size_min,stacklevel=3)
48 47 else:
49 48 self.do_full_cache = 1
50 49
51 50 self.cache_size = cache_size
52 51
53 52 # we need a reference to the user-level namespace
54 53 self.shell = shell
55 54
56 55 self._,self.__,self.___ = '','',''
57 56
58 57 # these are deliberately global:
59 58 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
60 59 self.shell.user_ns.update(to_user_ns)
61 60
62 61 @property
63 62 def prompt_count(self):
64 63 return self.shell.execution_count
65 64
66 65 #-------------------------------------------------------------------------
67 66 # Methods used in __call__. Override these methods to modify the behavior
68 67 # of the displayhook.
69 68 #-------------------------------------------------------------------------
70 69
71 70 def check_for_underscore(self):
72 71 """Check if the user has set the '_' variable by hand."""
73 72 # If something injected a '_' variable in __builtin__, delete
74 73 # ipython's automatic one so we don't clobber that. gettext() in
75 74 # particular uses _, so we need to stay away from it.
76 75 if '_' in builtin_mod.__dict__:
77 76 try:
78 77 user_value = self.shell.user_ns['_']
79 78 if user_value is not self._:
80 79 return
81 80 del self.shell.user_ns['_']
82 81 except KeyError:
83 82 pass
84 83
85 84 def quiet(self):
86 85 """Should we silence the display hook because of ';'?"""
87 86 # do not print output if input ends in ';'
88 87
89 88 try:
90 cell = cast_unicode_py2(self.shell.history_manager.input_hist_parsed[-1])
89 cell = self.shell.history_manager.input_hist_parsed[-1]
91 90 except IndexError:
92 91 # some uses of ipshellembed may fail here
93 92 return False
94 93
95 94 sio = _io.StringIO(cell)
96 95 tokens = list(tokenize.generate_tokens(sio.readline))
97 96
98 97 for token in reversed(tokens):
99 98 if token[0] in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT):
100 99 continue
101 100 if (token[0] == tokenize.OP) and (token[1] == ';'):
102 101 return True
103 102 else:
104 103 return False
105 104
106 105 def start_displayhook(self):
107 106 """Start the displayhook, initializing resources."""
108 107 pass
109 108
110 109 def write_output_prompt(self):
111 110 """Write the output prompt.
112 111
113 112 The default implementation simply writes the prompt to
114 113 ``sys.stdout``.
115 114 """
116 115 # Use write, not print which adds an extra space.
117 116 sys.stdout.write(self.shell.separate_out)
118 117 outprompt = 'Out[{}]: '.format(self.shell.execution_count)
119 118 if self.do_full_cache:
120 119 sys.stdout.write(outprompt)
121 120
122 121 def compute_format_data(self, result):
123 122 """Compute format data of the object to be displayed.
124 123
125 124 The format data is a generalization of the :func:`repr` of an object.
126 125 In the default implementation the format data is a :class:`dict` of
127 126 key value pair where the keys are valid MIME types and the values
128 127 are JSON'able data structure containing the raw data for that MIME
129 128 type. It is up to frontends to determine pick a MIME to to use and
130 129 display that data in an appropriate manner.
131 130
132 131 This method only computes the format data for the object and should
133 132 NOT actually print or write that to a stream.
134 133
135 134 Parameters
136 135 ----------
137 136 result : object
138 137 The Python object passed to the display hook, whose format will be
139 138 computed.
140 139
141 140 Returns
142 141 -------
143 142 (format_dict, md_dict) : dict
144 143 format_dict is a :class:`dict` whose keys are valid MIME types and values are
145 144 JSON'able raw data for that MIME type. It is recommended that
146 145 all return values of this should always include the "text/plain"
147 146 MIME type representation of the object.
148 147 md_dict is a :class:`dict` with the same MIME type keys
149 148 of metadata associated with each output.
150 149
151 150 """
152 151 return self.shell.display_formatter.format(result)
153 152
154 153 # This can be set to True by the write_output_prompt method in a subclass
155 154 prompt_end_newline = False
156 155
157 156 def write_format_data(self, format_dict, md_dict=None):
158 157 """Write the format data dict to the frontend.
159 158
160 159 This default version of this method simply writes the plain text
161 160 representation of the object to ``sys.stdout``. Subclasses should
162 161 override this method to send the entire `format_dict` to the
163 162 frontends.
164 163
165 164 Parameters
166 165 ----------
167 166 format_dict : dict
168 167 The format dict for the object passed to `sys.displayhook`.
169 168 md_dict : dict (optional)
170 169 The metadata dict to be associated with the display data.
171 170 """
172 171 if 'text/plain' not in format_dict:
173 172 # nothing to do
174 173 return
175 174 # We want to print because we want to always make sure we have a
176 175 # newline, even if all the prompt separators are ''. This is the
177 176 # standard IPython behavior.
178 177 result_repr = format_dict['text/plain']
179 178 if '\n' in result_repr:
180 179 # So that multi-line strings line up with the left column of
181 180 # the screen, instead of having the output prompt mess up
182 181 # their first line.
183 182 # We use the prompt template instead of the expanded prompt
184 183 # because the expansion may add ANSI escapes that will interfere
185 184 # with our ability to determine whether or not we should add
186 185 # a newline.
187 186 if not self.prompt_end_newline:
188 187 # But avoid extraneous empty lines.
189 188 result_repr = '\n' + result_repr
190 189
191 190 print(result_repr)
192 191
193 192 def update_user_ns(self, result):
194 193 """Update user_ns with various things like _, __, _1, etc."""
195 194
196 195 # Avoid recursive reference when displaying _oh/Out
197 196 if result is not self.shell.user_ns['_oh']:
198 197 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
199 198 self.cull_cache()
200 199
201 200 # Don't overwrite '_' and friends if '_' is in __builtin__
202 201 # (otherwise we cause buggy behavior for things like gettext). and
203 202 # do not overwrite _, __ or ___ if one of these has been assigned
204 203 # by the user.
205 204 update_unders = True
206 205 for unders in ['_'*i for i in range(1,4)]:
207 206 if not unders in self.shell.user_ns:
208 207 continue
209 208 if getattr(self, unders) is not self.shell.user_ns.get(unders):
210 209 update_unders = False
211 210
212 211 self.___ = self.__
213 212 self.__ = self._
214 213 self._ = result
215 214
216 215 if ('_' not in builtin_mod.__dict__) and (update_unders):
217 216 self.shell.push({'_':self._,
218 217 '__':self.__,
219 218 '___':self.___}, interactive=False)
220 219
221 220 # hackish access to top-level namespace to create _1,_2... dynamically
222 221 to_main = {}
223 222 if self.do_full_cache:
224 223 new_result = '_%s' % self.prompt_count
225 224 to_main[new_result] = result
226 225 self.shell.push(to_main, interactive=False)
227 226 self.shell.user_ns['_oh'][self.prompt_count] = result
228 227
229 228 def fill_exec_result(self, result):
230 229 if self.exec_result is not None:
231 230 self.exec_result.result = result
232 231
233 232 def log_output(self, format_dict):
234 233 """Log the output."""
235 234 if 'text/plain' not in format_dict:
236 235 # nothing to do
237 236 return
238 237 if self.shell.logger.log_output:
239 238 self.shell.logger.log_write(format_dict['text/plain'], 'output')
240 239 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
241 240 format_dict['text/plain']
242 241
243 242 def finish_displayhook(self):
244 243 """Finish up all displayhook activities."""
245 244 sys.stdout.write(self.shell.separate_out2)
246 245 sys.stdout.flush()
247 246
248 247 def __call__(self, result=None):
249 248 """Printing with history cache management.
250 249
251 250 This is invoked everytime the interpreter needs to print, and is
252 251 activated by setting the variable sys.displayhook to it.
253 252 """
254 253 self.check_for_underscore()
255 254 if result is not None and not self.quiet():
256 255 self.start_displayhook()
257 256 self.write_output_prompt()
258 257 format_dict, md_dict = self.compute_format_data(result)
259 258 self.update_user_ns(result)
260 259 self.fill_exec_result(result)
261 260 if format_dict:
262 261 self.write_format_data(format_dict, md_dict)
263 262 self.log_output(format_dict)
264 263 self.finish_displayhook()
265 264
266 265 def cull_cache(self):
267 266 """Output cache is full, cull the oldest entries"""
268 267 oh = self.shell.user_ns.get('_oh', {})
269 268 sz = len(oh)
270 269 cull_count = max(int(sz * self.cull_fraction), 2)
271 270 warn('Output cache limit (currently {sz} entries) hit.\n'
272 271 'Flushing oldest {cull_count} entries.'.format(sz=sz, cull_count=cull_count))
273 272
274 273 for i, n in enumerate(sorted(oh)):
275 274 if i >= cull_count:
276 275 break
277 276 self.shell.user_ns.pop('_%i' % n, None)
278 277 oh.pop(n, None)
279 278
280 279
281 280 def flush(self):
282 281 if not self.do_full_cache:
283 282 raise ValueError("You shouldn't have reached the cache flush "
284 283 "if full caching is not enabled!")
285 284 # delete auto-generated vars from global namespace
286 285
287 286 for n in range(1,self.prompt_count + 1):
288 287 key = '_'+repr(n)
289 288 try:
290 289 del self.shell.user_ns[key]
291 290 except: pass
292 291 # In some embedded circumstances, the user_ns doesn't have the
293 292 # '_oh' key set up.
294 293 oh = self.shell.user_ns.get('_oh', None)
295 294 if oh is not None:
296 295 oh.clear()
297 296
298 297 # Release our own references to objects:
299 298 self._, self.__, self.___ = '', '', ''
300 299
301 300 if '_' not in builtin_mod.__dict__:
302 301 self.shell.user_ns.update({'_':None,'__':None, '___':None})
303 302 import gc
304 303 # TODO: Is this really needed?
305 304 # IronPython blocks here forever
306 305 if sys.platform != "cli":
307 306 gc.collect()
308 307
309 308
310 309 class CapturingDisplayHook(object):
311 310 def __init__(self, shell, outputs=None):
312 311 self.shell = shell
313 312 if outputs is None:
314 313 outputs = []
315 314 self.outputs = outputs
316 315
317 316 def __call__(self, result=None):
318 317 if result is None:
319 318 return
320 319 format_dict, md_dict = self.shell.display_formatter.format(result)
321 320 self.outputs.append((format_dict, md_dict))
@@ -1,319 +1,318 b''
1 1 """Implementation of magic functions related to History.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012, IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import os
17 17 import sys
18 18 from io import open as io_open
19 19
20 20 # Our own packages
21 21 from IPython.core.error import StdinNotImplementedError
22 22 from IPython.core.magic import Magics, magics_class, line_magic
23 23 from IPython.core.magic_arguments import (argument, magic_arguments,
24 24 parse_argstring)
25 25 from IPython.testing.skipdoctest import skip_doctest
26 26 from IPython.utils import io
27 from IPython.utils.py3compat import cast_unicode_py2
28 27
29 28 #-----------------------------------------------------------------------------
30 29 # Magics class implementation
31 30 #-----------------------------------------------------------------------------
32 31
33 32
34 33 _unspecified = object()
35 34
36 35
37 36 @magics_class
38 37 class HistoryMagics(Magics):
39 38
40 39 @magic_arguments()
41 40 @argument(
42 41 '-n', dest='print_nums', action='store_true', default=False,
43 42 help="""
44 43 print line numbers for each input.
45 44 This feature is only available if numbered prompts are in use.
46 45 """)
47 46 @argument(
48 47 '-o', dest='get_output', action='store_true', default=False,
49 48 help="also print outputs for each input.")
50 49 @argument(
51 50 '-p', dest='pyprompts', action='store_true', default=False,
52 51 help="""
53 52 print classic '>>>' python prompts before each input.
54 53 This is useful for making documentation, and in conjunction
55 54 with -o, for producing doctest-ready output.
56 55 """)
57 56 @argument(
58 57 '-t', dest='raw', action='store_false', default=True,
59 58 help="""
60 59 print the 'translated' history, as IPython understands it.
61 60 IPython filters your input and converts it all into valid Python
62 61 source before executing it (things like magics or aliases are turned
63 62 into function calls, for example). With this option, you'll see the
64 63 native history instead of the user-entered version: '%%cd /' will be
65 64 seen as 'get_ipython().magic("%%cd /")' instead of '%%cd /'.
66 65 """)
67 66 @argument(
68 67 '-f', dest='filename',
69 68 help="""
70 69 FILENAME: instead of printing the output to the screen, redirect
71 70 it to the given file. The file is always overwritten, though *when
72 71 it can*, IPython asks for confirmation first. In particular, running
73 72 the command 'history -f FILENAME' from the IPython Notebook
74 73 interface will replace FILENAME even if it already exists *without*
75 74 confirmation.
76 75 """)
77 76 @argument(
78 77 '-g', dest='pattern', nargs='*', default=None,
79 78 help="""
80 79 treat the arg as a glob pattern to search for in (full) history.
81 80 This includes the saved history (almost all commands ever written).
82 81 The pattern may contain '?' to match one unknown character and '*'
83 82 to match any number of unknown characters. Use '%%hist -g' to show
84 83 full saved history (may be very long).
85 84 """)
86 85 @argument(
87 86 '-l', dest='limit', type=int, nargs='?', default=_unspecified,
88 87 help="""
89 88 get the last n lines from all sessions. Specify n as a single
90 89 arg, or the default is the last 10 lines.
91 90 """)
92 91 @argument(
93 92 '-u', dest='unique', action='store_true',
94 93 help="""
95 94 when searching history using `-g`, show only unique history.
96 95 """)
97 96 @argument('range', nargs='*')
98 97 @skip_doctest
99 98 @line_magic
100 99 def history(self, parameter_s = ''):
101 100 """Print input history (_i<n> variables), with most recent last.
102 101
103 102 By default, input history is printed without line numbers so it can be
104 103 directly pasted into an editor. Use -n to show them.
105 104
106 105 By default, all input history from the current session is displayed.
107 106 Ranges of history can be indicated using the syntax:
108 107
109 108 ``4``
110 109 Line 4, current session
111 110 ``4-6``
112 111 Lines 4-6, current session
113 112 ``243/1-5``
114 113 Lines 1-5, session 243
115 114 ``~2/7``
116 115 Line 7, session 2 before current
117 116 ``~8/1-~6/5``
118 117 From the first line of 8 sessions ago, to the fifth line of 6
119 118 sessions ago.
120 119
121 120 Multiple ranges can be entered, separated by spaces
122 121
123 122 The same syntax is used by %macro, %save, %edit, %rerun
124 123
125 124 Examples
126 125 --------
127 126 ::
128 127
129 128 In [6]: %history -n 4-6
130 129 4:a = 12
131 130 5:print a**2
132 131 6:%history -n 4-6
133 132
134 133 """
135 134
136 135 args = parse_argstring(self.history, parameter_s)
137 136
138 137 # For brevity
139 138 history_manager = self.shell.history_manager
140 139
141 140 def _format_lineno(session, line):
142 141 """Helper function to format line numbers properly."""
143 142 if session in (0, history_manager.session_number):
144 143 return str(line)
145 144 return "%s/%s" % (session, line)
146 145
147 146 # Check if output to specific file was requested.
148 147 outfname = args.filename
149 148 if not outfname:
150 149 outfile = sys.stdout # default
151 150 # We don't want to close stdout at the end!
152 151 close_at_end = False
153 152 else:
154 153 if os.path.exists(outfname):
155 154 try:
156 155 ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
157 156 except StdinNotImplementedError:
158 157 ans = True
159 158 if not ans:
160 159 print('Aborting.')
161 160 return
162 161 print("Overwriting file.")
163 162 outfile = io_open(outfname, 'w', encoding='utf-8')
164 163 close_at_end = True
165 164
166 165 print_nums = args.print_nums
167 166 get_output = args.get_output
168 167 pyprompts = args.pyprompts
169 168 raw = args.raw
170 169
171 170 pattern = None
172 171 limit = None if args.limit is _unspecified else args.limit
173 172
174 173 if args.pattern is not None:
175 174 if args.pattern:
176 175 pattern = "*" + " ".join(args.pattern) + "*"
177 176 else:
178 177 pattern = "*"
179 178 hist = history_manager.search(pattern, raw=raw, output=get_output,
180 179 n=limit, unique=args.unique)
181 180 print_nums = True
182 181 elif args.limit is not _unspecified:
183 182 n = 10 if limit is None else limit
184 183 hist = history_manager.get_tail(n, raw=raw, output=get_output)
185 184 else:
186 185 if args.range: # Get history by ranges
187 186 hist = history_manager.get_range_by_str(" ".join(args.range),
188 187 raw, get_output)
189 188 else: # Just get history for the current session
190 189 hist = history_manager.get_range(raw=raw, output=get_output)
191 190
192 191 # We could be displaying the entire history, so let's not try to pull
193 192 # it into a list in memory. Anything that needs more space will just
194 193 # misalign.
195 194 width = 4
196 195
197 196 for session, lineno, inline in hist:
198 197 # Print user history with tabs expanded to 4 spaces. The GUI
199 198 # clients use hard tabs for easier usability in auto-indented code,
200 199 # but we want to produce PEP-8 compliant history for safe pasting
201 200 # into an editor.
202 201 if get_output:
203 202 inline, output = inline
204 203 inline = inline.expandtabs(4).rstrip()
205 204
206 205 multiline = "\n" in inline
207 206 line_sep = '\n' if multiline else ' '
208 207 if print_nums:
209 208 print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
210 209 line_sep), file=outfile, end=u'')
211 210 if pyprompts:
212 211 print(u">>> ", end=u"", file=outfile)
213 212 if multiline:
214 213 inline = "\n... ".join(inline.splitlines()) + "\n..."
215 214 print(inline, file=outfile)
216 215 if get_output and output:
217 print(cast_unicode_py2(output), file=outfile)
216 print(output, file=outfile)
218 217
219 218 if close_at_end:
220 219 outfile.close()
221 220
222 221 @line_magic
223 222 def recall(self, arg):
224 223 r"""Repeat a command, or get command to input line for editing.
225 224
226 225 %recall and %rep are equivalent.
227 226
228 227 - %recall (no arguments):
229 228
230 229 Place a string version of last computation result (stored in the
231 230 special '_' variable) to the next input prompt. Allows you to create
232 231 elaborate command lines without using copy-paste::
233 232
234 233 In[1]: l = ["hei", "vaan"]
235 234 In[2]: "".join(l)
236 235 Out[2]: heivaan
237 236 In[3]: %recall
238 237 In[4]: heivaan_ <== cursor blinking
239 238
240 239 %recall 45
241 240
242 241 Place history line 45 on the next input prompt. Use %hist to find
243 242 out the number.
244 243
245 244 %recall 1-4
246 245
247 246 Combine the specified lines into one cell, and place it on the next
248 247 input prompt. See %history for the slice syntax.
249 248
250 249 %recall foo+bar
251 250
252 251 If foo+bar can be evaluated in the user namespace, the result is
253 252 placed at the next input prompt. Otherwise, the history is searched
254 253 for lines which contain that substring, and the most recent one is
255 254 placed at the next input prompt.
256 255 """
257 256 if not arg: # Last output
258 257 self.shell.set_next_input(str(self.shell.user_ns["_"]))
259 258 return
260 259 # Get history range
261 260 histlines = self.shell.history_manager.get_range_by_str(arg)
262 261 cmd = "\n".join(x[2] for x in histlines)
263 262 if cmd:
264 263 self.shell.set_next_input(cmd.rstrip())
265 264 return
266 265
267 266 try: # Variable in user namespace
268 267 cmd = str(eval(arg, self.shell.user_ns))
269 268 except Exception: # Search for term in history
270 269 histlines = self.shell.history_manager.search("*"+arg+"*")
271 270 for h in reversed([x[2] for x in histlines]):
272 271 if 'recall' in h or 'rep' in h:
273 272 continue
274 273 self.shell.set_next_input(h.rstrip())
275 274 return
276 275 else:
277 276 self.shell.set_next_input(cmd.rstrip())
278 277 print("Couldn't evaluate or find in history:", arg)
279 278
280 279 @line_magic
281 280 def rerun(self, parameter_s=''):
282 281 """Re-run previous input
283 282
284 283 By default, you can specify ranges of input history to be repeated
285 284 (as with %history). With no arguments, it will repeat the last line.
286 285
287 286 Options:
288 287
289 288 -l <n> : Repeat the last n lines of input, not including the
290 289 current command.
291 290
292 291 -g foo : Repeat the most recent line which contains foo
293 292 """
294 293 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
295 294 if "l" in opts: # Last n lines
296 295 n = int(opts['l'])
297 296 hist = self.shell.history_manager.get_tail(n)
298 297 elif "g" in opts: # Search
299 298 p = "*"+opts['g']+"*"
300 299 hist = list(self.shell.history_manager.search(p))
301 300 for l in reversed(hist):
302 301 if "rerun" not in l[2]:
303 302 hist = [l] # The last match which isn't a %rerun
304 303 break
305 304 else:
306 305 hist = [] # No matches except %rerun
307 306 elif args: # Specify history ranges
308 307 hist = self.shell.history_manager.get_range_by_str(args)
309 308 else: # Last line
310 309 hist = self.shell.history_manager.get_tail(1)
311 310 hist = [x[2] for x in hist]
312 311 if not hist:
313 312 print("No lines in history match specification")
314 313 return
315 314 histlines = "\n".join(hist)
316 315 print("=== Executing: ===")
317 316 print(histlines)
318 317 print("=== Output: ===")
319 318 self.shell.run_cell("\n".join(hist), store_history=False)
@@ -1,1461 +1,1456 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, line in enumerate(lines):
193 193 match = pat.match(line)
194 194 if match:
195 195 # if it's at toplevel, it's already the best one
196 196 if line[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 301 """
302 302 Deprecated since IPython 6.0
303 303 decorator for monkeypatching inspect.findsource
304 304 """
305 305
306 306 def wrapped(*args, **kwargs):
307 307 save_findsource = inspect.findsource
308 308 save_getargs = inspect.getargs
309 309 inspect.findsource = findsource
310 310 inspect.getargs = getargs
311 311 try:
312 312 return f(*args, **kwargs)
313 313 finally:
314 314 inspect.findsource = save_findsource
315 315 inspect.getargs = save_getargs
316 316
317 317 return wrapped
318 318
319 319
320 320 def fix_frame_records_filenames(records):
321 321 """Try to fix the filenames in each record from inspect.getinnerframes().
322 322
323 323 Particularly, modules loaded from within zip files have useless filenames
324 324 attached to their code object, and inspect.getinnerframes() just uses it.
325 325 """
326 326 fixed_records = []
327 327 for frame, filename, line_no, func_name, lines, index in records:
328 328 # Look inside the frame's globals dictionary for __file__,
329 329 # which should be better. However, keep Cython filenames since
330 330 # we prefer the source filenames over the compiled .so file.
331 filename = py3compat.cast_unicode_py2(filename, "utf-8")
332 331 if not filename.endswith(('.pyx', '.pxd', '.pxi')):
333 332 better_fn = frame.f_globals.get('__file__', None)
334 333 if isinstance(better_fn, str):
335 334 # Check the type just in case someone did something weird with
336 335 # __file__. It might also be None if the error occurred during
337 336 # import.
338 337 filename = better_fn
339 338 fixed_records.append((frame, filename, line_no, func_name, lines, index))
340 339 return fixed_records
341 340
342 341
343 342 @with_patch_inspect
344 343 def _fixed_getinnerframes(etb, context=1, tb_offset=0):
345 344 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
346 345
347 346 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
348 347 # If the error is at the console, don't build any context, since it would
349 348 # otherwise produce 5 blank lines printed out (there is no file at the
350 349 # console)
351 350 rec_check = records[tb_offset:]
352 351 try:
353 352 rname = rec_check[0][1]
354 353 if rname == '<ipython console>' or rname.endswith('<string>'):
355 354 return rec_check
356 355 except IndexError:
357 356 pass
358 357
359 358 aux = traceback.extract_tb(etb)
360 359 assert len(records) == len(aux)
361 360 for i, (file, lnum, _, _) in enumerate(aux):
362 361 maybeStart = lnum - 1 - context // 2
363 362 start = max(maybeStart, 0)
364 363 end = start + context
365 364 lines = linecache.getlines(file)[start:end]
366 365 buf = list(records[i])
367 366 buf[LNUM_POS] = lnum
368 367 buf[INDEX_POS] = lnum - 1 - start
369 368 buf[LINES_POS] = lines
370 369 records[i] = tuple(buf)
371 370 return records[tb_offset:]
372 371
373 372 # Helper function -- largely belongs to VerboseTB, but we need the same
374 373 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
375 374 # can be recognized properly by ipython.el's py-traceback-line-re
376 375 # (SyntaxErrors have to be treated specially because they have no traceback)
377 376
378 377
379 378 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None, _line_format=(lambda x,_:x,None)):
380 379 numbers_width = INDENT_SIZE - 1
381 380 res = []
382 381 i = lnum - index
383 382
384 383 for line in lines:
385 line = py3compat.cast_unicode(line)
386
387 384 new_line, err = _line_format(line, 'str')
388 385 if not err: line = new_line
389 386
390 387 if i == lnum:
391 388 # This is the line with the error
392 389 pad = numbers_width - len(str(i))
393 390 num = '%s%s' % (debugger.make_arrow(pad), str(lnum))
394 391 line = '%s%s%s %s%s' % (Colors.linenoEm, num,
395 392 Colors.line, line, Colors.Normal)
396 393 else:
397 394 num = '%*s' % (numbers_width, i)
398 395 line = '%s%s%s %s' % (Colors.lineno, num,
399 396 Colors.Normal, line)
400 397
401 398 res.append(line)
402 399 if lvals and i == lnum:
403 400 res.append(lvals + '\n')
404 401 i = i + 1
405 402 return res
406 403
407 404 def is_recursion_error(etype, value, records):
408 405 try:
409 406 # RecursionError is new in Python 3.5
410 407 recursion_error_type = RecursionError
411 408 except NameError:
412 409 recursion_error_type = RuntimeError
413 410
414 411 # The default recursion limit is 1000, but some of that will be taken up
415 412 # by stack frames in IPython itself. >500 frames probably indicates
416 413 # a recursion error.
417 414 return (etype is recursion_error_type) \
418 415 and "recursion" in str(value).lower() \
419 416 and len(records) > 500
420 417
421 418 def find_recursion(etype, value, records):
422 419 """Identify the repeating stack frames from a RecursionError traceback
423 420
424 421 'records' is a list as returned by VerboseTB.get_records()
425 422
426 423 Returns (last_unique, repeat_length)
427 424 """
428 425 # This involves a bit of guesswork - we want to show enough of the traceback
429 426 # to indicate where the recursion is occurring. We guess that the innermost
430 427 # quarter of the traceback (250 frames by default) is repeats, and find the
431 428 # first frame (from in to out) that looks different.
432 429 if not is_recursion_error(etype, value, records):
433 430 return len(records), 0
434 431
435 432 # Select filename, lineno, func_name to track frames with
436 433 records = [r[1:4] for r in records]
437 434 inner_frames = records[-(len(records)//4):]
438 435 frames_repeated = set(inner_frames)
439 436
440 437 last_seen_at = {}
441 438 longest_repeat = 0
442 439 i = len(records)
443 440 for frame in reversed(records):
444 441 i -= 1
445 442 if frame not in frames_repeated:
446 443 last_unique = i
447 444 break
448 445
449 446 if frame in last_seen_at:
450 447 distance = last_seen_at[frame] - i
451 448 longest_repeat = max(longest_repeat, distance)
452 449
453 450 last_seen_at[frame] = i
454 451 else:
455 452 last_unique = 0 # The whole traceback was recursion
456 453
457 454 return last_unique, longest_repeat
458 455
459 456 #---------------------------------------------------------------------------
460 457 # Module classes
461 458 class TBTools(colorable.Colorable):
462 459 """Basic tools used by all traceback printer classes."""
463 460
464 461 # Number of frames to skip when reporting tracebacks
465 462 tb_offset = 0
466 463
467 464 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
468 465 # Whether to call the interactive pdb debugger after printing
469 466 # tracebacks or not
470 467 super(TBTools, self).__init__(parent=parent, config=config)
471 468 self.call_pdb = call_pdb
472 469
473 470 # Output stream to write to. Note that we store the original value in
474 471 # a private attribute and then make the public ostream a property, so
475 472 # that we can delay accessing sys.stdout until runtime. The way
476 473 # things are written now, the sys.stdout object is dynamically managed
477 474 # so a reference to it should NEVER be stored statically. This
478 475 # property approach confines this detail to a single location, and all
479 476 # subclasses can simply access self.ostream for writing.
480 477 self._ostream = ostream
481 478
482 479 # Create color table
483 480 self.color_scheme_table = exception_colors()
484 481
485 482 self.set_colors(color_scheme)
486 483 self.old_scheme = color_scheme # save initial value for toggles
487 484
488 485 if call_pdb:
489 486 self.pdb = debugger.Pdb()
490 487 else:
491 488 self.pdb = None
492 489
493 490 def _get_ostream(self):
494 491 """Output stream that exceptions are written to.
495 492
496 493 Valid values are:
497 494
498 495 - None: the default, which means that IPython will dynamically resolve
499 496 to sys.stdout. This ensures compatibility with most tools, including
500 497 Windows (where plain stdout doesn't recognize ANSI escapes).
501 498
502 499 - Any object with 'write' and 'flush' attributes.
503 500 """
504 501 return sys.stdout if self._ostream is None else self._ostream
505 502
506 503 def _set_ostream(self, val):
507 504 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
508 505 self._ostream = val
509 506
510 507 ostream = property(_get_ostream, _set_ostream)
511 508
512 509 def set_colors(self, *args, **kw):
513 510 """Shorthand access to the color table scheme selector method."""
514 511
515 512 # Set own color table
516 513 self.color_scheme_table.set_active_scheme(*args, **kw)
517 514 # for convenience, set Colors to the active scheme
518 515 self.Colors = self.color_scheme_table.active_colors
519 516 # Also set colors of debugger
520 517 if hasattr(self, 'pdb') and self.pdb is not None:
521 518 self.pdb.set_colors(*args, **kw)
522 519
523 520 def color_toggle(self):
524 521 """Toggle between the currently active color scheme and NoColor."""
525 522
526 523 if self.color_scheme_table.active_scheme_name == 'NoColor':
527 524 self.color_scheme_table.set_active_scheme(self.old_scheme)
528 525 self.Colors = self.color_scheme_table.active_colors
529 526 else:
530 527 self.old_scheme = self.color_scheme_table.active_scheme_name
531 528 self.color_scheme_table.set_active_scheme('NoColor')
532 529 self.Colors = self.color_scheme_table.active_colors
533 530
534 531 def stb2text(self, stb):
535 532 """Convert a structured traceback (a list) to a string."""
536 533 return '\n'.join(stb)
537 534
538 535 def text(self, etype, value, tb, tb_offset=None, context=5):
539 536 """Return formatted traceback.
540 537
541 538 Subclasses may override this if they add extra arguments.
542 539 """
543 540 tb_list = self.structured_traceback(etype, value, tb,
544 541 tb_offset, context)
545 542 return self.stb2text(tb_list)
546 543
547 544 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
548 545 context=5, mode=None):
549 546 """Return a list of traceback frames.
550 547
551 548 Must be implemented by each class.
552 549 """
553 550 raise NotImplementedError()
554 551
555 552
556 553 #---------------------------------------------------------------------------
557 554 class ListTB(TBTools):
558 555 """Print traceback information from a traceback list, with optional color.
559 556
560 557 Calling requires 3 arguments: (etype, evalue, elist)
561 558 as would be obtained by::
562 559
563 560 etype, evalue, tb = sys.exc_info()
564 561 if tb:
565 562 elist = traceback.extract_tb(tb)
566 563 else:
567 564 elist = None
568 565
569 566 It can thus be used by programs which need to process the traceback before
570 567 printing (such as console replacements based on the code module from the
571 568 standard library).
572 569
573 570 Because they are meant to be called without a full traceback (only a
574 571 list), instances of this class can't call the interactive pdb debugger."""
575 572
576 573 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None, parent=None, config=None):
577 574 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
578 575 ostream=ostream, parent=parent,config=config)
579 576
580 577 def __call__(self, etype, value, elist):
581 578 self.ostream.flush()
582 579 self.ostream.write(self.text(etype, value, elist))
583 580 self.ostream.write('\n')
584 581
585 582 def structured_traceback(self, etype, value, elist, tb_offset=None,
586 583 context=5):
587 584 """Return a color formatted string with the traceback info.
588 585
589 586 Parameters
590 587 ----------
591 588 etype : exception type
592 589 Type of the exception raised.
593 590
594 591 value : object
595 592 Data stored in the exception
596 593
597 594 elist : list
598 595 List of frames, see class docstring for details.
599 596
600 597 tb_offset : int, optional
601 598 Number of frames in the traceback to skip. If not given, the
602 599 instance value is used (set in constructor).
603 600
604 601 context : int, optional
605 602 Number of lines of context information to print.
606 603
607 604 Returns
608 605 -------
609 606 String with formatted exception.
610 607 """
611 608 tb_offset = self.tb_offset if tb_offset is None else tb_offset
612 609 Colors = self.Colors
613 610 out_list = []
614 611 if elist:
615 612
616 613 if tb_offset and len(elist) > tb_offset:
617 614 elist = elist[tb_offset:]
618 615
619 616 out_list.append('Traceback %s(most recent call last)%s:' %
620 617 (Colors.normalEm, Colors.Normal) + '\n')
621 618 out_list.extend(self._format_list(elist))
622 619 # The exception info should be a single entry in the list.
623 620 lines = ''.join(self._format_exception_only(etype, value))
624 621 out_list.append(lines)
625 622
626 623 # Note: this code originally read:
627 624
628 625 ## for line in lines[:-1]:
629 626 ## out_list.append(" "+line)
630 627 ## out_list.append(lines[-1])
631 628
632 629 # This means it was indenting everything but the last line by a little
633 630 # bit. I've disabled this for now, but if we see ugliness somewhere we
634 631 # can restore it.
635 632
636 633 return out_list
637 634
638 635 def _format_list(self, extracted_list):
639 636 """Format a list of traceback entry tuples for printing.
640 637
641 638 Given a list of tuples as returned by extract_tb() or
642 639 extract_stack(), return a list of strings ready for printing.
643 640 Each string in the resulting list corresponds to the item with the
644 641 same index in the argument list. Each string ends in a newline;
645 642 the strings may contain internal newlines as well, for those items
646 643 whose source text line is not None.
647 644
648 645 Lifted almost verbatim from traceback.py
649 646 """
650 647
651 648 Colors = self.Colors
652 649 list = []
653 650 for filename, lineno, name, line in extracted_list[:-1]:
654 651 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
655 (Colors.filename, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.Normal,
652 (Colors.filename, filename, Colors.Normal,
656 653 Colors.lineno, lineno, Colors.Normal,
657 Colors.name, py3compat.cast_unicode_py2(name, "utf-8"), Colors.Normal)
654 Colors.name, name, Colors.Normal)
658 655 if line:
659 656 item += ' %s\n' % line.strip()
660 657 list.append(item)
661 658 # Emphasize the last entry
662 659 filename, lineno, name, line = extracted_list[-1]
663 660 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
664 661 (Colors.normalEm,
665 Colors.filenameEm, py3compat.cast_unicode_py2(filename, "utf-8"), Colors.normalEm,
662 Colors.filenameEm, filename, Colors.normalEm,
666 663 Colors.linenoEm, lineno, Colors.normalEm,
667 Colors.nameEm, py3compat.cast_unicode_py2(name, "utf-8"), Colors.normalEm,
664 Colors.nameEm, name, Colors.normalEm,
668 665 Colors.Normal)
669 666 if line:
670 667 item += '%s %s%s\n' % (Colors.line, line.strip(),
671 668 Colors.Normal)
672 669 list.append(item)
673 670 return list
674 671
675 672 def _format_exception_only(self, etype, value):
676 673 """Format the exception part of a traceback.
677 674
678 675 The arguments are the exception type and value such as given by
679 676 sys.exc_info()[:2]. The return value is a list of strings, each ending
680 677 in a newline. Normally, the list contains a single string; however,
681 678 for SyntaxError exceptions, it contains several lines that (when
682 679 printed) display detailed information about where the syntax error
683 680 occurred. The message indicating which exception occurred is the
684 681 always last string in the list.
685 682
686 683 Also lifted nearly verbatim from traceback.py
687 684 """
688 685 have_filedata = False
689 686 Colors = self.Colors
690 687 list = []
691 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
688 stype = Colors.excName + etype.__name__ + Colors.Normal
692 689 if value is None:
693 690 # Not sure if this can still happen in Python 2.6 and above
694 691 list.append(stype + '\n')
695 692 else:
696 693 if issubclass(etype, SyntaxError):
697 694 have_filedata = True
698 695 if not value.filename: value.filename = "<string>"
699 696 if value.lineno:
700 697 lineno = value.lineno
701 698 textline = linecache.getline(value.filename, value.lineno)
702 699 else:
703 700 lineno = 'unknown'
704 701 textline = ''
705 702 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
706 703 (Colors.normalEm,
707 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
704 Colors.filenameEm, value.filename, Colors.normalEm,
708 705 Colors.linenoEm, lineno, Colors.Normal ))
709 706 if textline == '':
710 textline = py3compat.cast_unicode(value.text, "utf-8")
707 textline = value.text
711 708
712 709 if textline is not None:
713 710 i = 0
714 711 while i < len(textline) and textline[i].isspace():
715 712 i += 1
716 713 list.append('%s %s%s\n' % (Colors.line,
717 714 textline.strip(),
718 715 Colors.Normal))
719 716 if value.offset is not None:
720 717 s = ' '
721 718 for c in textline[i:value.offset - 1]:
722 719 if c.isspace():
723 720 s += c
724 721 else:
725 722 s += ' '
726 723 list.append('%s%s^%s\n' % (Colors.caret, s,
727 724 Colors.Normal))
728 725
729 726 try:
730 727 s = value.msg
731 728 except Exception:
732 729 s = self._some_str(value)
733 730 if s:
734 731 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
735 732 Colors.Normal, s))
736 733 else:
737 734 list.append('%s\n' % stype)
738 735
739 736 # sync with user hooks
740 737 if have_filedata:
741 738 ipinst = get_ipython()
742 739 if ipinst is not None:
743 740 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
744 741
745 742 return list
746 743
747 744 def get_exception_only(self, etype, value):
748 745 """Only print the exception type and message, without a traceback.
749 746
750 747 Parameters
751 748 ----------
752 749 etype : exception type
753 750 value : exception value
754 751 """
755 752 return ListTB.structured_traceback(self, etype, value, [])
756 753
757 754 def show_exception_only(self, etype, evalue):
758 755 """Only print the exception type and message, without a traceback.
759 756
760 757 Parameters
761 758 ----------
762 759 etype : exception type
763 760 value : exception value
764 761 """
765 762 # This method needs to use __call__ from *this* class, not the one from
766 763 # a subclass whose signature or behavior may be different
767 764 ostream = self.ostream
768 765 ostream.flush()
769 766 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
770 767 ostream.flush()
771 768
772 769 def _some_str(self, value):
773 770 # Lifted from traceback.py
774 771 try:
775 return py3compat.cast_unicode(str(value))
772 return str(value)
776 773 except:
777 774 return u'<unprintable %s object>' % type(value).__name__
778 775
779 776
780 777 #----------------------------------------------------------------------------
781 778 class VerboseTB(TBTools):
782 779 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
783 780 of HTML. Requires inspect and pydoc. Crazy, man.
784 781
785 782 Modified version which optionally strips the topmost entries from the
786 783 traceback, to be used with alternate interpreters (because their own code
787 784 would appear in the traceback)."""
788 785
789 786 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
790 787 tb_offset=0, long_header=False, include_vars=True,
791 788 check_cache=None, debugger_cls = None,
792 789 parent=None, config=None):
793 790 """Specify traceback offset, headers and color scheme.
794 791
795 792 Define how many frames to drop from the tracebacks. Calling it with
796 793 tb_offset=1 allows use of this handler in interpreters which will have
797 794 their own code at the top of the traceback (VerboseTB will first
798 795 remove that frame before printing the traceback info)."""
799 796 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
800 797 ostream=ostream, parent=parent, config=config)
801 798 self.tb_offset = tb_offset
802 799 self.long_header = long_header
803 800 self.include_vars = include_vars
804 801 # By default we use linecache.checkcache, but the user can provide a
805 802 # different check_cache implementation. This is used by the IPython
806 803 # kernel to provide tracebacks for interactive code that is cached,
807 804 # by a compiler instance that flushes the linecache but preserves its
808 805 # own code cache.
809 806 if check_cache is None:
810 807 check_cache = linecache.checkcache
811 808 self.check_cache = check_cache
812 809
813 810 self.debugger_cls = debugger_cls or debugger.Pdb
814 811
815 812 def format_records(self, records, last_unique, recursion_repeat):
816 813 """Format the stack frames of the traceback"""
817 814 frames = []
818 815 for r in records[:last_unique+recursion_repeat+1]:
819 816 #print '*** record:',file,lnum,func,lines,index # dbg
820 817 frames.append(self.format_record(*r))
821 818
822 819 if recursion_repeat:
823 820 frames.append('... last %d frames repeated, from the frame below ...\n' % recursion_repeat)
824 821 frames.append(self.format_record(*records[last_unique+recursion_repeat+1]))
825 822
826 823 return frames
827 824
828 825 def format_record(self, frame, file, lnum, func, lines, index):
829 826 """Format a single stack frame"""
830 827 Colors = self.Colors # just a shorthand + quicker name lookup
831 828 ColorsNormal = Colors.Normal # used a lot
832 829 col_scheme = self.color_scheme_table.active_scheme_name
833 830 indent = ' ' * INDENT_SIZE
834 831 em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
835 832 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
836 833 tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
837 834 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
838 835 ColorsNormal)
839 836 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
840 837 (Colors.vName, Colors.valEm, ColorsNormal)
841 838 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
842 839 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
843 840 Colors.vName, ColorsNormal)
844 841 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
845 842
846 843 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
847 844 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line,
848 845 ColorsNormal)
849 846
850 847 abspath = os.path.abspath
851 848
852 849
853 850 if not file:
854 851 file = '?'
855 852 elif file.startswith(str("<")) and file.endswith(str(">")):
856 853 # Not a real filename, no problem...
857 854 pass
858 855 elif not os.path.isabs(file):
859 856 # Try to make the filename absolute by trying all
860 857 # sys.path entries (which is also what linecache does)
861 858 for dirname in sys.path:
862 859 try:
863 860 fullname = os.path.join(dirname, file)
864 861 if os.path.isfile(fullname):
865 862 file = os.path.abspath(fullname)
866 863 break
867 864 except Exception:
868 865 # Just in case that sys.path contains very
869 866 # strange entries...
870 867 pass
871 868
872 file = py3compat.cast_unicode(file, util_path.fs_encoding)
873 869 link = tpl_link % util_path.compress_user(file)
874 870 args, varargs, varkw, locals = inspect.getargvalues(frame)
875 871
876 872 if func == '?':
877 873 call = ''
878 874 else:
879 875 # Decide whether to include variable details or not
880 876 var_repr = self.include_vars and eqrepr or nullrepr
881 877 try:
882 878 call = tpl_call % (func, inspect.formatargvalues(args,
883 879 varargs, varkw,
884 880 locals, formatvalue=var_repr))
885 881 except KeyError:
886 882 # This happens in situations like errors inside generator
887 883 # expressions, where local variables are listed in the
888 884 # line, but can't be extracted from the frame. I'm not
889 885 # 100% sure this isn't actually a bug in inspect itself,
890 886 # but since there's no info for us to compute with, the
891 887 # best we can do is report the failure and move on. Here
892 888 # we must *not* call any traceback construction again,
893 889 # because that would mess up use of %debug later on. So we
894 890 # simply report the failure and move on. The only
895 891 # limitation will be that this frame won't have locals
896 892 # listed in the call signature. Quite subtle problem...
897 893 # I can't think of a good way to validate this in a unit
898 894 # test, but running a script consisting of:
899 895 # dict( (k,v.strip()) for (k,v) in range(10) )
900 896 # will illustrate the error, if this exception catch is
901 897 # disabled.
902 898 call = tpl_call_fail % func
903 899
904 900 # Don't attempt to tokenize binary files.
905 901 if file.endswith(('.so', '.pyd', '.dll')):
906 902 return '%s %s\n' % (link, call)
907 903
908 904 elif file.endswith(('.pyc', '.pyo')):
909 905 # Look up the corresponding source file.
910 906 try:
911 907 file = openpy.source_from_cache(file)
912 908 except ValueError:
913 909 # Failed to get the source file for some reason
914 910 # E.g. https://github.com/ipython/ipython/issues/9486
915 911 return '%s %s\n' % (link, call)
916 912
917 913 def linereader(file=file, lnum=[lnum], getline=linecache.getline):
918 914 line = getline(file, lnum[0])
919 915 lnum[0] += 1
920 916 return line
921 917
922 918 # Build the list of names on this line of code where the exception
923 919 # occurred.
924 920 try:
925 921 names = []
926 922 name_cont = False
927 923
928 924 for token_type, token, start, end, line in generate_tokens(linereader):
929 925 # build composite names
930 926 if token_type == tokenize.NAME and token not in keyword.kwlist:
931 927 if name_cont:
932 928 # Continuation of a dotted name
933 929 try:
934 930 names[-1].append(token)
935 931 except IndexError:
936 932 names.append([token])
937 933 name_cont = False
938 934 else:
939 935 # Regular new names. We append everything, the caller
940 936 # will be responsible for pruning the list later. It's
941 937 # very tricky to try to prune as we go, b/c composite
942 938 # names can fool us. The pruning at the end is easy
943 939 # to do (or the caller can print a list with repeated
944 940 # names if so desired.
945 941 names.append([token])
946 942 elif token == '.':
947 943 name_cont = True
948 944 elif token_type == tokenize.NEWLINE:
949 945 break
950 946
951 947 except (IndexError, UnicodeDecodeError, SyntaxError):
952 948 # signals exit of tokenizer
953 949 # SyntaxError can occur if the file is not actually Python
954 950 # - see gh-6300
955 951 pass
956 952 except tokenize.TokenError as msg:
957 953 _m = ("An unexpected error occurred while tokenizing input\n"
958 954 "The following traceback may be corrupted or invalid\n"
959 955 "The error message is: %s\n" % msg)
960 956 error(_m)
961 957
962 958 # Join composite names (e.g. "dict.fromkeys")
963 959 names = ['.'.join(n) for n in names]
964 960 # prune names list of duplicates, but keep the right order
965 961 unique_names = uniq_stable(names)
966 962
967 963 # Start loop over vars
968 964 lvals = []
969 965 if self.include_vars:
970 966 for name_full in unique_names:
971 967 name_base = name_full.split('.', 1)[0]
972 968 if name_base in frame.f_code.co_varnames:
973 969 if name_base in locals:
974 970 try:
975 971 value = repr(eval(name_full, locals))
976 972 except:
977 973 value = undefined
978 974 else:
979 975 value = undefined
980 976 name = tpl_local_var % name_full
981 977 else:
982 978 if name_base in frame.f_globals:
983 979 try:
984 980 value = repr(eval(name_full, frame.f_globals))
985 981 except:
986 982 value = undefined
987 983 else:
988 984 value = undefined
989 985 name = tpl_global_var % name_full
990 986 lvals.append(tpl_name_val % (name, value))
991 987 if lvals:
992 988 lvals = '%s%s' % (indent, em_normal.join(lvals))
993 989 else:
994 990 lvals = ''
995 991
996 992 level = '%s %s\n' % (link, call)
997 993
998 994 if index is None:
999 995 return level
1000 996 else:
1001 997 _line_format = PyColorize.Parser(style=col_scheme, parent=self).format2
1002 998 return '%s%s' % (level, ''.join(
1003 999 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1004 1000 _line_format)))
1005 1001
1006 1002 def prepare_chained_exception_message(self, cause):
1007 1003 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1008 1004 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1009 1005
1010 1006 if cause:
1011 1007 message = [[direct_cause]]
1012 1008 else:
1013 1009 message = [[exception_during_handling]]
1014 1010 return message
1015 1011
1016 1012 def prepare_header(self, etype, long_version=False):
1017 1013 colors = self.Colors # just a shorthand + quicker name lookup
1018 1014 colorsnormal = colors.Normal # used a lot
1019 1015 exc = '%s%s%s' % (colors.excName, etype, colorsnormal)
1020 1016 width = min(75, get_terminal_size()[0])
1021 1017 if long_version:
1022 1018 # Header with the exception type, python version, and date
1023 1019 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
1024 1020 date = time.ctime(time.time())
1025 1021
1026 1022 head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal,
1027 1023 exc, ' ' * (width - len(str(etype)) - len(pyver)),
1028 1024 pyver, date.rjust(width) )
1029 1025 head += "\nA problem occurred executing Python code. Here is the sequence of function" \
1030 1026 "\ncalls leading up to the error, with the most recent (innermost) call last."
1031 1027 else:
1032 1028 # Simplified header
1033 1029 head = '%s%s' % (exc, 'Traceback (most recent call last)'. \
1034 1030 rjust(width - len(str(etype))) )
1035 1031
1036 1032 return head
1037 1033
1038 1034 def format_exception(self, etype, evalue):
1039 1035 colors = self.Colors # just a shorthand + quicker name lookup
1040 1036 colorsnormal = colors.Normal # used a lot
1041 1037 indent = ' ' * INDENT_SIZE
1042 1038 # Get (safely) a string form of the exception info
1043 1039 try:
1044 1040 etype_str, evalue_str = map(str, (etype, evalue))
1045 1041 except:
1046 1042 # User exception is improperly defined.
1047 1043 etype, evalue = str, sys.exc_info()[:2]
1048 1044 etype_str, evalue_str = map(str, (etype, evalue))
1049 1045 # ... and format it
1050 return ['%s%s%s: %s' % (colors.excName, etype_str,
1051 colorsnormal, py3compat.cast_unicode(evalue_str))]
1046 return ['%s%s%s: %s' % (colors.excName, etype_str, colorsnormal, evalue_str)]
1052 1047
1053 1048 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
1054 1049 """Formats the header, traceback and exception message for a single exception.
1055 1050
1056 1051 This may be called multiple times by Python 3 exception chaining
1057 1052 (PEP 3134).
1058 1053 """
1059 1054 # some locals
1060 1055 orig_etype = etype
1061 1056 try:
1062 1057 etype = etype.__name__
1063 1058 except AttributeError:
1064 1059 pass
1065 1060
1066 1061 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1067 1062 head = self.prepare_header(etype, self.long_header)
1068 1063 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
1069 1064
1070 1065 if records is None:
1071 1066 return ""
1072 1067
1073 1068 last_unique, recursion_repeat = find_recursion(orig_etype, evalue, records)
1074 1069
1075 1070 frames = self.format_records(records, last_unique, recursion_repeat)
1076 1071
1077 1072 formatted_exception = self.format_exception(etype, evalue)
1078 1073 if records:
1079 1074 filepath, lnum = records[-1][1:3]
1080 1075 filepath = os.path.abspath(filepath)
1081 1076 ipinst = get_ipython()
1082 1077 if ipinst is not None:
1083 1078 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
1084 1079
1085 1080 return [[head] + frames + [''.join(formatted_exception[0])]]
1086 1081
1087 1082 def get_records(self, etb, number_of_lines_of_context, tb_offset):
1088 1083 try:
1089 1084 # Try the default getinnerframes and Alex's: Alex's fixes some
1090 1085 # problems, but it generates empty tracebacks for console errors
1091 1086 # (5 blanks lines) where none should be returned.
1092 1087 return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)
1093 1088 except UnicodeDecodeError:
1094 1089 # This can occur if a file's encoding magic comment is wrong.
1095 1090 # I can't see a way to recover without duplicating a bunch of code
1096 1091 # from the stdlib traceback module. --TK
1097 1092 error('\nUnicodeDecodeError while processing traceback.\n')
1098 1093 return None
1099 1094 except:
1100 1095 # FIXME: I've been getting many crash reports from python 2.3
1101 1096 # users, traceable to inspect.py. If I can find a small test-case
1102 1097 # to reproduce this, I should either write a better workaround or
1103 1098 # file a bug report against inspect (if that's the real problem).
1104 1099 # So far, I haven't been able to find an isolated example to
1105 1100 # reproduce the problem.
1106 1101 inspect_error()
1107 1102 traceback.print_exc(file=self.ostream)
1108 1103 info('\nUnfortunately, your original traceback can not be constructed.\n')
1109 1104 return None
1110 1105
1111 1106 def get_parts_of_chained_exception(self, evalue):
1112 1107 def get_chained_exception(exception_value):
1113 1108 cause = getattr(exception_value, '__cause__', None)
1114 1109 if cause:
1115 1110 return cause
1116 1111 if getattr(exception_value, '__suppress_context__', False):
1117 1112 return None
1118 1113 return getattr(exception_value, '__context__', None)
1119 1114
1120 1115 chained_evalue = get_chained_exception(evalue)
1121 1116
1122 1117 if chained_evalue:
1123 1118 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1124 1119
1125 1120 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1126 1121 number_of_lines_of_context=5):
1127 1122 """Return a nice text document describing the traceback."""
1128 1123
1129 1124 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
1130 1125 tb_offset)
1131 1126
1132 1127 colors = self.Colors # just a shorthand + quicker name lookup
1133 1128 colorsnormal = colors.Normal # used a lot
1134 1129 head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal)
1135 1130 structured_traceback_parts = [head]
1136 1131 if py3compat.PY3:
1137 1132 chained_exceptions_tb_offset = 0
1138 1133 lines_of_context = 3
1139 1134 formatted_exceptions = formatted_exception
1140 1135 exception = self.get_parts_of_chained_exception(evalue)
1141 1136 if exception:
1142 1137 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1143 1138 etype, evalue, etb = exception
1144 1139 else:
1145 1140 evalue = None
1146 1141 chained_exc_ids = set()
1147 1142 while evalue:
1148 1143 formatted_exceptions += self.format_exception_as_a_whole(etype, evalue, etb, lines_of_context,
1149 1144 chained_exceptions_tb_offset)
1150 1145 exception = self.get_parts_of_chained_exception(evalue)
1151 1146
1152 1147 if exception and not id(exception[1]) in chained_exc_ids:
1153 1148 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
1154 1149 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
1155 1150 etype, evalue, etb = exception
1156 1151 else:
1157 1152 evalue = None
1158 1153
1159 1154 # we want to see exceptions in a reversed order:
1160 1155 # the first exception should be on top
1161 1156 for formatted_exception in reversed(formatted_exceptions):
1162 1157 structured_traceback_parts += formatted_exception
1163 1158 else:
1164 1159 structured_traceback_parts += formatted_exception[0]
1165 1160
1166 1161 return structured_traceback_parts
1167 1162
1168 1163 def debugger(self, force=False):
1169 1164 """Call up the pdb debugger if desired, always clean up the tb
1170 1165 reference.
1171 1166
1172 1167 Keywords:
1173 1168
1174 1169 - force(False): by default, this routine checks the instance call_pdb
1175 1170 flag and does not actually invoke the debugger if the flag is false.
1176 1171 The 'force' option forces the debugger to activate even if the flag
1177 1172 is false.
1178 1173
1179 1174 If the call_pdb flag is set, the pdb interactive debugger is
1180 1175 invoked. In all cases, the self.tb reference to the current traceback
1181 1176 is deleted to prevent lingering references which hamper memory
1182 1177 management.
1183 1178
1184 1179 Note that each call to pdb() does an 'import readline', so if your app
1185 1180 requires a special setup for the readline completers, you'll have to
1186 1181 fix that by hand after invoking the exception handler."""
1187 1182
1188 1183 if force or self.call_pdb:
1189 1184 if self.pdb is None:
1190 1185 self.pdb = self.debugger_cls()
1191 1186 # the system displayhook may have changed, restore the original
1192 1187 # for pdb
1193 1188 display_trap = DisplayTrap(hook=sys.__displayhook__)
1194 1189 with display_trap:
1195 1190 self.pdb.reset()
1196 1191 # Find the right frame so we don't pop up inside ipython itself
1197 1192 if hasattr(self, 'tb') and self.tb is not None:
1198 1193 etb = self.tb
1199 1194 else:
1200 1195 etb = self.tb = sys.last_traceback
1201 1196 while self.tb is not None and self.tb.tb_next is not None:
1202 1197 self.tb = self.tb.tb_next
1203 1198 if etb and etb.tb_next:
1204 1199 etb = etb.tb_next
1205 1200 self.pdb.botframe = etb.tb_frame
1206 1201 self.pdb.interaction(self.tb.tb_frame, self.tb)
1207 1202
1208 1203 if hasattr(self, 'tb'):
1209 1204 del self.tb
1210 1205
1211 1206 def handler(self, info=None):
1212 1207 (etype, evalue, etb) = info or sys.exc_info()
1213 1208 self.tb = etb
1214 1209 ostream = self.ostream
1215 1210 ostream.flush()
1216 1211 ostream.write(self.text(etype, evalue, etb))
1217 1212 ostream.write('\n')
1218 1213 ostream.flush()
1219 1214
1220 1215 # Changed so an instance can just be called as VerboseTB_inst() and print
1221 1216 # out the right info on its own.
1222 1217 def __call__(self, etype=None, evalue=None, etb=None):
1223 1218 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1224 1219 if etb is None:
1225 1220 self.handler()
1226 1221 else:
1227 1222 self.handler((etype, evalue, etb))
1228 1223 try:
1229 1224 self.debugger()
1230 1225 except KeyboardInterrupt:
1231 1226 print("\nKeyboardInterrupt")
1232 1227
1233 1228
1234 1229 #----------------------------------------------------------------------------
1235 1230 class FormattedTB(VerboseTB, ListTB):
1236 1231 """Subclass ListTB but allow calling with a traceback.
1237 1232
1238 1233 It can thus be used as a sys.excepthook for Python > 2.1.
1239 1234
1240 1235 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1241 1236
1242 1237 Allows a tb_offset to be specified. This is useful for situations where
1243 1238 one needs to remove a number of topmost frames from the traceback (such as
1244 1239 occurs with python programs that themselves execute other python code,
1245 1240 like Python shells). """
1246 1241
1247 1242 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1248 1243 ostream=None,
1249 1244 tb_offset=0, long_header=False, include_vars=False,
1250 1245 check_cache=None, debugger_cls=None,
1251 1246 parent=None, config=None):
1252 1247
1253 1248 # NEVER change the order of this list. Put new modes at the end:
1254 1249 self.valid_modes = ['Plain', 'Context', 'Verbose']
1255 1250 self.verbose_modes = self.valid_modes[1:3]
1256 1251
1257 1252 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1258 1253 ostream=ostream, tb_offset=tb_offset,
1259 1254 long_header=long_header, include_vars=include_vars,
1260 1255 check_cache=check_cache, debugger_cls=debugger_cls,
1261 1256 parent=parent, config=config)
1262 1257
1263 1258 # Different types of tracebacks are joined with different separators to
1264 1259 # form a single string. They are taken from this dict
1265 1260 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1266 1261 # set_mode also sets the tb_join_char attribute
1267 1262 self.set_mode(mode)
1268 1263
1269 1264 def _extract_tb(self, tb):
1270 1265 if tb:
1271 1266 return traceback.extract_tb(tb)
1272 1267 else:
1273 1268 return None
1274 1269
1275 1270 def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5):
1276 1271 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1277 1272 mode = self.mode
1278 1273 if mode in self.verbose_modes:
1279 1274 # Verbose modes need a full traceback
1280 1275 return VerboseTB.structured_traceback(
1281 1276 self, etype, value, tb, tb_offset, number_of_lines_of_context
1282 1277 )
1283 1278 else:
1284 1279 # We must check the source cache because otherwise we can print
1285 1280 # out-of-date source code.
1286 1281 self.check_cache()
1287 1282 # Now we can extract and format the exception
1288 1283 elist = self._extract_tb(tb)
1289 1284 return ListTB.structured_traceback(
1290 1285 self, etype, value, elist, tb_offset, number_of_lines_of_context
1291 1286 )
1292 1287
1293 1288 def stb2text(self, stb):
1294 1289 """Convert a structured traceback (a list) to a string."""
1295 1290 return self.tb_join_char.join(stb)
1296 1291
1297 1292
1298 1293 def set_mode(self, mode=None):
1299 1294 """Switch to the desired mode.
1300 1295
1301 1296 If mode is not specified, cycles through the available modes."""
1302 1297
1303 1298 if not mode:
1304 1299 new_idx = (self.valid_modes.index(self.mode) + 1 ) % \
1305 1300 len(self.valid_modes)
1306 1301 self.mode = self.valid_modes[new_idx]
1307 1302 elif mode not in self.valid_modes:
1308 1303 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
1309 1304 'Valid modes: ' + str(self.valid_modes))
1310 1305 else:
1311 1306 self.mode = mode
1312 1307 # include variable details only in 'Verbose' mode
1313 1308 self.include_vars = (self.mode == self.valid_modes[2])
1314 1309 # Set the join character for generating text tracebacks
1315 1310 self.tb_join_char = self._join_chars[self.mode]
1316 1311
1317 1312 # some convenient shortcuts
1318 1313 def plain(self):
1319 1314 self.set_mode(self.valid_modes[0])
1320 1315
1321 1316 def context(self):
1322 1317 self.set_mode(self.valid_modes[1])
1323 1318
1324 1319 def verbose(self):
1325 1320 self.set_mode(self.valid_modes[2])
1326 1321
1327 1322
1328 1323 #----------------------------------------------------------------------------
1329 1324 class AutoFormattedTB(FormattedTB):
1330 1325 """A traceback printer which can be called on the fly.
1331 1326
1332 1327 It will find out about exceptions by itself.
1333 1328
1334 1329 A brief example::
1335 1330
1336 1331 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1337 1332 try:
1338 1333 ...
1339 1334 except:
1340 1335 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1341 1336 """
1342 1337
1343 1338 def __call__(self, etype=None, evalue=None, etb=None,
1344 1339 out=None, tb_offset=None):
1345 1340 """Print out a formatted exception traceback.
1346 1341
1347 1342 Optional arguments:
1348 1343 - out: an open file-like object to direct output to.
1349 1344
1350 1345 - tb_offset: the number of frames to skip over in the stack, on a
1351 1346 per-call basis (this overrides temporarily the instance's tb_offset
1352 1347 given at initialization time. """
1353 1348
1354 1349 if out is None:
1355 1350 out = self.ostream
1356 1351 out.flush()
1357 1352 out.write(self.text(etype, evalue, etb, tb_offset))
1358 1353 out.write('\n')
1359 1354 out.flush()
1360 1355 # FIXME: we should remove the auto pdb behavior from here and leave
1361 1356 # that to the clients.
1362 1357 try:
1363 1358 self.debugger()
1364 1359 except KeyboardInterrupt:
1365 1360 print("\nKeyboardInterrupt")
1366 1361
1367 1362 def structured_traceback(self, etype=None, value=None, tb=None,
1368 1363 tb_offset=None, number_of_lines_of_context=5):
1369 1364 if etype is None:
1370 1365 etype, value, tb = sys.exc_info()
1371 1366 self.tb = tb
1372 1367 return FormattedTB.structured_traceback(
1373 1368 self, etype, value, tb, tb_offset, number_of_lines_of_context)
1374 1369
1375 1370
1376 1371 #---------------------------------------------------------------------------
1377 1372
1378 1373 # A simple class to preserve Nathan's original functionality.
1379 1374 class ColorTB(FormattedTB):
1380 1375 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1381 1376
1382 1377 def __init__(self, color_scheme='Linux', call_pdb=0, **kwargs):
1383 1378 FormattedTB.__init__(self, color_scheme=color_scheme,
1384 1379 call_pdb=call_pdb, **kwargs)
1385 1380
1386 1381
1387 1382 class SyntaxTB(ListTB):
1388 1383 """Extension which holds some state: the last exception value"""
1389 1384
1390 1385 def __init__(self, color_scheme='NoColor', parent=None, config=None):
1391 1386 ListTB.__init__(self, color_scheme, parent=parent, config=config)
1392 1387 self.last_syntax_error = None
1393 1388
1394 1389 def __call__(self, etype, value, elist):
1395 1390 self.last_syntax_error = value
1396 1391
1397 1392 ListTB.__call__(self, etype, value, elist)
1398 1393
1399 1394 def structured_traceback(self, etype, value, elist, tb_offset=None,
1400 1395 context=5):
1401 1396 # If the source file has been edited, the line in the syntax error can
1402 1397 # be wrong (retrieved from an outdated cache). This replaces it with
1403 1398 # the current value.
1404 1399 if isinstance(value, SyntaxError) \
1405 1400 and isinstance(value.filename, str) \
1406 1401 and isinstance(value.lineno, int):
1407 1402 linecache.checkcache(value.filename)
1408 1403 newtext = linecache.getline(value.filename, value.lineno)
1409 1404 if newtext:
1410 1405 value.text = newtext
1411 1406 self.last_syntax_error = value
1412 1407 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1413 1408 tb_offset=tb_offset, context=context)
1414 1409
1415 1410 def clear_err_state(self):
1416 1411 """Return the current error state and clear it"""
1417 1412 e = self.last_syntax_error
1418 1413 self.last_syntax_error = None
1419 1414 return e
1420 1415
1421 1416 def stb2text(self, stb):
1422 1417 """Convert a structured traceback (a list) to a string."""
1423 1418 return ''.join(stb)
1424 1419
1425 1420
1426 1421 # some internal-use functions
1427 1422 def text_repr(value):
1428 1423 """Hopefully pretty robust repr equivalent."""
1429 1424 # this is pretty horrible but should always return *something*
1430 1425 try:
1431 1426 return pydoc.text.repr(value)
1432 1427 except KeyboardInterrupt:
1433 1428 raise
1434 1429 except:
1435 1430 try:
1436 1431 return repr(value)
1437 1432 except KeyboardInterrupt:
1438 1433 raise
1439 1434 except:
1440 1435 try:
1441 1436 # all still in an except block so we catch
1442 1437 # getattr raising
1443 1438 name = getattr(value, '__name__', None)
1444 1439 if name:
1445 1440 # ick, recursion
1446 1441 return text_repr(name)
1447 1442 klass = getattr(value, '__class__', None)
1448 1443 if klass:
1449 1444 return '%s instance' % text_repr(klass)
1450 1445 except KeyboardInterrupt:
1451 1446 raise
1452 1447 except:
1453 1448 return 'UNRECOVERABLE REPR FAILURE'
1454 1449
1455 1450
1456 1451 def eqrepr(value, repr=text_repr):
1457 1452 return '=%s' % repr(value)
1458 1453
1459 1454
1460 1455 def nullrepr(value, repr=text_repr):
1461 1456 return ''
@@ -1,201 +1,201 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for handling LaTeX."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 from io import BytesIO, open
8 8 import os
9 9 import tempfile
10 10 import shutil
11 11 import subprocess
12 12 from base64 import encodebytes
13 13
14 14 from IPython.utils.process import find_cmd, FindCmdError
15 15 from traitlets.config import get_config
16 16 from traitlets.config.configurable import SingletonConfigurable
17 17 from traitlets import List, Bool, Unicode
18 from IPython.utils.py3compat import cast_unicode, cast_unicode_py2 as u
18 from IPython.utils.py3compat import cast_unicode
19 19
20 20
21 21 class LaTeXTool(SingletonConfigurable):
22 22 """An object to store configuration of the LaTeX tool."""
23 23 def _config_default(self):
24 24 return get_config()
25 25
26 26 backends = List(
27 27 Unicode(), ["matplotlib", "dvipng"],
28 28 help="Preferred backend to draw LaTeX math equations. "
29 29 "Backends in the list are checked one by one and the first "
30 30 "usable one is used. Note that `matplotlib` backend "
31 31 "is usable only for inline style equations. To draw "
32 32 "display style equations, `dvipng` backend must be specified. ",
33 33 # It is a List instead of Enum, to make configuration more
34 34 # flexible. For example, to use matplotlib mainly but dvipng
35 35 # for display style, the default ["matplotlib", "dvipng"] can
36 36 # be used. To NOT use dvipng so that other repr such as
37 37 # unicode pretty printing is used, you can use ["matplotlib"].
38 38 ).tag(config=True)
39 39
40 40 use_breqn = Bool(
41 41 True,
42 42 help="Use breqn.sty to automatically break long equations. "
43 43 "This configuration takes effect only for dvipng backend.",
44 44 ).tag(config=True)
45 45
46 46 packages = List(
47 47 ['amsmath', 'amsthm', 'amssymb', 'bm'],
48 48 help="A list of packages to use for dvipng backend. "
49 49 "'breqn' will be automatically appended when use_breqn=True.",
50 50 ).tag(config=True)
51 51
52 52 preamble = Unicode(
53 53 help="Additional preamble to use when generating LaTeX source "
54 54 "for dvipng backend.",
55 55 ).tag(config=True)
56 56
57 57
58 58 def latex_to_png(s, encode=False, backend=None, wrap=False):
59 59 """Render a LaTeX string to PNG.
60 60
61 61 Parameters
62 62 ----------
63 63 s : str
64 64 The raw string containing valid inline LaTeX.
65 65 encode : bool, optional
66 66 Should the PNG data base64 encoded to make it JSON'able.
67 67 backend : {matplotlib, dvipng}
68 68 Backend for producing PNG data.
69 69 wrap : bool
70 70 If true, Automatically wrap `s` as a LaTeX equation.
71 71
72 72 None is returned when the backend cannot be used.
73 73
74 74 """
75 75 s = cast_unicode(s)
76 76 allowed_backends = LaTeXTool.instance().backends
77 77 if backend is None:
78 78 backend = allowed_backends[0]
79 79 if backend not in allowed_backends:
80 80 return None
81 81 if backend == 'matplotlib':
82 82 f = latex_to_png_mpl
83 83 elif backend == 'dvipng':
84 84 f = latex_to_png_dvipng
85 85 else:
86 86 raise ValueError('No such backend {0}'.format(backend))
87 87 bin_data = f(s, wrap)
88 88 if encode and bin_data:
89 89 bin_data = encodebytes(bin_data)
90 90 return bin_data
91 91
92 92
93 93 def latex_to_png_mpl(s, wrap):
94 94 try:
95 95 from matplotlib import mathtext
96 96 from pyparsing import ParseFatalException
97 97 except ImportError:
98 98 return None
99 99
100 100 # mpl mathtext doesn't support display math, force inline
101 101 s = s.replace('$$', '$')
102 102 if wrap:
103 103 s = u'${0}$'.format(s)
104 104
105 105 try:
106 106 mt = mathtext.MathTextParser('bitmap')
107 107 f = BytesIO()
108 108 mt.to_png(f, s, fontsize=12)
109 109 return f.getvalue()
110 110 except (ValueError, RuntimeError, ParseFatalException):
111 111 return None
112 112
113 113
114 114 def latex_to_png_dvipng(s, wrap):
115 115 try:
116 116 find_cmd('latex')
117 117 find_cmd('dvipng')
118 118 except FindCmdError:
119 119 return None
120 120 try:
121 121 workdir = tempfile.mkdtemp()
122 122 tmpfile = os.path.join(workdir, "tmp.tex")
123 123 dvifile = os.path.join(workdir, "tmp.dvi")
124 124 outfile = os.path.join(workdir, "tmp.png")
125 125
126 126 with open(tmpfile, "w", encoding='utf8') as f:
127 127 f.writelines(genelatex(s, wrap))
128 128
129 129 with open(os.devnull, 'wb') as devnull:
130 130 subprocess.check_call(
131 131 ["latex", "-halt-on-error", "-interaction", "batchmode", tmpfile],
132 132 cwd=workdir, stdout=devnull, stderr=devnull)
133 133
134 134 subprocess.check_call(
135 135 ["dvipng", "-T", "tight", "-x", "1500", "-z", "9",
136 136 "-bg", "transparent", "-o", outfile, dvifile], cwd=workdir,
137 137 stdout=devnull, stderr=devnull)
138 138
139 139 with open(outfile, "rb") as f:
140 140 return f.read()
141 141 except subprocess.CalledProcessError:
142 142 return None
143 143 finally:
144 144 shutil.rmtree(workdir)
145 145
146 146
147 147 def kpsewhich(filename):
148 148 """Invoke kpsewhich command with an argument `filename`."""
149 149 try:
150 150 find_cmd("kpsewhich")
151 151 proc = subprocess.Popen(
152 152 ["kpsewhich", filename],
153 153 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
154 154 (stdout, stderr) = proc.communicate()
155 155 return stdout.strip().decode('utf8', 'replace')
156 156 except FindCmdError:
157 157 pass
158 158
159 159
160 160 def genelatex(body, wrap):
161 161 """Generate LaTeX document for dvipng backend."""
162 162 lt = LaTeXTool.instance()
163 163 breqn = wrap and lt.use_breqn and kpsewhich("breqn.sty")
164 yield u(r'\documentclass{article}')
164 yield r'\documentclass{article}'
165 165 packages = lt.packages
166 166 if breqn:
167 167 packages = packages + ['breqn']
168 168 for pack in packages:
169 yield u(r'\usepackage{{{0}}}'.format(pack))
170 yield u(r'\pagestyle{empty}')
169 yield r'\usepackage{{{0}}}'.format(pack)
170 yield r'\pagestyle{empty}'
171 171 if lt.preamble:
172 172 yield lt.preamble
173 yield u(r'\begin{document}')
173 yield r'\begin{document}'
174 174 if breqn:
175 yield u(r'\begin{dmath*}')
175 yield r'\begin{dmath*}'
176 176 yield body
177 yield u(r'\end{dmath*}')
177 yield r'\end{dmath*}'
178 178 elif wrap:
179 179 yield u'$${0}$$'.format(body)
180 180 else:
181 181 yield body
182 182 yield u'\end{document}'
183 183
184 184
185 185 _data_uri_template_png = u"""<img src="data:image/png;base64,%s" alt=%s />"""
186 186
187 187 def latex_to_html(s, alt='image'):
188 188 """Render LaTeX to HTML with embedded PNG data using data URIs.
189 189
190 190 Parameters
191 191 ----------
192 192 s : str
193 193 The raw string containing valid inline LateX.
194 194 alt : str
195 195 The alt text to use for the HTML.
196 196 """
197 197 base64_data = latex_to_png(s, encode=True).decode('ascii')
198 198 if base64_data:
199 199 return _data_uri_template_png % (base64_data, alt)
200 200
201 201
@@ -1,530 +1,530 b''
1 1 """IPython terminal interface using prompt_toolkit"""
2 2
3 3 import os
4 4 import sys
5 5 import warnings
6 6 from warnings import warn
7 7
8 8 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
9 9 from IPython.utils import io
10 from IPython.utils.py3compat import cast_unicode_py2, input
10 from IPython.utils.py3compat import input
11 11 from IPython.utils.terminal import toggle_set_term_title, set_term_title
12 12 from IPython.utils.process import abbrev_cwd
13 13 from traitlets import (
14 14 Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union,
15 15 Any,
16 16 )
17 17
18 18 from prompt_toolkit.document import Document
19 19 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
20 20 from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
21 21 from prompt_toolkit.history import InMemoryHistory
22 22 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout, create_output
23 23 from prompt_toolkit.interface import CommandLineInterface
24 24 from prompt_toolkit.key_binding.manager import KeyBindingManager
25 25 from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
26 26 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
27 27
28 28 from pygments.styles import get_style_by_name, get_all_styles
29 29 from pygments.style import Style
30 30 from pygments.token import Token
31 31
32 32 from .debugger import TerminalPdb, Pdb
33 33 from .magics import TerminalMagics
34 34 from .pt_inputhooks import get_inputhook_name_and_func
35 35 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
36 36 from .ptutils import IPythonPTCompleter, IPythonPTLexer
37 37 from .shortcuts import register_ipython_shortcuts
38 38
39 39 DISPLAY_BANNER_DEPRECATED = object()
40 40
41 41
42 42 class _NoStyle(Style): pass
43 43
44 44
45 45
46 46 _style_overrides_light_bg = {
47 47 Token.Prompt: '#0000ff',
48 48 Token.PromptNum: '#0000ee bold',
49 49 Token.OutPrompt: '#cc0000',
50 50 Token.OutPromptNum: '#bb0000 bold',
51 51 }
52 52
53 53 _style_overrides_linux = {
54 54 Token.Prompt: '#00cc00',
55 55 Token.PromptNum: '#00bb00 bold',
56 56 Token.OutPrompt: '#cc0000',
57 57 Token.OutPromptNum: '#bb0000 bold',
58 58 }
59 59
60 60
61 61
62 62 def get_default_editor():
63 63 try:
64 64 return os.environ['EDITOR']
65 65 except KeyError:
66 66 pass
67 67 except UnicodeError:
68 68 warn("$EDITOR environment variable is not pure ASCII. Using platform "
69 69 "default editor.")
70 70
71 71 if os.name == 'posix':
72 72 return 'vi' # the only one guaranteed to be there!
73 73 else:
74 74 return 'notepad' # same in Windows!
75 75
76 76 # conservatively check for tty
77 77 # overridden streams can result in things like:
78 78 # - sys.stdin = None
79 79 # - no isatty method
80 80 for _name in ('stdin', 'stdout', 'stderr'):
81 81 _stream = getattr(sys, _name)
82 82 if not _stream or not hasattr(_stream, 'isatty') or not _stream.isatty():
83 83 _is_tty = False
84 84 break
85 85 else:
86 86 _is_tty = True
87 87
88 88
89 89 _use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
90 90
91 91 class TerminalInteractiveShell(InteractiveShell):
92 92 space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
93 93 'to reserve for the completion menu'
94 94 ).tag(config=True)
95 95
96 96 def _space_for_menu_changed(self, old, new):
97 97 self._update_layout()
98 98
99 99 pt_cli = None
100 100 debugger_history = None
101 101 _pt_app = None
102 102
103 103 simple_prompt = Bool(_use_simple_prompt,
104 104 help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
105 105
106 106 Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
107 107 IPython own testing machinery, and emacs inferior-shell integration through elpy.
108 108
109 109 This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
110 110 environment variable is set, or the current terminal is not a tty."""
111 111 ).tag(config=True)
112 112
113 113 @property
114 114 def debugger_cls(self):
115 115 return Pdb if self.simple_prompt else TerminalPdb
116 116
117 117 confirm_exit = Bool(True,
118 118 help="""
119 119 Set to confirm when you try to exit IPython with an EOF (Control-D
120 120 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
121 121 you can force a direct exit without any confirmation.""",
122 122 ).tag(config=True)
123 123
124 124 editing_mode = Unicode('emacs',
125 125 help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
126 126 ).tag(config=True)
127 127
128 128 mouse_support = Bool(False,
129 129 help="Enable mouse support in the prompt"
130 130 ).tag(config=True)
131 131
132 132 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
133 133 help="""The name or class of a Pygments style to use for syntax
134 134 highlighting: \n %s""" % ', '.join(get_all_styles())
135 135 ).tag(config=True)
136 136
137 137
138 138 @observe('highlighting_style')
139 139 @observe('colors')
140 140 def _highlighting_style_changed(self, change):
141 141 self.refresh_style()
142 142
143 143 def refresh_style(self):
144 144 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
145 145
146 146
147 147 highlighting_style_overrides = Dict(
148 148 help="Override highlighting format for specific tokens"
149 149 ).tag(config=True)
150 150
151 151 true_color = Bool(False,
152 152 help=("Use 24bit colors instead of 256 colors in prompt highlighting. "
153 153 "If your terminal supports true color, the following command "
154 154 "should print 'TRUECOLOR' in orange: "
155 155 "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"")
156 156 ).tag(config=True)
157 157
158 158 editor = Unicode(get_default_editor(),
159 159 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
160 160 ).tag(config=True)
161 161
162 162 prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
163 163
164 164 prompts = Instance(Prompts)
165 165
166 166 @default('prompts')
167 167 def _prompts_default(self):
168 168 return self.prompts_class(self)
169 169
170 170 @observe('prompts')
171 171 def _(self, change):
172 172 self._update_layout()
173 173
174 174 @default('displayhook_class')
175 175 def _displayhook_class_default(self):
176 176 return RichPromptDisplayHook
177 177
178 178 term_title = Bool(True,
179 179 help="Automatically set the terminal title"
180 180 ).tag(config=True)
181 181
182 182 term_title_format = Unicode("IPython: {cwd}",
183 183 help="Customize the terminal title format. This is a python format string. " +
184 184 "Available substitutions are: {cwd}."
185 185 ).tag(config=True)
186 186
187 187 display_completions = Enum(('column', 'multicolumn','readlinelike'),
188 188 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
189 189 "'readlinelike'. These options are for `prompt_toolkit`, see "
190 190 "`prompt_toolkit` documentation for more information."
191 191 ),
192 192 default_value='multicolumn').tag(config=True)
193 193
194 194 highlight_matching_brackets = Bool(True,
195 195 help="Highlight matching brackets.",
196 196 ).tag(config=True)
197 197
198 198 extra_open_editor_shortcuts = Bool(False,
199 199 help="Enable vi (v) or Emacs (C-X C-E) shortcuts to open an external editor. "
200 200 "This is in addition to the F2 binding, which is always enabled."
201 201 ).tag(config=True)
202 202
203 203 handle_return = Any(None,
204 204 help="Provide an alternative handler to be called when the user presses "
205 205 "Return. This is an advanced option intended for debugging, which "
206 206 "may be changed or removed in later releases."
207 207 ).tag(config=True)
208 208
209 209 @observe('term_title')
210 210 def init_term_title(self, change=None):
211 211 # Enable or disable the terminal title.
212 212 if self.term_title:
213 213 toggle_set_term_title(True)
214 214 set_term_title(self.term_title_format.format(cwd=abbrev_cwd()))
215 215 else:
216 216 toggle_set_term_title(False)
217 217
218 218 def init_display_formatter(self):
219 219 super(TerminalInteractiveShell, self).init_display_formatter()
220 220 # terminal only supports plain text
221 221 self.display_formatter.active_types = ['text/plain']
222 222 # disable `_ipython_display_`
223 223 self.display_formatter.ipython_display_formatter.enabled = False
224 224
225 225 def init_prompt_toolkit_cli(self):
226 226 if self.simple_prompt:
227 227 # Fall back to plain non-interactive output for tests.
228 228 # This is very limited, and only accepts a single line.
229 229 def prompt():
230 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
230 return input('In [%d]: ' % self.execution_count)
231 231 self.prompt_for_code = prompt
232 232 return
233 233
234 234 # Set up keyboard shortcuts
235 235 kbmanager = KeyBindingManager.for_prompt(
236 236 enable_open_in_editor=self.extra_open_editor_shortcuts,
237 237 )
238 238 register_ipython_shortcuts(kbmanager.registry, self)
239 239
240 240 # Pre-populate history from IPython's history database
241 241 history = InMemoryHistory()
242 242 last_cell = u""
243 243 for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
244 244 include_latest=True):
245 245 # Ignore blank lines and consecutive duplicates
246 246 cell = cell.rstrip()
247 247 if cell and (cell != last_cell):
248 248 history.append(cell)
249 249 last_cell = cell
250 250
251 251 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
252 252 self.style = DynamicStyle(lambda: self._style)
253 253
254 254 editing_mode = getattr(EditingMode, self.editing_mode.upper())
255 255
256 256 def patch_stdout(**kwargs):
257 257 return self.pt_cli.patch_stdout_context(**kwargs)
258 258
259 259 self._pt_app = create_prompt_application(
260 260 editing_mode=editing_mode,
261 261 key_bindings_registry=kbmanager.registry,
262 262 history=history,
263 263 completer=IPythonPTCompleter(shell=self,
264 264 patch_stdout=patch_stdout),
265 265 enable_history_search=True,
266 266 style=self.style,
267 267 mouse_support=self.mouse_support,
268 268 **self._layout_options()
269 269 )
270 270 self._eventloop = create_eventloop(self.inputhook)
271 271 self.pt_cli = CommandLineInterface(
272 272 self._pt_app, eventloop=self._eventloop,
273 273 output=create_output(true_color=self.true_color))
274 274
275 275 def _make_style_from_name_or_cls(self, name_or_cls):
276 276 """
277 277 Small wrapper that make an IPython compatible style from a style name
278 278
279 279 We need that to add style for prompt ... etc.
280 280 """
281 281 style_overrides = {}
282 282 if name_or_cls == 'legacy':
283 283 legacy = self.colors.lower()
284 284 if legacy == 'linux':
285 285 style_cls = get_style_by_name('monokai')
286 286 style_overrides = _style_overrides_linux
287 287 elif legacy == 'lightbg':
288 288 style_overrides = _style_overrides_light_bg
289 289 style_cls = get_style_by_name('pastie')
290 290 elif legacy == 'neutral':
291 291 # The default theme needs to be visible on both a dark background
292 292 # and a light background, because we can't tell what the terminal
293 293 # looks like. These tweaks to the default theme help with that.
294 294 style_cls = get_style_by_name('default')
295 295 style_overrides.update({
296 296 Token.Number: '#007700',
297 297 Token.Operator: 'noinherit',
298 298 Token.String: '#BB6622',
299 299 Token.Name.Function: '#2080D0',
300 300 Token.Name.Class: 'bold #2080D0',
301 301 Token.Name.Namespace: 'bold #2080D0',
302 302 Token.Prompt: '#009900',
303 303 Token.PromptNum: '#00ff00 bold',
304 304 Token.OutPrompt: '#990000',
305 305 Token.OutPromptNum: '#ff0000 bold',
306 306 })
307 307
308 308 # Hack: Due to limited color support on the Windows console
309 309 # the prompt colors will be wrong without this
310 310 if os.name == 'nt':
311 311 style_overrides.update({
312 312 Token.Prompt: '#ansidarkgreen',
313 313 Token.PromptNum: '#ansigreen bold',
314 314 Token.OutPrompt: '#ansidarkred',
315 315 Token.OutPromptNum: '#ansired bold',
316 316 })
317 317 elif legacy =='nocolor':
318 318 style_cls=_NoStyle
319 319 style_overrides = {}
320 320 else :
321 321 raise ValueError('Got unknown colors: ', legacy)
322 322 else :
323 323 if isinstance(name_or_cls, str):
324 324 style_cls = get_style_by_name(name_or_cls)
325 325 else:
326 326 style_cls = name_or_cls
327 327 style_overrides = {
328 328 Token.Prompt: '#009900',
329 329 Token.PromptNum: '#00ff00 bold',
330 330 Token.OutPrompt: '#990000',
331 331 Token.OutPromptNum: '#ff0000 bold',
332 332 }
333 333 style_overrides.update(self.highlighting_style_overrides)
334 334 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
335 335 style_dict=style_overrides)
336 336
337 337 return style
338 338
339 339 def _layout_options(self):
340 340 """
341 341 Return the current layout option for the current Terminal InteractiveShell
342 342 """
343 343 return {
344 344 'lexer':IPythonPTLexer(),
345 345 'reserve_space_for_menu':self.space_for_menu,
346 346 'get_prompt_tokens':self.prompts.in_prompt_tokens,
347 347 'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
348 348 'multiline':True,
349 349 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
350 350
351 351 # Highlight matching brackets, but only when this setting is
352 352 # enabled, and only when the DEFAULT_BUFFER has the focus.
353 353 'extra_input_processors': [ConditionalProcessor(
354 354 processor=HighlightMatchingBracketProcessor(chars='[](){}'),
355 355 filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
356 356 Condition(lambda cli: self.highlight_matching_brackets))],
357 357 }
358 358
359 359 def _update_layout(self):
360 360 """
361 361 Ask for a re computation of the application layout, if for example ,
362 362 some configuration options have changed.
363 363 """
364 364 if self._pt_app:
365 365 self._pt_app.layout = create_prompt_layout(**self._layout_options())
366 366
367 367 def prompt_for_code(self):
368 368 document = self.pt_cli.run(
369 369 pre_run=self.pre_prompt, reset_current_buffer=True)
370 370 return document.text
371 371
372 372 def enable_win_unicode_console(self):
373 373 if sys.version_info >= (3, 6):
374 374 # Since PEP 528, Python uses the unicode APIs for the Windows
375 375 # console by default, so WUC shouldn't be needed.
376 376 return
377 377
378 378 import win_unicode_console
379 379 win_unicode_console.enable()
380 380
381 381 def init_io(self):
382 382 if sys.platform not in {'win32', 'cli'}:
383 383 return
384 384
385 385 self.enable_win_unicode_console()
386 386
387 387 import colorama
388 388 colorama.init()
389 389
390 390 # For some reason we make these wrappers around stdout/stderr.
391 391 # For now, we need to reset them so all output gets coloured.
392 392 # https://github.com/ipython/ipython/issues/8669
393 393 # io.std* are deprecated, but don't show our own deprecation warnings
394 394 # during initialization of the deprecated API.
395 395 with warnings.catch_warnings():
396 396 warnings.simplefilter('ignore', DeprecationWarning)
397 397 io.stdout = io.IOStream(sys.stdout)
398 398 io.stderr = io.IOStream(sys.stderr)
399 399
400 400 def init_magics(self):
401 401 super(TerminalInteractiveShell, self).init_magics()
402 402 self.register_magics(TerminalMagics)
403 403
404 404 def init_alias(self):
405 405 # The parent class defines aliases that can be safely used with any
406 406 # frontend.
407 407 super(TerminalInteractiveShell, self).init_alias()
408 408
409 409 # Now define aliases that only make sense on the terminal, because they
410 410 # need direct access to the console in a way that we can't emulate in
411 411 # GUI or web frontend
412 412 if os.name == 'posix':
413 413 for cmd in ['clear', 'more', 'less', 'man']:
414 414 self.alias_manager.soft_define_alias(cmd, cmd)
415 415
416 416
417 417 def __init__(self, *args, **kwargs):
418 418 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
419 419 self.init_prompt_toolkit_cli()
420 420 self.init_term_title()
421 421 self.keep_running = True
422 422
423 423 self.debugger_history = InMemoryHistory()
424 424
425 425 def ask_exit(self):
426 426 self.keep_running = False
427 427
428 428 rl_next_input = None
429 429
430 430 def pre_prompt(self):
431 431 if self.rl_next_input:
432 432 # We can't set the buffer here, because it will be reset just after
433 433 # this. Adding a callable to pre_run_callables does what we need
434 434 # after the buffer is reset.
435 s = cast_unicode_py2(self.rl_next_input)
435 s = self.rl_next_input
436 436 def set_doc():
437 437 self.pt_cli.application.buffer.document = Document(s)
438 438 if hasattr(self.pt_cli, 'pre_run_callables'):
439 439 self.pt_cli.pre_run_callables.append(set_doc)
440 440 else:
441 441 # Older version of prompt_toolkit; it's OK to set the document
442 442 # directly here.
443 443 set_doc()
444 444 self.rl_next_input = None
445 445
446 446 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
447 447
448 448 if display_banner is not DISPLAY_BANNER_DEPRECATED:
449 449 warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
450 450
451 451 self.keep_running = True
452 452 while self.keep_running:
453 453 print(self.separate_in, end='')
454 454
455 455 try:
456 456 code = self.prompt_for_code()
457 457 except EOFError:
458 458 if (not self.confirm_exit) \
459 459 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
460 460 self.ask_exit()
461 461
462 462 else:
463 463 if code:
464 464 self.run_cell(code, store_history=True)
465 465
466 466 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
467 467 # An extra layer of protection in case someone mashing Ctrl-C breaks
468 468 # out of our internal code.
469 469 if display_banner is not DISPLAY_BANNER_DEPRECATED:
470 470 warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
471 471 while True:
472 472 try:
473 473 self.interact()
474 474 break
475 475 except KeyboardInterrupt as e:
476 476 print("\n%s escaped interact()\n" % type(e).__name__)
477 477 finally:
478 478 # An interrupt during the eventloop will mess up the
479 479 # internal state of the prompt_toolkit library.
480 480 # Stopping the eventloop fixes this, see
481 481 # https://github.com/ipython/ipython/pull/9867
482 482 if hasattr(self, '_eventloop'):
483 483 self._eventloop.stop()
484 484
485 485 _inputhook = None
486 486 def inputhook(self, context):
487 487 if self._inputhook is not None:
488 488 self._inputhook(context)
489 489
490 490 active_eventloop = None
491 491 def enable_gui(self, gui=None):
492 492 if gui:
493 493 self.active_eventloop, self._inputhook =\
494 494 get_inputhook_name_and_func(gui)
495 495 else:
496 496 self.active_eventloop = self._inputhook = None
497 497
498 498 # Run !system commands directly, not through pipes, so terminal programs
499 499 # work correctly.
500 500 system = InteractiveShell.system_raw
501 501
502 502 def auto_rewrite_input(self, cmd):
503 503 """Overridden from the parent class to use fancy rewriting prompt"""
504 504 if not self.show_rewritten_input:
505 505 return
506 506
507 507 tokens = self.prompts.rewrite_prompt_tokens()
508 508 if self.pt_cli:
509 509 self.pt_cli.print_tokens(tokens)
510 510 print(cmd)
511 511 else:
512 512 prompt = ''.join(s for t, s in tokens)
513 513 print(prompt, cmd, sep='')
514 514
515 515 _prompts_before = None
516 516 def switch_doctest_mode(self, mode):
517 517 """Switch prompts to classic for %doctest_mode"""
518 518 if mode:
519 519 self._prompts_before = self.prompts
520 520 self.prompts = ClassicPrompts(self)
521 521 elif self._prompts_before:
522 522 self.prompts = self._prompts_before
523 523 self._prompts_before = None
524 524 self._update_layout()
525 525
526 526
527 527 InteractiveShellABC.register(TerminalInteractiveShell)
528 528
529 529 if __name__ == '__main__':
530 530 TerminalInteractiveShell.instance().interact()
@@ -1,127 +1,125 b''
1 1 """Token-related utilities"""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6
7 6 from collections import namedtuple
8 7 from io import StringIO
9 8 from keyword import iskeyword
10 9
11 10 from . import tokenize2
12 from .py3compat import cast_unicode_py2
11
13 12
14 13 Token = namedtuple('Token', ['token', 'text', 'start', 'end', 'line'])
15 14
16 15 def generate_tokens(readline):
17 16 """wrap generate_tokens to catch EOF errors"""
18 17 try:
19 18 for token in tokenize2.generate_tokens(readline):
20 19 yield token
21 20 except tokenize2.TokenError:
22 21 # catch EOF error
23 22 return
24 23
25 24 def line_at_cursor(cell, cursor_pos=0):
26 25 """Return the line in a cell at a given cursor position
27 26
28 27 Used for calling line-based APIs that don't support multi-line input, yet.
29 28
30 29 Parameters
31 30 ----------
32 31
33 32 cell: str
34 33 multiline block of text
35 34 cursor_pos: integer
36 35 the cursor position
37 36
38 37 Returns
39 38 -------
40 39
41 40 (line, offset): (string, integer)
42 41 The line with the current cursor, and the character offset of the start of the line.
43 42 """
44 43 offset = 0
45 44 lines = cell.splitlines(True)
46 45 for line in lines:
47 46 next_offset = offset + len(line)
48 47 if next_offset >= cursor_pos:
49 48 break
50 49 offset = next_offset
51 50 else:
52 51 line = ""
53 52 return (line, offset)
54 53
55 54 def token_at_cursor(cell, cursor_pos=0):
56 55 """Get the token at a given cursor
57 56
58 57 Used for introspection.
59 58
60 59 Function calls are prioritized, so the token for the callable will be returned
61 60 if the cursor is anywhere inside the call.
62 61
63 62 Parameters
64 63 ----------
65 64
66 65 cell : unicode
67 66 A block of Python code
68 67 cursor_pos : int
69 68 The location of the cursor in the block where the token should be found
70 69 """
71 cell = cast_unicode_py2(cell)
72 70 names = []
73 71 tokens = []
74 72 call_names = []
75 73
76 74 offsets = {1: 0} # lines start at 1
77 75 for tup in generate_tokens(StringIO(cell).readline):
78 76
79 77 tok = Token(*tup)
80 78
81 79 # token, text, start, end, line = tup
82 80 start_line, start_col = tok.start
83 81 end_line, end_col = tok.end
84 82 if end_line + 1 not in offsets:
85 83 # keep track of offsets for each line
86 84 lines = tok.line.splitlines(True)
87 85 for lineno, line in enumerate(lines, start_line + 1):
88 86 if lineno not in offsets:
89 87 offsets[lineno] = offsets[lineno-1] + len(line)
90 88
91 89 offset = offsets[start_line]
92 90 # allow '|foo' to find 'foo' at the beginning of a line
93 91 boundary = cursor_pos + 1 if start_col == 0 else cursor_pos
94 92 if offset + start_col >= boundary:
95 93 # current token starts after the cursor,
96 94 # don't consume it
97 95 break
98 96
99 97 if tok.token == tokenize2.NAME and not iskeyword(tok.text):
100 98 if names and tokens and tokens[-1].token == tokenize2.OP and tokens[-1].text == '.':
101 99 names[-1] = "%s.%s" % (names[-1], tok.text)
102 100 else:
103 101 names.append(tok.text)
104 102 elif tok.token == tokenize2.OP:
105 103 if tok.text == '=' and names:
106 104 # don't inspect the lhs of an assignment
107 105 names.pop(-1)
108 106 if tok.text == '(' and names:
109 107 # if we are inside a function call, inspect the function
110 108 call_names.append(names[-1])
111 109 elif tok.text == ')' and call_names:
112 110 call_names.pop(-1)
113 111
114 112 tokens.append(tok)
115 113
116 114 if offsets[end_line] + end_col > cursor_pos:
117 115 # we found the cursor, stop reading
118 116 break
119 117
120 118 if call_names:
121 119 return call_names[-1]
122 120 elif names:
123 121 return names[-1]
124 122 else:
125 123 return ''
126 124
127 125
General Comments 0
You need to be logged in to leave comments. Login now