##// END OF EJS Templates
Merge pull request #9375 from liukelly/jedi_completion...
Matthias Bussonnier -
r22297:730393a7 merge
parent child Browse files
Show More
@@ -1,1272 +1,1332 b''
1 1 # encoding: utf-8
2 2 """Word completion for IPython.
3 3
4 4 This module is a 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, but we need a lot more
7 7 functionality specific to IPython, so this module will continue to live as an
8 8 IPython-specific utility.
9 9
10 10 Original rlcompleter documentation:
11 11
12 12 This requires the latest extension to the readline module (the
13 13 completes keywords, built-ins and globals in __main__; when completing
14 14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 15 completes its attributes.
16 16
17 17 It's very cool to do "import string" type "string.", hit the
18 18 completion key (twice), and see the list of names defined by the
19 19 string module!
20 20
21 21 Tip: to use the tab key as the completion key, call
22 22
23 23 readline.parse_and_bind("tab: complete")
24 24
25 25 Notes:
26 26
27 27 - Exceptions raised by the completer function are *ignored* (and
28 28 generally cause the completion to fail). This is a feature -- since
29 29 readline sets the tty device in raw (or cbreak) mode, printing a
30 30 traceback wouldn't work well without some complicated hoopla to save,
31 31 reset and restore the tty state.
32 32
33 33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 34 application defined code to be executed if an object with a
35 35 ``__getattr__`` hook is found. Since it is the responsibility of the
36 36 application (or the user) to enable this feature, I consider this an
37 37 acceptable risk. More complicated expressions (e.g. function calls or
38 38 indexing operations) are *not* evaluated.
39 39
40 40 - GNU readline is also used by the built-in functions input() and
41 41 raw_input(), and thus these also benefit/suffer from the completer
42 42 features. Clearly an interactive application can benefit by
43 43 specifying its own completer function and using raw_input() for all
44 44 its input.
45 45
46 46 - When the original stdin is not a tty device, GNU readline is never
47 47 used, and this module (and the readline module) are silently inactive.
48 48 """
49 49
50 50 # Copyright (c) IPython Development Team.
51 51 # Distributed under the terms of the Modified BSD License.
52 52 #
53 53 # Some of this code originated from rlcompleter in the Python standard library
54 54 # Copyright (C) 2001 Python Software Foundation, www.python.org
55 55
56 from __future__ import print_function
57
56 58 import __main__
57 59 import glob
58 60 import inspect
59 61 import itertools
60 62 import keyword
61 63 import os
62 64 import re
63 65 import sys
64 66 import unicodedata
65 67 import string
66 68
67 69 from traitlets.config.configurable import Configurable
68 70 from IPython.core.error import TryNext
69 71 from IPython.core.inputsplitter import ESC_MAGIC
70 72 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
71 73 from IPython.utils import generics
72 74 from IPython.utils.decorators import undoc
73 75 from IPython.utils.dir2 import dir2, get_real_method
74 76 from IPython.utils.process import arg_split
75 77 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
76 78 from traitlets import CBool, Enum
77 79
80 try:
81 import jedi
82 import jedi.api.helpers
83 import jedi.parser.user_context
84 JEDI_INSTALLED = True
85 except ImportError:
86 JEDI_INSTALLED = False
87
78 88 #-----------------------------------------------------------------------------
79 89 # Globals
80 90 #-----------------------------------------------------------------------------
81 91
82 92 # Public API
83 93 __all__ = ['Completer','IPCompleter']
84 94
85 95 if sys.platform == 'win32':
86 96 PROTECTABLES = ' '
87 97 else:
88 98 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
89 99
90 100
91 101 #-----------------------------------------------------------------------------
92 102 # Main functions and classes
93 103 #-----------------------------------------------------------------------------
94 104
95 105 def has_open_quotes(s):
96 106 """Return whether a string has open quotes.
97 107
98 108 This simply counts whether the number of quote characters of either type in
99 109 the string is odd.
100 110
101 111 Returns
102 112 -------
103 113 If there is an open quote, the quote character is returned. Else, return
104 114 False.
105 115 """
106 116 # We check " first, then ', so complex cases with nested quotes will get
107 117 # the " to take precedence.
108 118 if s.count('"') % 2:
109 119 return '"'
110 120 elif s.count("'") % 2:
111 121 return "'"
112 122 else:
113 123 return False
114 124
115 125
116 126 def protect_filename(s):
117 127 """Escape a string to protect certain characters."""
118 128
119 129 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
120 130 for ch in s])
121 131
122 132 def expand_user(path):
123 133 """Expand '~'-style usernames in strings.
124 134
125 135 This is similar to :func:`os.path.expanduser`, but it computes and returns
126 136 extra information that will be useful if the input was being used in
127 137 computing completions, and you wish to return the completions with the
128 138 original '~' instead of its expanded value.
129 139
130 140 Parameters
131 141 ----------
132 142 path : str
133 143 String to be expanded. If no ~ is present, the output is the same as the
134 144 input.
135 145
136 146 Returns
137 147 -------
138 148 newpath : str
139 149 Result of ~ expansion in the input path.
140 150 tilde_expand : bool
141 151 Whether any expansion was performed or not.
142 152 tilde_val : str
143 153 The value that ~ was replaced with.
144 154 """
145 155 # Default values
146 156 tilde_expand = False
147 157 tilde_val = ''
148 158 newpath = path
149 159
150 160 if path.startswith('~'):
151 161 tilde_expand = True
152 162 rest = len(path)-1
153 163 newpath = os.path.expanduser(path)
154 164 if rest:
155 165 tilde_val = newpath[:-rest]
156 166 else:
157 167 tilde_val = newpath
158 168
159 169 return newpath, tilde_expand, tilde_val
160 170
161 171
162 172 def compress_user(path, tilde_expand, tilde_val):
163 173 """Does the opposite of expand_user, with its outputs.
164 174 """
165 175 if tilde_expand:
166 176 return path.replace(tilde_val, '~')
167 177 else:
168 178 return path
169 179
170 180
171 181
172 182 def completions_sorting_key(word):
173 183 """key for sorting completions
174 184
175 185 This does several things:
176 186
177 187 - Lowercase all completions, so they are sorted alphabetically with
178 188 upper and lower case words mingled
179 189 - Demote any completions starting with underscores to the end
180 190 - Insert any %magic and %%cellmagic completions in the alphabetical order
181 191 by their name
182 192 """
183 193 # Case insensitive sort
184 194 word = word.lower()
185 195
186 196 prio1, prio2 = 0, 0
187 197
188 198 if word.startswith('__'):
189 199 prio1 = 2
190 200 elif word.startswith('_'):
191 201 prio1 = 1
192 202
193 203 if word.endswith('='):
194 204 prio1 = -1
195 205
196 206 if word.startswith('%%'):
197 207 # If there's another % in there, this is something else, so leave it alone
198 208 if not "%" in word[2:]:
199 209 word = word[2:]
200 210 prio2 = 2
201 211 elif word.startswith('%'):
202 212 if not "%" in word[1:]:
203 213 word = word[1:]
204 214 prio2 = 1
205 215
206 216 return prio1, word, prio2
207 217
208 218
209 219 @undoc
210 220 class Bunch(object): pass
211 221
212 222
213 223 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
214 224 GREEDY_DELIMS = ' =\r\n'
215 225
216 226
217 227 class CompletionSplitter(object):
218 228 """An object to split an input line in a manner similar to readline.
219 229
220 230 By having our own implementation, we can expose readline-like completion in
221 231 a uniform manner to all frontends. This object only needs to be given the
222 232 line of text to be split and the cursor position on said line, and it
223 233 returns the 'word' to be completed on at the cursor after splitting the
224 234 entire line.
225 235
226 236 What characters are used as splitting delimiters can be controlled by
227 237 setting the `delims` attribute (this is a property that internally
228 238 automatically builds the necessary regular expression)"""
229 239
230 240 # Private interface
231 241
232 242 # A string of delimiter characters. The default value makes sense for
233 243 # IPython's most typical usage patterns.
234 244 _delims = DELIMS
235 245
236 246 # The expression (a normal string) to be compiled into a regular expression
237 247 # for actual splitting. We store it as an attribute mostly for ease of
238 248 # debugging, since this type of code can be so tricky to debug.
239 249 _delim_expr = None
240 250
241 251 # The regular expression that does the actual splitting
242 252 _delim_re = None
243 253
244 254 def __init__(self, delims=None):
245 255 delims = CompletionSplitter._delims if delims is None else delims
246 256 self.delims = delims
247 257
248 258 @property
249 259 def delims(self):
250 260 """Return the string of delimiter characters."""
251 261 return self._delims
252 262
253 263 @delims.setter
254 264 def delims(self, delims):
255 265 """Set the delimiters for line splitting."""
256 266 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
257 267 self._delim_re = re.compile(expr)
258 268 self._delims = delims
259 269 self._delim_expr = expr
260 270
261 271 def split_line(self, line, cursor_pos=None):
262 272 """Split a line of text with a cursor at the given position.
263 273 """
264 274 l = line if cursor_pos is None else line[:cursor_pos]
265 275 return self._delim_re.split(l)[-1]
266 276
267 277
268 278 class Completer(Configurable):
269 279
270 280 greedy = CBool(False, config=True,
271 281 help="""Activate greedy completion
282 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
272 283
273 284 This will enable completion on elements of lists, results of function calls, etc.,
274 285 but can be unsafe because the code is actually evaluated on TAB.
275 286 """
276 287 )
277 288
278 289
279 290 def __init__(self, namespace=None, global_namespace=None, **kwargs):
280 291 """Create a new completer for the command line.
281 292
282 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
293 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
283 294
284 295 If unspecified, the default namespace where completions are performed
285 296 is __main__ (technically, __main__.__dict__). Namespaces should be
286 297 given as dictionaries.
287 298
288 299 An optional second namespace can be given. This allows the completer
289 300 to handle cases where both the local and global scopes need to be
290 301 distinguished.
291 302
292 303 Completer instances should be used as the completion mechanism of
293 304 readline via the set_completer() call:
294 305
295 306 readline.set_completer(Completer(my_namespace).complete)
296 307 """
297 308
298 309 # Don't bind to namespace quite yet, but flag whether the user wants a
299 310 # specific namespace or to use __main__.__dict__. This will allow us
300 311 # to bind to __main__.__dict__ at completion time, not now.
301 312 if namespace is None:
302 313 self.use_main_ns = 1
303 314 else:
304 315 self.use_main_ns = 0
305 316 self.namespace = namespace
306 317
307 318 # The global namespace, if given, can be bound directly
308 319 if global_namespace is None:
309 320 self.global_namespace = {}
310 321 else:
311 322 self.global_namespace = global_namespace
312 323
313 324 super(Completer, self).__init__(**kwargs)
314 325
315 326 def complete(self, text, state):
316 327 """Return the next possible completion for 'text'.
317 328
318 329 This is called successively with state == 0, 1, 2, ... until it
319 330 returns None. The completion should begin with 'text'.
320 331
321 332 """
322 333 if self.use_main_ns:
323 334 self.namespace = __main__.__dict__
324 335
325 336 if state == 0:
326 337 if "." in text:
327 338 self.matches = self.attr_matches(text)
328 339 else:
329 340 self.matches = self.global_matches(text)
330 341 try:
331 342 return self.matches[state]
332 343 except IndexError:
333 344 return None
334 345
335 346 def global_matches(self, text):
336 347 """Compute matches when text is a simple name.
337 348
338 349 Return a list of all keywords, built-in functions and names currently
339 350 defined in self.namespace or self.global_namespace that match.
340 351
341 352 """
342 #print 'Completer->global_matches, txt=%r' % text # dbg
343 353 matches = []
344 354 match_append = matches.append
345 355 n = len(text)
346 356 for lst in [keyword.kwlist,
347 357 builtin_mod.__dict__.keys(),
348 358 self.namespace.keys(),
349 359 self.global_namespace.keys()]:
350 360 for word in lst:
351 361 if word[:n] == text and word != "__builtins__":
352 362 match_append(word)
353 363 return [cast_unicode_py2(m) for m in matches]
354 364
355 365 def attr_matches(self, text):
356 366 """Compute matches when text contains a dot.
357 367
358 368 Assuming the text is of the form NAME.NAME....[NAME], and is
359 369 evaluatable in self.namespace or self.global_namespace, it will be
360 370 evaluated and its attributes (as revealed by dir()) are used as
361 371 possible completions. (For class instances, class members are are
362 372 also considered.)
363 373
364 374 WARNING: this can still invoke arbitrary C code, if an object
365 375 with a __getattr__ hook is evaluated.
366 376
367 377 """
368 378
369 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
370 379 # Another option, seems to work great. Catches things like ''.<tab>
371 380 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
372 381
373 382 if m:
374 383 expr, attr = m.group(1, 3)
375 384 elif self.greedy:
376 385 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
377 386 if not m2:
378 387 return []
379 388 expr, attr = m2.group(1,2)
380 389 else:
381 390 return []
382 391
383 392 try:
384 393 obj = eval(expr, self.namespace)
385 394 except:
386 395 try:
387 396 obj = eval(expr, self.global_namespace)
388 397 except:
389 398 return []
390 399
391 400 if self.limit_to__all__ and hasattr(obj, '__all__'):
392 401 words = get__all__entries(obj)
393 402 else:
394 403 words = dir2(obj)
395 404
396 405 try:
397 406 words = generics.complete_object(obj, words)
398 407 except TryNext:
399 408 pass
400 409 except Exception:
401 410 # Silence errors from completion function
402 411 #raise # dbg
403 412 pass
404 413 # Build match list to return
405 414 n = len(attr)
406 415 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
407 416
408 417
409 418 def get__all__entries(obj):
410 419 """returns the strings in the __all__ attribute"""
411 420 try:
412 421 words = getattr(obj, '__all__')
413 422 except:
414 423 return []
415 424
416 425 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
417 426
418 427
419 428 def match_dict_keys(keys, prefix, delims):
420 429 """Used by dict_key_matches, matching the prefix to a list of keys"""
421 430 if not prefix:
422 431 return None, 0, [repr(k) for k in keys
423 432 if isinstance(k, (string_types, bytes))]
424 433 quote_match = re.search('["\']', prefix)
425 434 quote = quote_match.group()
426 435 try:
427 436 prefix_str = eval(prefix + quote, {})
428 437 except Exception:
429 438 return None, 0, []
430 439
431 440 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
432 441 token_match = re.search(pattern, prefix, re.UNICODE)
433 442 token_start = token_match.start()
434 443 token_prefix = token_match.group()
435 444
436 445 # TODO: support bytes in Py3k
437 446 matched = []
438 447 for key in keys:
439 448 try:
440 449 if not key.startswith(prefix_str):
441 450 continue
442 451 except (AttributeError, TypeError, UnicodeError):
443 452 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
444 453 continue
445 454
446 455 # reformat remainder of key to begin with prefix
447 456 rem = key[len(prefix_str):]
448 457 # force repr wrapped in '
449 458 rem_repr = repr(rem + '"')
450 459 if rem_repr.startswith('u') and prefix[0] not in 'uU':
451 460 # Found key is unicode, but prefix is Py2 string.
452 461 # Therefore attempt to interpret key as string.
453 462 try:
454 463 rem_repr = repr(rem.encode('ascii') + '"')
455 464 except UnicodeEncodeError:
456 465 continue
457 466
458 467 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
459 468 if quote == '"':
460 469 # The entered prefix is quoted with ",
461 470 # but the match is quoted with '.
462 471 # A contained " hence needs escaping for comparison:
463 472 rem_repr = rem_repr.replace('"', '\\"')
464 473
465 474 # then reinsert prefix from start of token
466 475 matched.append('%s%s' % (token_prefix, rem_repr))
467 476 return quote, token_start, matched
468 477
469 478
470 479 def _safe_isinstance(obj, module, class_name):
471 480 """Checks if obj is an instance of module.class_name if loaded
472 481 """
473 482 return (module in sys.modules and
474 483 isinstance(obj, getattr(__import__(module), class_name)))
475 484
476 485
477 486 def back_unicode_name_matches(text):
478 487 u"""Match unicode characters back to unicode name
479 488
480 489 This does β˜ƒ -> \\snowman
481 490
482 491 Note that snowman is not a valid python3 combining character but will be expanded.
483 492 Though it will not recombine back to the snowman character by the completion machinery.
484 493
485 494 This will not either back-complete standard sequences like \\n, \\b ...
486 495
487 496 Used on Python 3 only.
488 497 """
489 498 if len(text)<2:
490 499 return u'', ()
491 500 maybe_slash = text[-2]
492 501 if maybe_slash != '\\':
493 502 return u'', ()
494 503
495 504 char = text[-1]
496 505 # no expand on quote for completion in strings.
497 506 # nor backcomplete standard ascii keys
498 507 if char in string.ascii_letters or char in ['"',"'"]:
499 508 return u'', ()
500 509 try :
501 510 unic = unicodedata.name(char)
502 511 return '\\'+char,['\\'+unic]
503 512 except KeyError as e:
504 513 pass
505 514 return u'', ()
506 515
507 516 def back_latex_name_matches(text):
508 517 u"""Match latex characters back to unicode name
509 518
510 519 This does ->\\sqrt
511 520
512 521 Used on Python 3 only.
513 522 """
514 523 if len(text)<2:
515 524 return u'', ()
516 525 maybe_slash = text[-2]
517 526 if maybe_slash != '\\':
518 527 return u'', ()
519 528
520 529
521 530 char = text[-1]
522 531 # no expand on quote for completion in strings.
523 532 # nor backcomplete standard ascii keys
524 533 if char in string.ascii_letters or char in ['"',"'"]:
525 534 return u'', ()
526 535 try :
527 536 latex = reverse_latex_symbol[char]
528 537 # '\\' replace the \ as well
529 538 return '\\'+char,[latex]
530 539 except KeyError as e:
531 540 pass
532 541 return u'', ()
533 542
534 543
535 544 class IPCompleter(Completer):
536 545 """Extension of the completer class with IPython-specific features"""
537 546
538 547 def _greedy_changed(self, name, old, new):
539 548 """update the splitter and readline delims when greedy is changed"""
540 549 if new:
541 550 self.splitter.delims = GREEDY_DELIMS
542 551 else:
543 552 self.splitter.delims = DELIMS
544 553
545 554 if self.readline:
546 555 self.readline.set_completer_delims(self.splitter.delims)
547 556
548 557 merge_completions = CBool(True, config=True,
549 558 help="""Whether to merge completion results into a single list
550 559
551 560 If False, only the completion results from the first non-empty
552 561 completer will be returned.
553 562 """
554 563 )
555 564 omit__names = Enum((0,1,2), default_value=2, config=True,
556 565 help="""Instruct the completer to omit private method names
557 566
558 567 Specifically, when completing on ``object.<tab>``.
559 568
560 569 When 2 [default]: all names that start with '_' will be excluded.
561 570
562 571 When 1: all 'magic' names (``__foo__``) will be excluded.
563 572
564 573 When 0: nothing will be excluded.
565 574 """
566 575 )
567 576 limit_to__all__ = CBool(default_value=False, config=True,
568 help="""Instruct the completer to use __all__ for the completion
577 help="""
578 DEPRECATED as of version 5.0.
579
580 Instruct the completer to use __all__ for the completion
569 581
570 582 Specifically, when completing on ``object.<tab>``.
571 583
572 584 When True: only those names in obj.__all__ will be included.
573 585
574 586 When False [default]: the __all__ attribute is ignored
575 587 """
576 588 )
589 use_jedi_completions = CBool(default_value=JEDI_INSTALLED, config=True,
590 help="""Use Jedi to generate autocompletions.
591 """)
577 592
578 593 def __init__(self, shell=None, namespace=None, global_namespace=None,
579 594 use_readline=True, config=None, **kwargs):
580 595 """IPCompleter() -> completer
581 596
582 597 Return a completer object suitable for use by the readline library
583 598 via readline.set_completer().
584 599
585 600 Inputs:
586 601
587 602 - shell: a pointer to the ipython shell itself. This is needed
588 603 because this completer knows about magic functions, and those can
589 604 only be accessed via the ipython instance.
590 605
591 606 - namespace: an optional dict where completions are performed.
592 607
593 608 - global_namespace: secondary optional dict for completions, to
594 609 handle cases (such as IPython embedded inside functions) where
595 610 both Python scopes are visible.
596 611
597 612 use_readline : bool, optional
598 613 If true, use the readline library. This completer can still function
599 614 without readline, though in that case callers must provide some extra
600 615 information on each call about the current line."""
601 616
602 617 self.magic_escape = ESC_MAGIC
603 618 self.splitter = CompletionSplitter()
604 619
605 620 # Readline configuration, only used by the rlcompleter method.
606 621 if use_readline:
607 622 # We store the right version of readline so that later code
608 623 import IPython.utils.rlineimpl as readline
609 624 self.readline = readline
610 625 else:
611 626 self.readline = None
612 627
613 628 # _greedy_changed() depends on splitter and readline being defined:
614 629 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
615 630 config=config, **kwargs)
616 631
617 632 # List where completion matches will be stored
618 633 self.matches = []
619 634 self.shell = shell
620 635 # Regexp to split filenames with spaces in them
621 636 self.space_name_re = re.compile(r'([^\\] )')
622 637 # Hold a local ref. to glob.glob for speed
623 638 self.glob = glob.glob
624 639
625 640 # Determine if we are running on 'dumb' terminals, like (X)Emacs
626 641 # buffers, to avoid completion problems.
627 642 term = os.environ.get('TERM','xterm')
628 643 self.dumb_terminal = term in ['dumb','emacs']
629 644
630 645 # Special handling of backslashes needed in win32 platforms
631 646 if sys.platform == "win32":
632 647 self.clean_glob = self._clean_glob_win32
633 648 else:
634 649 self.clean_glob = self._clean_glob
635 650
636 651 #regexp to parse docstring for function signature
637 652 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
638 653 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
639 654 #use this if positional argument name is also needed
640 655 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
641 656
642 657 # All active matcher routines for completion
643 self.matchers = [self.python_matches,
658 self.matchers = [
644 659 self.file_matches,
645 660 self.magic_matches,
646 661 self.python_func_kw_matches,
647 662 self.dict_key_matches,
648 663 ]
649 664
650 665 def all_completions(self, text):
651 666 """
652 667 Wrapper around the complete method for the benefit of emacs
653 668 and pydb.
654 669 """
655 670 return self.complete(text)[1]
656 671
657 def _clean_glob(self,text):
672 def _clean_glob(self, text):
658 673 return self.glob("%s*" % text)
659 674
660 675 def _clean_glob_win32(self,text):
661 676 return [f.replace("\\","/")
662 677 for f in self.glob("%s*" % text)]
663 678
664 679 def file_matches(self, text):
665 680 """Match filenames, expanding ~USER type strings.
666 681
667 682 Most of the seemingly convoluted logic in this completer is an
668 683 attempt to handle filenames with spaces in them. And yet it's not
669 684 quite perfect, because Python's readline doesn't expose all of the
670 685 GNU readline details needed for this to be done correctly.
671 686
672 687 For a filename with a space in it, the printed completions will be
673 688 only the parts after what's already been typed (instead of the
674 689 full completions, as is normally done). I don't think with the
675 690 current (as of Python 2.3) Python readline it's possible to do
676 691 better."""
677 692
678 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
679
680 693 # chars that require escaping with backslash - i.e. chars
681 694 # that readline treats incorrectly as delimiters, but we
682 695 # don't want to treat as delimiters in filename matching
683 696 # when escaped with backslash
684 697 if text.startswith('!'):
685 698 text = text[1:]
686 699 text_prefix = u'!'
687 700 else:
688 701 text_prefix = u''
689 702
690 703 text_until_cursor = self.text_until_cursor
691 704 # track strings with open quotes
692 705 open_quotes = has_open_quotes(text_until_cursor)
693 706
694 707 if '(' in text_until_cursor or '[' in text_until_cursor:
695 708 lsplit = text
696 709 else:
697 710 try:
698 711 # arg_split ~ shlex.split, but with unicode bugs fixed by us
699 712 lsplit = arg_split(text_until_cursor)[-1]
700 713 except ValueError:
701 714 # typically an unmatched ", or backslash without escaped char.
702 715 if open_quotes:
703 716 lsplit = text_until_cursor.split(open_quotes)[-1]
704 717 else:
705 718 return []
706 719 except IndexError:
707 720 # tab pressed on empty line
708 721 lsplit = ""
709 722
710 723 if not open_quotes and lsplit != protect_filename(lsplit):
711 724 # if protectables are found, do matching on the whole escaped name
712 725 has_protectables = True
713 726 text0,text = text,lsplit
714 727 else:
715 728 has_protectables = False
716 729 text = os.path.expanduser(text)
717 730
718 731 if text == "":
719 732 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
720 733
721 734 # Compute the matches from the filesystem
722 735 m0 = self.clean_glob(text.replace('\\',''))
723 736
724 737 if has_protectables:
725 738 # If we had protectables, we need to revert our changes to the
726 739 # beginning of filename so that we don't double-write the part
727 740 # of the filename we have so far
728 741 len_lsplit = len(lsplit)
729 742 matches = [text_prefix + text0 +
730 743 protect_filename(f[len_lsplit:]) for f in m0]
731 744 else:
732 745 if open_quotes:
733 746 # if we have a string with an open quote, we don't need to
734 747 # protect the names at all (and we _shouldn't_, as it
735 748 # would cause bugs when the filesystem call is made).
736 749 matches = m0
737 750 else:
738 751 matches = [text_prefix +
739 752 protect_filename(f) for f in m0]
740 753
741 754 # Mark directories in input list by appending '/' to their names.
742 755 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
743 756
744 757 def magic_matches(self, text):
745 758 """Match magics"""
746 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
747 759 # Get all shell magics now rather than statically, so magics loaded at
748 760 # runtime show up too.
749 761 lsm = self.shell.magics_manager.lsmagic()
750 762 line_magics = lsm['line']
751 763 cell_magics = lsm['cell']
752 764 pre = self.magic_escape
753 765 pre2 = pre+pre
754 766
755 767 # Completion logic:
756 768 # - user gives %%: only do cell magics
757 769 # - user gives %: do both line and cell magics
758 770 # - no prefix: do both
759 771 # In other words, line magics are skipped if the user gives %% explicitly
760 772 bare_text = text.lstrip(pre)
761 773 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
762 774 if not text.startswith(pre2):
763 775 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
764 776 return [cast_unicode_py2(c) for c in comp]
765 777
778 def python_jedi_matches(self, text, line_buffer, cursor_pos):
779 """Match attributes or global Python names using Jedi."""
780 if line_buffer.startswith('aimport ') or line_buffer.startswith('%aimport '):
781 return ()
782 namespaces = []
783 if self.namespace is None:
784 import __main__
785 namespaces.append(__main__.__dict__)
786 else:
787 namespaces.append(self.namespace)
788 if self.global_namespace is not None:
789 namespaces.append(self.global_namespace)
790
791 # cursor_pos is an it, jedi wants line and column
792
793 interpreter = jedi.Interpreter(line_buffer, namespaces, column=cursor_pos)
794 path = jedi.parser.user_context.UserContext(line_buffer, \
795 (1, len(line_buffer))).get_path_until_cursor()
796 path, dot, like = jedi.api.helpers.completion_parts(path)
797 if text.startswith('.'):
798 # text will be `.` on completions like `a[0].<tab>`
799 before = dot
800 else:
801 before = line_buffer[:len(line_buffer) - len(like)]
802
803
804 def trim_start(completion):
805 """completions need to start with `text`, trim the beginning until it does"""
806 if text in completion and not (completion.startswith(text)):
807 start_index = completion.index(text)
808 if cursor_pos:
809 assert start_index < cursor_pos
810 return completion[start_index:]
811 return completion
812
813 completions = interpreter.completions()
814
815 completion_text = [c.name_with_symbols for c in completions]
816
817 if self.omit__names:
818 if self.omit__names == 1:
819 # true if txt is _not_ a __ name, false otherwise:
820 no__name = lambda txt: not txt.startswith('__')
821 else:
822 # true if txt is _not_ a _ name, false otherwise:
823 no__name = lambda txt: not txt.startswith('_')
824 completion_text = filter(no__name, completion_text)
825
826
827 return [trim_start(before + c_text) for c_text in completion_text]
828
829
766 830 def python_matches(self, text):
767 831 """Match attributes or global python names"""
768
769 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
832 # Jedi completion
833
770 834 if "." in text:
771 835 try:
772 836 matches = self.attr_matches(text)
773 837 if text.endswith('.') and self.omit__names:
774 838 if self.omit__names == 1:
775 839 # true if txt is _not_ a __ name, false otherwise:
776 840 no__name = (lambda txt:
777 841 re.match(r'.*\.__.*?__',txt) is None)
778 842 else:
779 843 # true if txt is _not_ a _ name, false otherwise:
780 844 no__name = (lambda txt:
781 845 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
782 846 matches = filter(no__name, matches)
783 847 except NameError:
784 848 # catches <undefined attributes>.<tab>
785 849 matches = []
786 850 else:
787 851 matches = self.global_matches(text)
788 852 return matches
789 853
790 854 def _default_arguments_from_docstring(self, doc):
791 855 """Parse the first line of docstring for call signature.
792 856
793 857 Docstring should be of the form 'min(iterable[, key=func])\n'.
794 858 It can also parse cython docstring of the form
795 859 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
796 860 """
797 861 if doc is None:
798 862 return []
799 863
800 864 #care only the firstline
801 865 line = doc.lstrip().splitlines()[0]
802 866
803 867 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
804 868 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
805 869 sig = self.docstring_sig_re.search(line)
806 870 if sig is None:
807 871 return []
808 872 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
809 873 sig = sig.groups()[0].split(',')
810 874 ret = []
811 875 for s in sig:
812 876 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
813 877 ret += self.docstring_kwd_re.findall(s)
814 878 return ret
815 879
816 880 def _default_arguments(self, obj):
817 881 """Return the list of default arguments of obj if it is callable,
818 882 or empty list otherwise."""
819 883 call_obj = obj
820 884 ret = []
821 885 if inspect.isbuiltin(obj):
822 886 pass
823 887 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
824 888 if inspect.isclass(obj):
825 889 #for cython embededsignature=True the constructor docstring
826 890 #belongs to the object itself not __init__
827 891 ret += self._default_arguments_from_docstring(
828 892 getattr(obj, '__doc__', ''))
829 893 # for classes, check for __init__,__new__
830 894 call_obj = (getattr(obj, '__init__', None) or
831 895 getattr(obj, '__new__', None))
832 896 # for all others, check if they are __call__able
833 897 elif hasattr(obj, '__call__'):
834 898 call_obj = obj.__call__
835 899 ret += self._default_arguments_from_docstring(
836 900 getattr(call_obj, '__doc__', ''))
837 901
838 902 if PY3:
839 903 _keeps = (inspect.Parameter.KEYWORD_ONLY,
840 904 inspect.Parameter.POSITIONAL_OR_KEYWORD)
841 905 signature = inspect.signature
842 906 else:
843 907 import IPython.utils.signatures
844 908 _keeps = (IPython.utils.signatures.Parameter.KEYWORD_ONLY,
845 909 IPython.utils.signatures.Parameter.POSITIONAL_OR_KEYWORD)
846 910 signature = IPython.utils.signatures.signature
847 911
848 912 try:
849 913 sig = signature(call_obj)
850 914 ret.extend(k for k, v in sig.parameters.items() if
851 915 v.kind in _keeps)
852 916 except ValueError:
853 917 pass
854 918
855 919 return list(set(ret))
856 920
857 921 def python_func_kw_matches(self,text):
858 922 """Match named parameters (kwargs) of the last open function"""
859 923
860 924 if "." in text: # a parameter cannot be dotted
861 925 return []
862 926 try: regexp = self.__funcParamsRegex
863 927 except AttributeError:
864 928 regexp = self.__funcParamsRegex = re.compile(r'''
865 929 '.*?(?<!\\)' | # single quoted strings or
866 930 ".*?(?<!\\)" | # double quoted strings or
867 931 \w+ | # identifier
868 932 \S # other characters
869 933 ''', re.VERBOSE | re.DOTALL)
870 934 # 1. find the nearest identifier that comes before an unclosed
871 935 # parenthesis before the cursor
872 936 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
873 937 tokens = regexp.findall(self.text_until_cursor)
874 938 tokens.reverse()
875 939 iterTokens = iter(tokens); openPar = 0
876 940
877 941 for token in iterTokens:
878 942 if token == ')':
879 943 openPar -= 1
880 944 elif token == '(':
881 945 openPar += 1
882 946 if openPar > 0:
883 947 # found the last unclosed parenthesis
884 948 break
885 949 else:
886 950 return []
887 951 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
888 952 ids = []
889 953 isId = re.compile(r'\w+$').match
890 954
891 955 while True:
892 956 try:
893 957 ids.append(next(iterTokens))
894 958 if not isId(ids[-1]):
895 959 ids.pop(); break
896 960 if not next(iterTokens) == '.':
897 961 break
898 962 except StopIteration:
899 963 break
900 964 # lookup the candidate callable matches either using global_matches
901 965 # or attr_matches for dotted names
902 966 if len(ids) == 1:
903 967 callableMatches = self.global_matches(ids[0])
904 968 else:
905 969 callableMatches = self.attr_matches('.'.join(ids[::-1]))
906 970 argMatches = []
907 971 for callableMatch in callableMatches:
908 972 try:
909 973 namedArgs = self._default_arguments(eval(callableMatch,
910 974 self.namespace))
911 975 except:
912 976 continue
913 977
914 978 for namedArg in namedArgs:
915 979 if namedArg.startswith(text):
916 980 argMatches.append(u"%s=" %namedArg)
917 981 return argMatches
918 982
919 983 def dict_key_matches(self, text):
920 984 "Match string keys in a dictionary, after e.g. 'foo[' "
921 985 def get_keys(obj):
922 986 # Objects can define their own completions by defining an
923 987 # _ipy_key_completions_() method.
924 988 method = get_real_method(obj, '_ipython_key_completions_')
925 989 if method is not None:
926 990 return method()
927 991
928 992 # Special case some common in-memory dict-like types
929 993 if isinstance(obj, dict) or\
930 994 _safe_isinstance(obj, 'pandas', 'DataFrame'):
931 995 try:
932 996 return list(obj.keys())
933 997 except Exception:
934 998 return []
935 999 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
936 1000 _safe_isinstance(obj, 'numpy', 'void'):
937 1001 return obj.dtype.names or []
938 1002 return []
939 1003
940 1004 try:
941 1005 regexps = self.__dict_key_regexps
942 1006 except AttributeError:
943 1007 dict_key_re_fmt = r'''(?x)
944 1008 ( # match dict-referring expression wrt greedy setting
945 1009 %s
946 1010 )
947 1011 \[ # open bracket
948 1012 \s* # and optional whitespace
949 1013 ([uUbB]? # string prefix (r not handled)
950 1014 (?: # unclosed string
951 1015 '(?:[^']|(?<!\\)\\')*
952 1016 |
953 1017 "(?:[^"]|(?<!\\)\\")*
954 1018 )
955 1019 )?
956 1020 $
957 1021 '''
958 1022 regexps = self.__dict_key_regexps = {
959 1023 False: re.compile(dict_key_re_fmt % '''
960 1024 # identifiers separated by .
961 1025 (?!\d)\w+
962 1026 (?:\.(?!\d)\w+)*
963 1027 '''),
964 1028 True: re.compile(dict_key_re_fmt % '''
965 1029 .+
966 1030 ''')
967 1031 }
968 1032
969 1033 match = regexps[self.greedy].search(self.text_until_cursor)
970 1034 if match is None:
971 1035 return []
972 1036
973 1037 expr, prefix = match.groups()
974 1038 try:
975 1039 obj = eval(expr, self.namespace)
976 1040 except Exception:
977 1041 try:
978 1042 obj = eval(expr, self.global_namespace)
979 1043 except Exception:
980 1044 return []
981 1045
982 1046 keys = get_keys(obj)
983 1047 if not keys:
984 1048 return keys
985 1049 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
986 1050 if not matches:
987 1051 return matches
988 1052
989 1053 # get the cursor position of
990 1054 # - the text being completed
991 1055 # - the start of the key text
992 1056 # - the start of the completion
993 1057 text_start = len(self.text_until_cursor) - len(text)
994 1058 if prefix:
995 1059 key_start = match.start(2)
996 1060 completion_start = key_start + token_offset
997 1061 else:
998 1062 key_start = completion_start = match.end()
999 1063
1000 1064 # grab the leading prefix, to make sure all completions start with `text`
1001 1065 if text_start > key_start:
1002 1066 leading = ''
1003 1067 else:
1004 1068 leading = text[text_start:completion_start]
1005 1069
1006 1070 # the index of the `[` character
1007 1071 bracket_idx = match.end(1)
1008 1072
1009 1073 # append closing quote and bracket as appropriate
1010 1074 # this is *not* appropriate if the opening quote or bracket is outside
1011 1075 # the text given to this method
1012 1076 suf = ''
1013 1077 continuation = self.line_buffer[len(self.text_until_cursor):]
1014 1078 if key_start > text_start and closing_quote:
1015 1079 # quotes were opened inside text, maybe close them
1016 1080 if continuation.startswith(closing_quote):
1017 1081 continuation = continuation[len(closing_quote):]
1018 1082 else:
1019 1083 suf += closing_quote
1020 1084 if bracket_idx > text_start:
1021 1085 # brackets were opened inside text, maybe close them
1022 1086 if not continuation.startswith(']'):
1023 1087 suf += ']'
1024 1088
1025 1089 return [leading + k + suf for k in matches]
1026 1090
1027 1091 def unicode_name_matches(self, text):
1028 1092 u"""Match Latex-like syntax for unicode characters base
1029 1093 on the name of the character.
1030 1094
1031 1095 This does \\GREEK SMALL LETTER ETA -> Ξ·
1032 1096
1033 1097 Works only on valid python 3 identifier, or on combining characters that
1034 1098 will combine to form a valid identifier.
1035 1099
1036 1100 Used on Python 3 only.
1037 1101 """
1038 1102 slashpos = text.rfind('\\')
1039 1103 if slashpos > -1:
1040 1104 s = text[slashpos+1:]
1041 1105 try :
1042 1106 unic = unicodedata.lookup(s)
1043 1107 # allow combining chars
1044 1108 if ('a'+unic).isidentifier():
1045 1109 return '\\'+s,[unic]
1046 1110 except KeyError as e:
1047 1111 pass
1048 1112 return u'', []
1049 1113
1050 1114
1051 1115
1052 1116
1053 1117 def latex_matches(self, text):
1054 1118 u"""Match Latex syntax for unicode characters.
1055 1119
1056 1120 This does both \\alp -> \\alpha and \\alpha -> Ξ±
1057 1121
1058 1122 Used on Python 3 only.
1059 1123 """
1060 1124 slashpos = text.rfind('\\')
1061 1125 if slashpos > -1:
1062 1126 s = text[slashpos:]
1063 1127 if s in latex_symbols:
1064 1128 # Try to complete a full latex symbol to unicode
1065 1129 # \\alpha -> Ξ±
1066 1130 return s, [latex_symbols[s]]
1067 1131 else:
1068 1132 # If a user has partially typed a latex symbol, give them
1069 1133 # a full list of options \al -> [\aleph, \alpha]
1070 1134 matches = [k for k in latex_symbols if k.startswith(s)]
1071 1135 return s, matches
1072 1136 return u'', []
1073 1137
1074 1138 def dispatch_custom_completer(self, text):
1075 1139 line = self.line_buffer
1076 1140 if not line.strip():
1077 1141 return None
1078 1142
1079 1143 # Create a little structure to pass all the relevant information about
1080 1144 # the current completion to any custom completer.
1081 1145 event = Bunch()
1082 1146 event.line = line
1083 1147 event.symbol = text
1084 1148 cmd = line.split(None,1)[0]
1085 1149 event.command = cmd
1086 1150 event.text_until_cursor = self.text_until_cursor
1087 1151
1088 #print "\ncustom:{%s]\n" % event # dbg
1089
1090 1152 # for foo etc, try also to find completer for %foo
1091 1153 if not cmd.startswith(self.magic_escape):
1092 1154 try_magic = self.custom_completers.s_matches(
1093 1155 self.magic_escape + cmd)
1094 1156 else:
1095 1157 try_magic = []
1096 1158
1097 1159 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1098 1160 try_magic,
1099 1161 self.custom_completers.flat_matches(self.text_until_cursor)):
1100 1162 try:
1101 1163 res = c(event)
1102 1164 if res:
1103 1165 # first, try case sensitive match
1104 1166 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1105 1167 if withcase:
1106 1168 return withcase
1107 1169 # if none, then case insensitive ones are ok too
1108 1170 text_low = text.lower()
1109 1171 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1110 1172 except TryNext:
1111 1173 pass
1112 1174
1113 1175 return None
1114 1176
1115 1177 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1116 1178 """Find completions for the given text and line context.
1117 1179
1118 1180 Note that both the text and the line_buffer are optional, but at least
1119 1181 one of them must be given.
1120 1182
1121 1183 Parameters
1122 1184 ----------
1123 1185 text : string, optional
1124 1186 Text to perform the completion on. If not given, the line buffer
1125 1187 is split using the instance's CompletionSplitter object.
1126 1188
1127 1189 line_buffer : string, optional
1128 1190 If not given, the completer attempts to obtain the current line
1129 1191 buffer via readline. This keyword allows clients which are
1130 1192 requesting for text completions in non-readline contexts to inform
1131 1193 the completer of the entire text.
1132 1194
1133 1195 cursor_pos : int, optional
1134 1196 Index of the cursor in the full line buffer. Should be provided by
1135 1197 remote frontends where kernel has no access to frontend state.
1136 1198
1137 1199 Returns
1138 1200 -------
1139 1201 text : str
1140 1202 Text that was actually used in the completion.
1141 1203
1142 1204 matches : list
1143 1205 A list of completion matches.
1144 1206 """
1145 # io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1146
1147 1207 # if the cursor position isn't given, the only sane assumption we can
1148 1208 # make is that it's at the end of the line (the common case)
1149 1209 if cursor_pos is None:
1150 1210 cursor_pos = len(line_buffer) if text is None else len(text)
1151 1211
1152 1212 if PY3:
1153 1213
1154 1214 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1155 1215 latex_text, latex_matches = self.latex_matches(base_text)
1156 1216 if latex_matches:
1157 1217 return latex_text, latex_matches
1158 1218 name_text = ''
1159 1219 name_matches = []
1160 1220 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1161 1221 name_text, name_matches = meth(base_text)
1162 1222 if name_text:
1163 1223 return name_text, name_matches
1164 1224
1165 1225 # if text is either None or an empty string, rely on the line buffer
1166 1226 if not text:
1167 1227 text = self.splitter.split_line(line_buffer, cursor_pos)
1168 1228
1169 1229 # If no line buffer is given, assume the input text is all there was
1170 1230 if line_buffer is None:
1171 1231 line_buffer = text
1172 1232
1173 1233 self.line_buffer = line_buffer
1174 1234 self.text_until_cursor = self.line_buffer[:cursor_pos]
1175 # io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1176 1235
1177 1236 # Start with a clean slate of completions
1178 1237 self.matches[:] = []
1179 1238 custom_res = self.dispatch_custom_completer(text)
1180 1239 if custom_res is not None:
1181 1240 # did custom completers produce something?
1182 1241 self.matches = custom_res
1183 1242 else:
1184 1243 # Extend the list of completions with the results of each
1185 1244 # matcher, so we return results to the user from all
1186 1245 # namespaces.
1187 1246 if self.merge_completions:
1188 1247 self.matches = []
1189 1248 for matcher in self.matchers:
1190 1249 try:
1191 1250 self.matches.extend(matcher(text))
1192 1251 except:
1193 1252 # Show the ugly traceback if the matcher causes an
1194 1253 # exception, but do NOT crash the kernel!
1195 1254 sys.excepthook(*sys.exc_info())
1196 1255 else:
1197 1256 for matcher in self.matchers:
1198 1257 self.matches = matcher(text)
1199 1258 if self.matches:
1200 1259 break
1201 1260 # FIXME: we should extend our api to return a dict with completions for
1202 1261 # different types of objects. The rlcomplete() method could then
1203 1262 # simply collapse the dict into a list for readline, but we'd have
1204 1263 # richer completion semantics in other evironments.
1264 if self.use_jedi_completions:
1265 self.matches.extend(self.python_jedi_matches(text, line_buffer, cursor_pos))
1205 1266
1206 1267 self.matches = sorted(set(self.matches), key=completions_sorting_key)
1207 1268
1208 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
1209 1269 return text, self.matches
1210 1270
1211 1271 def rlcomplete(self, text, state):
1212 1272 """Return the state-th possible completion for 'text'.
1213 1273
1214 1274 This is called successively with state == 0, 1, 2, ... until it
1215 1275 returns None. The completion should begin with 'text'.
1216 1276
1217 1277 Parameters
1218 1278 ----------
1219 1279 text : string
1220 1280 Text to perform the completion on.
1221 1281
1222 1282 state : int
1223 1283 Counter used by readline.
1224 1284 """
1225 1285 if state==0:
1226 1286
1227 1287 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1228 1288 cursor_pos = self.readline.get_endidx()
1229 1289
1230 1290 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1231 1291 # (text, line_buffer, cursor_pos) ) # dbg
1232 1292
1233 1293 # if there is only a tab on a line with only whitespace, instead of
1234 1294 # the mostly useless 'do you want to see all million completions'
1235 1295 # message, just do the right thing and give the user his tab!
1236 1296 # Incidentally, this enables pasting of tabbed text from an editor
1237 1297 # (as long as autoindent is off).
1238 1298
1239 1299 # It should be noted that at least pyreadline still shows file
1240 1300 # completions - is there a way around it?
1241 1301
1242 1302 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1243 1303 # we don't interfere with their own tab-completion mechanism.
1244 1304 if not (self.dumb_terminal or line_buffer.strip()):
1245 1305 self.readline.insert_text('\t')
1246 1306 sys.stdout.flush()
1247 1307 return None
1248 1308
1249 1309 # Note: debugging exceptions that may occur in completion is very
1250 1310 # tricky, because readline unconditionally silences them. So if
1251 1311 # during development you suspect a bug in the completion code, turn
1252 1312 # this flag on temporarily by uncommenting the second form (don't
1253 1313 # flip the value in the first line, as the '# dbg' marker can be
1254 1314 # automatically detected and is used elsewhere).
1255 1315 DEBUG = False
1256 1316 #DEBUG = True # dbg
1257 1317 if DEBUG:
1258 1318 try:
1259 1319 self.complete(text, line_buffer, cursor_pos)
1260 1320 except:
1261 1321 import traceback; traceback.print_exc()
1262 1322 else:
1263 1323 # The normal production version is here
1264 1324
1265 1325 # This method computes the self.matches array
1266 1326 self.complete(text, line_buffer, cursor_pos)
1267 1327
1268 1328 try:
1269 1329 return self.matches[state]
1270 1330 except IndexError:
1271 1331 return None
1272 1332
@@ -1,803 +1,805 b''
1 1 # encoding: utf-8
2 2 """Tests for the IPython tab-completion machinery."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import os
8 8 import sys
9 9 import unittest
10 10
11 11 from contextlib import contextmanager
12 12
13 13 import nose.tools as nt
14 14
15 15 from traitlets.config.loader import Config
16 16 from IPython import get_ipython
17 17 from IPython.core import completer
18 18 from IPython.external.decorators import knownfailureif
19 19 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
20 20 from IPython.utils.generics import complete_object
21 21 from IPython.utils.py3compat import string_types, unicode_type
22 22 from IPython.testing import decorators as dec
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Test functions
26 26 #-----------------------------------------------------------------------------
27 27
28 28 @contextmanager
29 29 def greedy_completion():
30 30 ip = get_ipython()
31 31 greedy_original = ip.Completer.greedy
32 32 try:
33 33 ip.Completer.greedy = True
34 34 yield
35 35 finally:
36 36 ip.Completer.greedy = greedy_original
37 37
38 38 def test_protect_filename():
39 39 pairs = [ ('abc','abc'),
40 40 (' abc',r'\ abc'),
41 41 ('a bc',r'a\ bc'),
42 42 ('a bc',r'a\ \ bc'),
43 43 (' bc',r'\ \ bc'),
44 44 ]
45 45 # On posix, we also protect parens and other special characters
46 46 if sys.platform != 'win32':
47 47 pairs.extend( [('a(bc',r'a\(bc'),
48 48 ('a)bc',r'a\)bc'),
49 49 ('a( )bc',r'a\(\ \)bc'),
50 50 ('a[1]bc', r'a\[1\]bc'),
51 51 ('a{1}bc', r'a\{1\}bc'),
52 52 ('a#bc', r'a\#bc'),
53 53 ('a?bc', r'a\?bc'),
54 54 ('a=bc', r'a\=bc'),
55 55 ('a\\bc', r'a\\bc'),
56 56 ('a|bc', r'a\|bc'),
57 57 ('a;bc', r'a\;bc'),
58 58 ('a:bc', r'a\:bc'),
59 59 ("a'bc", r"a\'bc"),
60 60 ('a*bc', r'a\*bc'),
61 61 ('a"bc', r'a\"bc'),
62 62 ('a^bc', r'a\^bc'),
63 63 ('a&bc', r'a\&bc'),
64 64 ] )
65 65 # run the actual tests
66 66 for s1, s2 in pairs:
67 67 s1p = completer.protect_filename(s1)
68 68 nt.assert_equal(s1p, s2)
69 69
70 70
71 71 def check_line_split(splitter, test_specs):
72 72 for part1, part2, split in test_specs:
73 73 cursor_pos = len(part1)
74 74 line = part1+part2
75 75 out = splitter.split_line(line, cursor_pos)
76 76 nt.assert_equal(out, split)
77 77
78 78
79 79 def test_line_split():
80 80 """Basic line splitter test with default specs."""
81 81 sp = completer.CompletionSplitter()
82 82 # The format of the test specs is: part1, part2, expected answer. Parts 1
83 83 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
84 84 # was at the end of part1. So an empty part2 represents someone hitting
85 85 # tab at the end of the line, the most common case.
86 86 t = [('run some/scrip', '', 'some/scrip'),
87 87 ('run scripts/er', 'ror.py foo', 'scripts/er'),
88 88 ('echo $HOM', '', 'HOM'),
89 89 ('print sys.pa', '', 'sys.pa'),
90 90 ('print(sys.pa', '', 'sys.pa'),
91 91 ("execfile('scripts/er", '', 'scripts/er'),
92 92 ('a[x.', '', 'x.'),
93 93 ('a[x.', 'y', 'x.'),
94 94 ('cd "some_file/', '', 'some_file/'),
95 95 ]
96 96 check_line_split(sp, t)
97 97 # Ensure splitting works OK with unicode by re-running the tests with
98 98 # all inputs turned into unicode
99 99 check_line_split(sp, [ map(unicode_type, p) for p in t] )
100 100
101 101
102 102 def test_custom_completion_error():
103 103 """Test that errors from custom attribute completers are silenced."""
104 104 ip = get_ipython()
105 105 class A(object): pass
106 106 ip.user_ns['a'] = A()
107 107
108 108 @complete_object.when_type(A)
109 109 def complete_A(a, existing_completions):
110 110 raise TypeError("this should be silenced")
111 111
112 112 ip.complete("a.")
113 113
114 114
115 115 def test_unicode_completions():
116 116 ip = get_ipython()
117 117 # Some strings that trigger different types of completion. Check them both
118 118 # in str and unicode forms
119 119 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
120 120 for t in s + list(map(unicode_type, s)):
121 121 # We don't need to check exact completion values (they may change
122 122 # depending on the state of the namespace, but at least no exceptions
123 123 # should be thrown and the return value should be a pair of text, list
124 124 # values.
125 125 text, matches = ip.complete(t)
126 126 nt.assert_true(isinstance(text, string_types))
127 127 nt.assert_true(isinstance(matches, list))
128 128
129 129 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
130 130 def test_latex_completions():
131 131 from IPython.core.latex_symbols import latex_symbols
132 132 import random
133 133 ip = get_ipython()
134 134 # Test some random unicode symbols
135 135 keys = random.sample(latex_symbols.keys(), 10)
136 136 for k in keys:
137 137 text, matches = ip.complete(k)
138 138 nt.assert_equal(len(matches),1)
139 139 nt.assert_equal(text, k)
140 140 nt.assert_equal(matches[0], latex_symbols[k])
141 141 # Test a more complex line
142 142 text, matches = ip.complete(u'print(\\alpha')
143 143 nt.assert_equals(text, u'\\alpha')
144 144 nt.assert_equals(matches[0], latex_symbols['\\alpha'])
145 145 # Test multiple matching latex symbols
146 146 text, matches = ip.complete(u'\\al')
147 147 nt.assert_in('\\alpha', matches)
148 148 nt.assert_in('\\aleph', matches)
149 149
150 150
151 151
152 152
153 153 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
154 154 def test_back_latex_completion():
155 155 ip = get_ipython()
156 156
157 157 # do not return more than 1 matches fro \beta, only the latex one.
158 158 name, matches = ip.complete('\\Ξ²')
159 159 nt.assert_equal(len(matches), 1)
160 160 nt.assert_equal(matches[0], '\\beta')
161 161
162 162 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
163 163 def test_back_unicode_completion():
164 164 ip = get_ipython()
165 165
166 166 name, matches = ip.complete('\\β…€')
167 167 nt.assert_equal(len(matches), 1)
168 168 nt.assert_equal(matches[0], '\\ROMAN NUMERAL FIVE')
169 169
170 170
171 171 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
172 172 def test_forward_unicode_completion():
173 173 ip = get_ipython()
174 174
175 175 name, matches = ip.complete('\\ROMAN NUMERAL FIVE')
176 176 nt.assert_equal(len(matches), 1)
177 177 nt.assert_equal(matches[0], 'β…€')
178 178
179 179 @dec.onlyif(sys.version_info[0] >= 3, 'This test only apply on python3')
180 180 def test_no_ascii_back_completion():
181 181 ip = get_ipython()
182 182 with TemporaryWorkingDirectory(): # Avoid any filename completions
183 183 # single ascii letter that don't have yet completions
184 for letter in 'fjqyJMQVWY' :
184 for letter in 'jJ' :
185 185 name, matches = ip.complete('\\'+letter)
186 186 nt.assert_equal(matches, [])
187 187
188 188
189 189
190 190
191 191 class CompletionSplitterTestCase(unittest.TestCase):
192 192 def setUp(self):
193 193 self.sp = completer.CompletionSplitter()
194 194
195 195 def test_delim_setting(self):
196 196 self.sp.delims = ' '
197 197 nt.assert_equal(self.sp.delims, ' ')
198 198 nt.assert_equal(self.sp._delim_expr, '[\ ]')
199 199
200 200 def test_spaces(self):
201 201 """Test with only spaces as split chars."""
202 202 self.sp.delims = ' '
203 203 t = [('foo', '', 'foo'),
204 204 ('run foo', '', 'foo'),
205 205 ('run foo', 'bar', 'foo'),
206 206 ]
207 207 check_line_split(self.sp, t)
208 208
209 209
210 210 def test_has_open_quotes1():
211 211 for s in ["'", "'''", "'hi' '"]:
212 212 nt.assert_equal(completer.has_open_quotes(s), "'")
213 213
214 214
215 215 def test_has_open_quotes2():
216 216 for s in ['"', '"""', '"hi" "']:
217 217 nt.assert_equal(completer.has_open_quotes(s), '"')
218 218
219 219
220 220 def test_has_open_quotes3():
221 221 for s in ["''", "''' '''", "'hi' 'ipython'"]:
222 222 nt.assert_false(completer.has_open_quotes(s))
223 223
224 224
225 225 def test_has_open_quotes4():
226 226 for s in ['""', '""" """', '"hi" "ipython"']:
227 227 nt.assert_false(completer.has_open_quotes(s))
228 228
229 229
230 230 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
231 231 def test_abspath_file_completions():
232 232 ip = get_ipython()
233 233 with TemporaryDirectory() as tmpdir:
234 234 prefix = os.path.join(tmpdir, 'foo')
235 235 suffixes = ['1', '2']
236 236 names = [prefix+s for s in suffixes]
237 237 for n in names:
238 238 open(n, 'w').close()
239 239
240 240 # Check simple completion
241 241 c = ip.complete(prefix)[1]
242 242 nt.assert_equal(c, names)
243 243
244 244 # Now check with a function call
245 245 cmd = 'a = f("%s' % prefix
246 246 c = ip.complete(prefix, cmd)[1]
247 247 comp = [prefix+s for s in suffixes]
248 248 nt.assert_equal(c, comp)
249 249
250 250
251 251 def test_local_file_completions():
252 252 ip = get_ipython()
253 253 with TemporaryWorkingDirectory():
254 254 prefix = './foo'
255 255 suffixes = ['1', '2']
256 256 names = [prefix+s for s in suffixes]
257 257 for n in names:
258 258 open(n, 'w').close()
259 259
260 260 # Check simple completion
261 261 c = ip.complete(prefix)[1]
262 262 nt.assert_equal(c, names)
263 263
264 264 # Now check with a function call
265 265 cmd = 'a = f("%s' % prefix
266 266 c = ip.complete(prefix, cmd)[1]
267 comp = [prefix+s for s in suffixes]
268 nt.assert_equal(c, comp)
267 comp = set(prefix+s for s in suffixes)
268 nt.assert_true(comp.issubset(set(c)))
269 269
270 270
271 271 def test_greedy_completions():
272 272 ip = get_ipython()
273 273 ip.ex('a=list(range(5))')
274 274 _,c = ip.complete('.',line='a[0].')
275 nt.assert_false('a[0].real' in c,
275 nt.assert_false('.real' in c,
276 276 "Shouldn't have completed on a[0]: %s"%c)
277 277 with greedy_completion():
278 _,c = ip.complete('.',line='a[0].')
279 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
278 def _(line, cursor_pos, expect, message):
279 _,c = ip.complete('.', line=line, cursor_pos=cursor_pos)
280 nt.assert_in(expect, c, message%c)
281
282 yield _, 'a[0].', 5, '.real', "Should have completed on a[0].: %s"
283 yield _, 'a[0].r', 6, '.real', "Should have completed on a[0].r: %s"
284
285 if sys.version_info > (3,4):
286 yield _, 'a[0].from_', 10, '.from_bytes', "Should have completed on a[0].from_: %s"
287
288
289 def _2():
290 # jedi bug, this will be empty, makeitfail for now,
291 # once jedi is fixed, switch to assert_in
292 # https://github.com/davidhalter/jedi/issues/718
293 _,c = ip.complete('.',line='a[0].from', cursor_pos=9)
294 nt.assert_not_in('.from_bytes', c, "Should not have completed on a[0].from (jedi bug), if fails, update test to assert_in: %s"%c)
295 yield _2
296
280 297
281 298
282 299 def test_omit__names():
283 300 # also happens to test IPCompleter as a configurable
284 301 ip = get_ipython()
285 302 ip._hidden_attr = 1
286 303 ip._x = {}
287 304 c = ip.Completer
288 305 ip.ex('ip=get_ipython()')
289 306 cfg = Config()
290 307 cfg.IPCompleter.omit__names = 0
291 308 c.update_config(cfg)
292 309 s,matches = c.complete('ip.')
293 310 nt.assert_in('ip.__str__', matches)
294 311 nt.assert_in('ip._hidden_attr', matches)
295 312 cfg = Config()
296 313 cfg.IPCompleter.omit__names = 1
297 314 c.update_config(cfg)
298 315 s,matches = c.complete('ip.')
299 316 nt.assert_not_in('ip.__str__', matches)
300 317 nt.assert_in('ip._hidden_attr', matches)
301 318 cfg = Config()
302 319 cfg.IPCompleter.omit__names = 2
303 320 c.update_config(cfg)
304 321 s,matches = c.complete('ip.')
305 322 nt.assert_not_in('ip.__str__', matches)
306 323 nt.assert_not_in('ip._hidden_attr', matches)
307 324 s,matches = c.complete('ip._x.')
308 325 nt.assert_in('ip._x.keys', matches)
309 326 del ip._hidden_attr
310 327
311 328
312 329 def test_limit_to__all__False_ok():
313 330 ip = get_ipython()
314 331 c = ip.Completer
315 332 ip.ex('class D: x=24')
316 333 ip.ex('d=D()')
317 334 cfg = Config()
318 335 cfg.IPCompleter.limit_to__all__ = False
319 336 c.update_config(cfg)
320 337 s, matches = c.complete('d.')
321 338 nt.assert_in('d.x', matches)
322 339
323 340
324 def test_limit_to__all__True_ok():
325 ip = get_ipython()
326 c = ip.Completer
327 ip.ex('class D: x=24')
328 ip.ex('d=D()')
329 ip.ex("d.__all__=['z']")
330 cfg = Config()
331 cfg.IPCompleter.limit_to__all__ = True
332 c.update_config(cfg)
333 s, matches = c.complete('d.')
334 nt.assert_in('d.z', matches)
335 nt.assert_not_in('d.x', matches)
336
337
338 341 def test_get__all__entries_ok():
339 342 class A(object):
340 343 __all__ = ['x', 1]
341 344 words = completer.get__all__entries(A())
342 345 nt.assert_equal(words, ['x'])
343 346
344 347
345 348 def test_get__all__entries_no__all__ok():
346 349 class A(object):
347 350 pass
348 351 words = completer.get__all__entries(A())
349 352 nt.assert_equal(words, [])
350 353
351 354
352 355 def test_func_kw_completions():
353 356 ip = get_ipython()
354 357 c = ip.Completer
355 358 ip.ex('def myfunc(a=1,b=2): return a+b')
356 359 s, matches = c.complete(None, 'myfunc(1,b')
357 360 nt.assert_in('b=', matches)
358 361 # Simulate completing with cursor right after b (pos==10):
359 362 s, matches = c.complete(None, 'myfunc(1,b)', 10)
360 363 nt.assert_in('b=', matches)
361 364 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
362 365 nt.assert_in('b=', matches)
363 366 #builtin function
364 367 s, matches = c.complete(None, 'min(k, k')
365 368 nt.assert_in('key=', matches)
366 369
367 370
368 371 def test_default_arguments_from_docstring():
369 doc = min.__doc__
370 372 ip = get_ipython()
371 373 c = ip.Completer
372 374 kwd = c._default_arguments_from_docstring(
373 375 'min(iterable[, key=func]) -> value')
374 376 nt.assert_equal(kwd, ['key'])
375 377 #with cython type etc
376 378 kwd = c._default_arguments_from_docstring(
377 379 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
378 380 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
379 381 #white spaces
380 382 kwd = c._default_arguments_from_docstring(
381 383 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
382 384 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
383 385
384 386 def test_line_magics():
385 387 ip = get_ipython()
386 388 c = ip.Completer
387 389 s, matches = c.complete(None, 'lsmag')
388 390 nt.assert_in('%lsmagic', matches)
389 391 s, matches = c.complete(None, '%lsmag')
390 392 nt.assert_in('%lsmagic', matches)
391 393
392 394
393 395 def test_cell_magics():
394 396 from IPython.core.magic import register_cell_magic
395 397
396 398 @register_cell_magic
397 399 def _foo_cellm(line, cell):
398 400 pass
399 401
400 402 ip = get_ipython()
401 403 c = ip.Completer
402 404
403 405 s, matches = c.complete(None, '_foo_ce')
404 406 nt.assert_in('%%_foo_cellm', matches)
405 407 s, matches = c.complete(None, '%%_foo_ce')
406 408 nt.assert_in('%%_foo_cellm', matches)
407 409
408 410
409 411 def test_line_cell_magics():
410 412 from IPython.core.magic import register_line_cell_magic
411 413
412 414 @register_line_cell_magic
413 415 def _bar_cellm(line, cell):
414 416 pass
415 417
416 418 ip = get_ipython()
417 419 c = ip.Completer
418 420
419 421 # The policy here is trickier, see comments in completion code. The
420 422 # returned values depend on whether the user passes %% or not explicitly,
421 423 # and this will show a difference if the same name is both a line and cell
422 424 # magic.
423 425 s, matches = c.complete(None, '_bar_ce')
424 426 nt.assert_in('%_bar_cellm', matches)
425 427 nt.assert_in('%%_bar_cellm', matches)
426 428 s, matches = c.complete(None, '%_bar_ce')
427 429 nt.assert_in('%_bar_cellm', matches)
428 430 nt.assert_in('%%_bar_cellm', matches)
429 431 s, matches = c.complete(None, '%%_bar_ce')
430 432 nt.assert_not_in('%_bar_cellm', matches)
431 433 nt.assert_in('%%_bar_cellm', matches)
432 434
433 435
434 436 def test_magic_completion_order():
435 437
436 438 ip = get_ipython()
437 439 c = ip.Completer
438 440
439 441 # Test ordering of magics and non-magics with the same name
440 442 # We want the non-magic first
441 443
442 444 # Before importing matplotlib, there should only be one option:
443 445
444 446 text, matches = c.complete('mat')
445 447 nt.assert_equal(matches, ["%matplotlib"])
446 448
447 449
448 450 ip.run_cell("matplotlib = 1") # introduce name into namespace
449 451
450 452 # After the import, there should be two options, ordered like this:
451 453 text, matches = c.complete('mat')
452 454 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
453 455
454 456
455 457 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
456 458
457 459 # Order of user variable and line and cell magics with same name:
458 460 text, matches = c.complete('timeit')
459 461 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
460 462
461 463
462 464 def test_dict_key_completion_string():
463 465 """Test dictionary key completion for string keys"""
464 466 ip = get_ipython()
465 467 complete = ip.Completer.complete
466 468
467 469 ip.user_ns['d'] = {'abc': None}
468 470
469 471 # check completion at different stages
470 472 _, matches = complete(line_buffer="d[")
471 473 nt.assert_in("'abc'", matches)
472 474 nt.assert_not_in("'abc']", matches)
473 475
474 476 _, matches = complete(line_buffer="d['")
475 477 nt.assert_in("abc", matches)
476 478 nt.assert_not_in("abc']", matches)
477 479
478 480 _, matches = complete(line_buffer="d['a")
479 481 nt.assert_in("abc", matches)
480 482 nt.assert_not_in("abc']", matches)
481 483
482 484 # check use of different quoting
483 485 _, matches = complete(line_buffer="d[\"")
484 486 nt.assert_in("abc", matches)
485 487 nt.assert_not_in('abc\"]', matches)
486 488
487 489 _, matches = complete(line_buffer="d[\"a")
488 490 nt.assert_in("abc", matches)
489 491 nt.assert_not_in('abc\"]', matches)
490 492
491 493 # check sensitivity to following context
492 494 _, matches = complete(line_buffer="d[]", cursor_pos=2)
493 495 nt.assert_in("'abc'", matches)
494 496
495 497 _, matches = complete(line_buffer="d['']", cursor_pos=3)
496 498 nt.assert_in("abc", matches)
497 499 nt.assert_not_in("abc'", matches)
498 500 nt.assert_not_in("abc']", matches)
499 501
500 502 # check multiple solutions are correctly returned and that noise is not
501 503 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
502 504 5: None}
503 505
504 506 _, matches = complete(line_buffer="d['a")
505 507 nt.assert_in("abc", matches)
506 508 nt.assert_in("abd", matches)
507 509 nt.assert_not_in("bad", matches)
508 510 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
509 511
510 512 # check escaping and whitespace
511 513 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
512 514 _, matches = complete(line_buffer="d['a")
513 515 nt.assert_in("a\\nb", matches)
514 516 nt.assert_in("a\\'b", matches)
515 517 nt.assert_in("a\"b", matches)
516 518 nt.assert_in("a word", matches)
517 519 assert not any(m.endswith((']', '"', "'")) for m in matches), matches
518 520
519 521 # - can complete on non-initial word of the string
520 522 _, matches = complete(line_buffer="d['a w")
521 523 nt.assert_in("word", matches)
522 524
523 525 # - understands quote escaping
524 526 _, matches = complete(line_buffer="d['a\\'")
525 527 nt.assert_in("b", matches)
526 528
527 529 # - default quoting should work like repr
528 530 _, matches = complete(line_buffer="d[")
529 531 nt.assert_in("\"a'b\"", matches)
530 532
531 533 # - when opening quote with ", possible to match with unescaped apostrophe
532 534 _, matches = complete(line_buffer="d[\"a'")
533 535 nt.assert_in("b", matches)
534 536
535 537 # need to not split at delims that readline won't split at
536 538 if '-' not in ip.Completer.splitter.delims:
537 539 ip.user_ns['d'] = {'before-after': None}
538 540 _, matches = complete(line_buffer="d['before-af")
539 541 nt.assert_in('before-after', matches)
540 542
541 543 def test_dict_key_completion_contexts():
542 544 """Test expression contexts in which dict key completion occurs"""
543 545 ip = get_ipython()
544 546 complete = ip.Completer.complete
545 547 d = {'abc': None}
546 548 ip.user_ns['d'] = d
547 549
548 550 class C:
549 551 data = d
550 552 ip.user_ns['C'] = C
551 553 ip.user_ns['get'] = lambda: d
552 554
553 555 def assert_no_completion(**kwargs):
554 556 _, matches = complete(**kwargs)
555 557 nt.assert_not_in('abc', matches)
556 558 nt.assert_not_in('abc\'', matches)
557 559 nt.assert_not_in('abc\']', matches)
558 560 nt.assert_not_in('\'abc\'', matches)
559 561 nt.assert_not_in('\'abc\']', matches)
560 562
561 563 def assert_completion(**kwargs):
562 564 _, matches = complete(**kwargs)
563 565 nt.assert_in("'abc'", matches)
564 566 nt.assert_not_in("'abc']", matches)
565 567
566 568 # no completion after string closed, even if reopened
567 569 assert_no_completion(line_buffer="d['a'")
568 570 assert_no_completion(line_buffer="d[\"a\"")
569 571 assert_no_completion(line_buffer="d['a' + ")
570 572 assert_no_completion(line_buffer="d['a' + '")
571 573
572 574 # completion in non-trivial expressions
573 575 assert_completion(line_buffer="+ d[")
574 576 assert_completion(line_buffer="(d[")
575 577 assert_completion(line_buffer="C.data[")
576 578
577 579 # greedy flag
578 580 def assert_completion(**kwargs):
579 581 _, matches = complete(**kwargs)
580 582 nt.assert_in("get()['abc']", matches)
581 583
582 584 assert_no_completion(line_buffer="get()[")
583 585 with greedy_completion():
584 586 assert_completion(line_buffer="get()[")
585 587 assert_completion(line_buffer="get()['")
586 588 assert_completion(line_buffer="get()['a")
587 589 assert_completion(line_buffer="get()['ab")
588 590 assert_completion(line_buffer="get()['abc")
589 591
590 592
591 593
592 594 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
593 595 def test_dict_key_completion_bytes():
594 596 """Test handling of bytes in dict key completion"""
595 597 ip = get_ipython()
596 598 complete = ip.Completer.complete
597 599
598 600 ip.user_ns['d'] = {'abc': None, b'abd': None}
599 601
600 602 _, matches = complete(line_buffer="d[")
601 603 nt.assert_in("'abc'", matches)
602 604 nt.assert_in("b'abd'", matches)
603 605
604 606 if False: # not currently implemented
605 607 _, matches = complete(line_buffer="d[b")
606 608 nt.assert_in("b'abd'", matches)
607 609 nt.assert_not_in("b'abc'", matches)
608 610
609 611 _, matches = complete(line_buffer="d[b'")
610 612 nt.assert_in("abd", matches)
611 613 nt.assert_not_in("abc", matches)
612 614
613 615 _, matches = complete(line_buffer="d[B'")
614 616 nt.assert_in("abd", matches)
615 617 nt.assert_not_in("abc", matches)
616 618
617 619 _, matches = complete(line_buffer="d['")
618 620 nt.assert_in("abc", matches)
619 621 nt.assert_not_in("abd", matches)
620 622
621 623
622 624 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
623 625 def test_dict_key_completion_unicode_py2():
624 626 """Test handling of unicode in dict key completion"""
625 627 ip = get_ipython()
626 628 complete = ip.Completer.complete
627 629
628 630 ip.user_ns['d'] = {u'abc': None,
629 631 u'a\u05d0b': None}
630 632
631 633 _, matches = complete(line_buffer="d[")
632 634 nt.assert_in("u'abc'", matches)
633 635 nt.assert_in("u'a\\u05d0b'", matches)
634 636
635 637 _, matches = complete(line_buffer="d['a")
636 638 nt.assert_in("abc", matches)
637 639 nt.assert_not_in("a\\u05d0b", matches)
638 640
639 641 _, matches = complete(line_buffer="d[u'a")
640 642 nt.assert_in("abc", matches)
641 643 nt.assert_in("a\\u05d0b", matches)
642 644
643 645 _, matches = complete(line_buffer="d[U'a")
644 646 nt.assert_in("abc", matches)
645 647 nt.assert_in("a\\u05d0b", matches)
646 648
647 649 # query using escape
648 650 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
649 651 nt.assert_in("u05d0b", matches) # tokenized after \\
650 652
651 653 # query using character
652 654 _, matches = complete(line_buffer=u"d[u'a\u05d0")
653 655 nt.assert_in(u"a\u05d0b", matches)
654 656
655 657 with greedy_completion():
656 658 _, matches = complete(line_buffer="d[")
657 659 nt.assert_in("d[u'abc']", matches)
658 660 nt.assert_in("d[u'a\\u05d0b']", matches)
659 661
660 662 _, matches = complete(line_buffer="d['a")
661 663 nt.assert_in("d['abc']", matches)
662 664 nt.assert_not_in("d[u'a\\u05d0b']", matches)
663 665
664 666 _, matches = complete(line_buffer="d[u'a")
665 667 nt.assert_in("d[u'abc']", matches)
666 668 nt.assert_in("d[u'a\\u05d0b']", matches)
667 669
668 670 _, matches = complete(line_buffer="d[U'a")
669 671 nt.assert_in("d[U'abc']", matches)
670 672 nt.assert_in("d[U'a\\u05d0b']", matches)
671 673
672 674 # query using escape
673 675 _, matches = complete(line_buffer=u"d[u'a\\u05d0")
674 676 nt.assert_in("d[u'a\\u05d0b']", matches) # tokenized after \\
675 677
676 678 # query using character
677 679 _, matches = complete(line_buffer=u"d[u'a\u05d0")
678 680 nt.assert_in(u"d[u'a\u05d0b']", matches)
679 681
680 682
681 683 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
682 684 def test_dict_key_completion_unicode_py3():
683 685 """Test handling of unicode in dict key completion"""
684 686 ip = get_ipython()
685 687 complete = ip.Completer.complete
686 688
687 689 ip.user_ns['d'] = {u'a\u05d0': None}
688 690
689 691 # query using escape
690 692 _, matches = complete(line_buffer="d['a\\u05d0")
691 693 nt.assert_in("u05d0", matches) # tokenized after \\
692 694
693 695 # query using character
694 696 _, matches = complete(line_buffer="d['a\u05d0")
695 697 nt.assert_in(u"a\u05d0", matches)
696 698
697 699 with greedy_completion():
698 700 # query using escape
699 701 _, matches = complete(line_buffer="d['a\\u05d0")
700 702 nt.assert_in("d['a\\u05d0']", matches) # tokenized after \\
701 703
702 704 # query using character
703 705 _, matches = complete(line_buffer="d['a\u05d0")
704 706 nt.assert_in(u"d['a\u05d0']", matches)
705 707
706 708
707 709
708 710 @dec.skip_without('numpy')
709 711 def test_struct_array_key_completion():
710 712 """Test dict key completion applies to numpy struct arrays"""
711 713 import numpy
712 714 ip = get_ipython()
713 715 complete = ip.Completer.complete
714 716 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
715 717 _, matches = complete(line_buffer="d['")
716 718 nt.assert_in("hello", matches)
717 719 nt.assert_in("world", matches)
718 720 # complete on the numpy struct itself
719 721 dt = numpy.dtype([('my_head', [('my_dt', '>u4'), ('my_df', '>u4')]),
720 722 ('my_data', '>f4', 5)])
721 723 x = numpy.zeros(2, dtype=dt)
722 724 ip.user_ns['d'] = x[1]
723 725 _, matches = complete(line_buffer="d['")
724 726 nt.assert_in("my_head", matches)
725 727 nt.assert_in("my_data", matches)
726 728 # complete on a nested level
727 729 with greedy_completion():
728 730 ip.user_ns['d'] = numpy.zeros(2, dtype=dt)
729 731 _, matches = complete(line_buffer="d[1]['my_head']['")
730 732 nt.assert_true(any(["my_dt" in m for m in matches]))
731 733 nt.assert_true(any(["my_df" in m for m in matches]))
732 734
733 735
734 736 @dec.skip_without('pandas')
735 737 def test_dataframe_key_completion():
736 738 """Test dict key completion applies to pandas DataFrames"""
737 739 import pandas
738 740 ip = get_ipython()
739 741 complete = ip.Completer.complete
740 742 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
741 743 _, matches = complete(line_buffer="d['")
742 744 nt.assert_in("hello", matches)
743 745 nt.assert_in("world", matches)
744 746
745 747
746 748 def test_dict_key_completion_invalids():
747 749 """Smoke test cases dict key completion can't handle"""
748 750 ip = get_ipython()
749 751 complete = ip.Completer.complete
750 752
751 753 ip.user_ns['no_getitem'] = None
752 754 ip.user_ns['no_keys'] = []
753 755 ip.user_ns['cant_call_keys'] = dict
754 756 ip.user_ns['empty'] = {}
755 757 ip.user_ns['d'] = {'abc': 5}
756 758
757 759 _, matches = complete(line_buffer="no_getitem['")
758 760 _, matches = complete(line_buffer="no_keys['")
759 761 _, matches = complete(line_buffer="cant_call_keys['")
760 762 _, matches = complete(line_buffer="empty['")
761 763 _, matches = complete(line_buffer="name_error['")
762 764 _, matches = complete(line_buffer="d['\\") # incomplete escape
763 765
764 766 class KeyCompletable(object):
765 767 def __init__(self, things=()):
766 768 self.things = things
767 769
768 770 def _ipython_key_completions_(self):
769 771 return list(self.things)
770 772
771 773 def test_object_key_completion():
772 774 ip = get_ipython()
773 775 ip.user_ns['key_completable'] = KeyCompletable(['qwerty', 'qwick'])
774 776
775 777 _, matches = ip.Completer.complete(line_buffer="key_completable['qw")
776 778 nt.assert_in('qwerty', matches)
777 779 nt.assert_in('qwick', matches)
778 780
779 781
780 782 def test_aimport_module_completer():
781 783 ip = get_ipython()
782 784 _, matches = ip.complete('i', '%aimport i')
783 785 nt.assert_in('io', matches)
784 786 nt.assert_not_in('int', matches)
785 787
786 788 def test_nested_import_module_completer():
787 789 ip = get_ipython()
788 790 _, matches = ip.complete(None, 'import IPython.co', 17)
789 791 nt.assert_in('IPython.core', matches)
790 792 nt.assert_not_in('import IPython.core', matches)
791 793 nt.assert_not_in('IPython.display', matches)
792 794
793 795 def test_import_module_completer():
794 796 ip = get_ipython()
795 797 _, matches = ip.complete('i', 'import i')
796 798 nt.assert_in('io', matches)
797 799 nt.assert_not_in('int', matches)
798 800
799 801 def test_from_module_completer():
800 802 ip = get_ipython()
801 803 _, matches = ip.complete('B', 'from io import B')
802 804 nt.assert_in('BytesIO', matches)
803 805 nt.assert_not_in('BaseException', matches)
@@ -1,451 +1,455 b''
1 1 """IPython terminal interface using prompt_toolkit in place of readline"""
2 2 from __future__ import print_function
3 3
4 4 import os
5 5 import sys
6 6 import signal
7 7 import unicodedata
8 8 from warnings import warn
9 9 from wcwidth import wcwidth
10 10
11 11 from IPython.core.error import TryNext
12 12 from IPython.core.interactiveshell import InteractiveShell
13 13 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
14 14 from IPython.utils.terminal import toggle_set_term_title, set_term_title
15 15 from IPython.utils.process import abbrev_cwd
16 16 from traitlets import Bool, CBool, Unicode, Dict, Integer
17 17
18 18 from prompt_toolkit.completion import Completer, Completion
19 19 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
20 20 from prompt_toolkit.filters import HasFocus, HasSelection, Condition
21 21 from prompt_toolkit.history import InMemoryHistory
22 22 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
23 23 from prompt_toolkit.interface import CommandLineInterface
24 24 from prompt_toolkit.key_binding.manager import KeyBindingManager
25 25 from prompt_toolkit.key_binding.vi_state import InputMode
26 26 from prompt_toolkit.key_binding.bindings.vi import ViStateFilter
27 27 from prompt_toolkit.keys import Keys
28 28 from prompt_toolkit.layout.lexers import Lexer
29 29 from prompt_toolkit.layout.lexers import PygmentsLexer
30 30 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
31 31
32 32 from pygments.styles import get_style_by_name, get_all_styles
33 33 from pygments.lexers import Python3Lexer, BashLexer, PythonLexer
34 34 from pygments.token import Token
35 35
36 36 from .pt_inputhooks import get_inputhook_func
37 37 from .interactiveshell import get_default_editor, TerminalMagics
38 38
39 39
40 40 class IPythonPTCompleter(Completer):
41 41 """Adaptor to provide IPython completions to prompt_toolkit"""
42 42 def __init__(self, ipy_completer):
43 43 self.ipy_completer = ipy_completer
44 44
45 45 def get_completions(self, document, complete_event):
46 46 if not document.current_line.strip():
47 47 return
48 48
49 49 used, matches = self.ipy_completer.complete(
50 50 line_buffer=document.current_line,
51 51 cursor_pos=document.cursor_position_col
52 52 )
53 53 start_pos = -len(used)
54 54 for m in matches:
55 55 m = unicodedata.normalize('NFC', m)
56 56
57 57 # When the first character of the completion has a zero length,
58 58 # then it's probably a decomposed unicode character. E.g. caused by
59 59 # the "\dot" completion. Try to compose again with the previous
60 60 # character.
61 61 if wcwidth(m[0]) == 0:
62 62 if document.cursor_position + start_pos > 0:
63 63 char_before = document.text[document.cursor_position + start_pos - 1]
64 64 m = unicodedata.normalize('NFC', char_before + m)
65 65
66 66 # Yield the modified completion instead, if this worked.
67 67 if wcwidth(m[0:1]) == 1:
68 68 yield Completion(m, start_position=start_pos - 1)
69 69 continue
70 70
71 # TODO: Use Jedi to determine meta_text
72 # (Jedi currently has a bug that results in incorrect information.)
73 # meta_text = ''
74 # yield Completion(m, start_position=start_pos,
75 # display_meta=meta_text)
71 76 yield Completion(m, start_position=start_pos)
72 77
73
74 78 class IPythonPTLexer(Lexer):
75 79 """
76 80 Wrapper around PythonLexer and BashLexer.
77 81 """
78 82 def __init__(self):
79 83 self.python_lexer = PygmentsLexer(Python3Lexer if PY3 else PythonLexer)
80 84 self.shell_lexer = PygmentsLexer(BashLexer)
81 85
82 86 def lex_document(self, cli, document):
83 87 if document.text.startswith('!'):
84 88 return self.shell_lexer.lex_document(cli, document)
85 89 else:
86 90 return self.python_lexer.lex_document(cli, document)
87 91
88 92
89 93 class TerminalInteractiveShell(InteractiveShell):
90 94 colors_force = True
91 95
92 96 space_for_menu = Integer(6, config=True, help='Number of line at the bottom of the screen '
93 97 'to reserve for the completion menu')
94 98
95 99 def _space_for_menu_changed(self, old, new):
96 100 self._update_layout()
97 101
98 102 pt_cli = None
99 103
100 104 autoedit_syntax = CBool(False, config=True,
101 105 help="auto editing of files with syntax errors.")
102 106
103 107 confirm_exit = CBool(True, config=True,
104 108 help="""
105 109 Set to confirm when you try to exit IPython with an EOF (Control-D
106 110 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
107 111 you can force a direct exit without any confirmation.""",
108 112 )
109 113 vi_mode = Bool(False, config=True,
110 114 help="Use vi style keybindings at the prompt",
111 115 )
112 116
113 117 mouse_support = Bool(False, config=True,
114 118 help="Enable mouse support in the prompt"
115 119 )
116 120
117 121 highlighting_style = Unicode('default', config=True,
118 122 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
119 123 )
120 124
121 125 def _highlighting_style_changed(self, old, new):
122 126 self._style = self._make_style_from_name(self.highlighting_style)
123 127
124 128 highlighting_style_overrides = Dict(config=True,
125 129 help="Override highlighting format for specific tokens"
126 130 )
127 131
128 132 editor = Unicode(get_default_editor(), config=True,
129 133 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
130 134 )
131 135
132 136 term_title = Bool(True, config=True,
133 137 help="Automatically set the terminal title"
134 138 )
135 139 def _term_title_changed(self, name, new_value):
136 140 self.init_term_title()
137 141
138 142 def init_term_title(self):
139 143 # Enable or disable the terminal title.
140 144 if self.term_title:
141 145 toggle_set_term_title(True)
142 146 set_term_title('IPython: ' + abbrev_cwd())
143 147 else:
144 148 toggle_set_term_title(False)
145 149
146 150 def get_prompt_tokens(self, cli):
147 151 return [
148 152 (Token.Prompt, 'In ['),
149 153 (Token.PromptNum, str(self.execution_count)),
150 154 (Token.Prompt, ']: '),
151 155 ]
152 156
153 157 def get_continuation_tokens(self, cli, width):
154 158 return [
155 159 (Token.Prompt, (' ' * (width - 5)) + '...: '),
156 160 ]
157 161
158 162 def init_prompt_toolkit_cli(self):
159 163 if ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or not sys.stdin.isatty():
160 164 # Fall back to plain non-interactive output for tests.
161 165 # This is very limited, and only accepts a single line.
162 166 def prompt():
163 167 return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
164 168 self.prompt_for_code = prompt
165 169 return
166 170
167 171 kbmanager = KeyBindingManager.for_prompt(enable_vi_mode=self.vi_mode)
168 172 insert_mode = ViStateFilter(kbmanager.get_vi_state, InputMode.INSERT)
169 173 # Ctrl+J == Enter, seemingly
170 174 @kbmanager.registry.add_binding(Keys.ControlJ,
171 175 filter=(HasFocus(DEFAULT_BUFFER)
172 176 & ~HasSelection()
173 177 & insert_mode
174 178 ))
175 179 def _(event):
176 180 b = event.current_buffer
177 181 d = b.document
178 182 if not (d.on_last_line or d.cursor_position_row >= d.line_count
179 183 - d.empty_line_count_at_the_end()):
180 184 b.newline()
181 185 return
182 186
183 187 status, indent = self.input_splitter.check_complete(d.text)
184 188
185 189 if (status != 'incomplete') and b.accept_action.is_returnable:
186 190 b.accept_action.validate_and_handle(event.cli, b)
187 191 else:
188 192 b.insert_text('\n' + (' ' * (indent or 0)))
189 193
190 194 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER))
191 195 def _(event):
192 196 event.current_buffer.reset()
193 197
194 198 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
195 199 def _(event):
196 200 if event.current_buffer.document.text:
197 201 event.current_buffer.reset()
198 202 else:
199 203 event.cli.push_focus(DEFAULT_BUFFER)
200 204
201 205 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
202 206
203 207 @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
204 208 def _(event):
205 209 event.cli.suspend_to_background()
206 210
207 211 @Condition
208 212 def cursor_in_leading_ws(cli):
209 213 before = cli.application.buffer.document.current_line_before_cursor
210 214 return (not before) or before.isspace()
211 215
212 216 # Ctrl+I == Tab
213 217 @kbmanager.registry.add_binding(Keys.ControlI,
214 218 filter=(HasFocus(DEFAULT_BUFFER)
215 219 & ~HasSelection()
216 220 & insert_mode
217 221 & cursor_in_leading_ws
218 222 ))
219 223 def _(event):
220 224 event.current_buffer.insert_text(' ' * 4)
221 225
222 226 # Pre-populate history from IPython's history database
223 227 history = InMemoryHistory()
224 228 last_cell = u""
225 229 for _, _, cell in self.history_manager.get_tail(self.history_load_length,
226 230 include_latest=True):
227 231 # Ignore blank lines and consecutive duplicates
228 232 cell = cell.rstrip()
229 233 if cell and (cell != last_cell):
230 234 history.append(cell)
231 235
232 236 self._style = self._make_style_from_name(self.highlighting_style)
233 237 style = DynamicStyle(lambda: self._style)
234 238
235 239 self._app = create_prompt_application(
236 240 key_bindings_registry=kbmanager.registry,
237 241 history=history,
238 242 completer=IPythonPTCompleter(self.Completer),
239 243 enable_history_search=True,
240 244 style=style,
241 245 mouse_support=self.mouse_support,
242 246 **self._layout_options()
243 247 )
244 248 self.pt_cli = CommandLineInterface(self._app,
245 249 eventloop=create_eventloop(self.inputhook))
246 250
247 251 def _make_style_from_name(self, name):
248 252 """
249 253 Small wrapper that make an IPython compatible style from a style name
250 254
251 255 We need that to add style for prompt ... etc.
252 256 """
253 257 style_cls = get_style_by_name(name)
254 258 style_overrides = {
255 259 Token.Prompt: '#009900',
256 260 Token.PromptNum: '#00ff00 bold',
257 261 }
258 262 if name is 'default':
259 263 style_cls = get_style_by_name('default')
260 264 # The default theme needs to be visible on both a dark background
261 265 # and a light background, because we can't tell what the terminal
262 266 # looks like. These tweaks to the default theme help with that.
263 267 style_overrides.update({
264 268 Token.Number: '#007700',
265 269 Token.Operator: 'noinherit',
266 270 Token.String: '#BB6622',
267 271 Token.Name.Function: '#2080D0',
268 272 Token.Name.Class: 'bold #2080D0',
269 273 Token.Name.Namespace: 'bold #2080D0',
270 274 })
271 275 style_overrides.update(self.highlighting_style_overrides)
272 276 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
273 277 style_dict=style_overrides)
274 278
275 279 return style
276 280
277 281 def _layout_options(self):
278 282 """
279 283 Return the current layout option for the current Terminal InteractiveShell
280 284 """
281 285 return {
282 286 'lexer':IPythonPTLexer(),
283 287 'reserve_space_for_menu':self.space_for_menu,
284 288 'get_prompt_tokens':self.get_prompt_tokens,
285 289 'get_continuation_tokens':self.get_continuation_tokens,
286 290 'multiline':True,
287 291 }
288 292
289 293
290 294 def _update_layout(self):
291 295 """
292 296 Ask for a re computation of the application layout, if for example ,
293 297 some configuration options have changed.
294 298 """
295 299 self._app.layout = create_prompt_layout(**self._layout_options())
296 300
297 301 def prompt_for_code(self):
298 302 document = self.pt_cli.run(pre_run=self.pre_prompt)
299 303 return document.text
300 304
301 305 def init_io(self):
302 306 if sys.platform not in {'win32', 'cli'}:
303 307 return
304 308
305 309 import colorama
306 310 colorama.init()
307 311
308 312 # For some reason we make these wrappers around stdout/stderr.
309 313 # For now, we need to reset them so all output gets coloured.
310 314 # https://github.com/ipython/ipython/issues/8669
311 315 from IPython.utils import io
312 316 io.stdout = io.IOStream(sys.stdout)
313 317 io.stderr = io.IOStream(sys.stderr)
314 318
315 319 def init_magics(self):
316 320 super(TerminalInteractiveShell, self).init_magics()
317 321 self.register_magics(TerminalMagics)
318 322
319 323 def init_alias(self):
320 324 # The parent class defines aliases that can be safely used with any
321 325 # frontend.
322 326 super(TerminalInteractiveShell, self).init_alias()
323 327
324 328 # Now define aliases that only make sense on the terminal, because they
325 329 # need direct access to the console in a way that we can't emulate in
326 330 # GUI or web frontend
327 331 if os.name == 'posix':
328 332 for cmd in ['clear', 'more', 'less', 'man']:
329 333 self.alias_manager.soft_define_alias(cmd, cmd)
330 334
331 335
332 336 def __init__(self, *args, **kwargs):
333 337 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
334 338 self.init_prompt_toolkit_cli()
335 339 self.init_term_title()
336 340 self.keep_running = True
337 341
338 342 def ask_exit(self):
339 343 self.keep_running = False
340 344
341 345 rl_next_input = None
342 346
343 347 def pre_prompt(self):
344 348 if self.rl_next_input:
345 349 self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
346 350 self.rl_next_input = None
347 351
348 352 def interact(self):
349 353 while self.keep_running:
350 354 print(self.separate_in, end='')
351 355
352 356 try:
353 357 code = self.prompt_for_code()
354 358 except EOFError:
355 359 if (not self.confirm_exit) \
356 360 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
357 361 self.ask_exit()
358 362
359 363 else:
360 364 if code:
361 365 self.run_cell(code, store_history=True)
362 366 if self.autoedit_syntax and self.SyntaxTB.last_syntax_error:
363 367 self.edit_syntax_error()
364 368
365 369 def mainloop(self):
366 370 # An extra layer of protection in case someone mashing Ctrl-C breaks
367 371 # out of our internal code.
368 372 while True:
369 373 try:
370 374 self.interact()
371 375 break
372 376 except KeyboardInterrupt:
373 377 print("\nKeyboardInterrupt escaped interact()\n")
374 378
375 379 _inputhook = None
376 380 def inputhook(self, context):
377 381 if self._inputhook is not None:
378 382 self._inputhook(context)
379 383
380 384 def enable_gui(self, gui=None):
381 385 if gui:
382 386 self._inputhook = get_inputhook_func(gui)
383 387 else:
384 388 self._inputhook = None
385 389
386 390 # Methods to support auto-editing of SyntaxErrors:
387 391
388 392 def edit_syntax_error(self):
389 393 """The bottom half of the syntax error handler called in the main loop.
390 394
391 395 Loop until syntax error is fixed or user cancels.
392 396 """
393 397
394 398 while self.SyntaxTB.last_syntax_error:
395 399 # copy and clear last_syntax_error
396 400 err = self.SyntaxTB.clear_err_state()
397 401 if not self._should_recompile(err):
398 402 return
399 403 try:
400 404 # may set last_syntax_error again if a SyntaxError is raised
401 405 self.safe_execfile(err.filename, self.user_ns)
402 406 except:
403 407 self.showtraceback()
404 408 else:
405 409 try:
406 410 with open(err.filename) as f:
407 411 # This should be inside a display_trap block and I
408 412 # think it is.
409 413 sys.displayhook(f.read())
410 414 except:
411 415 self.showtraceback()
412 416
413 417 def _should_recompile(self, e):
414 418 """Utility routine for edit_syntax_error"""
415 419
416 420 if e.filename in ('<ipython console>', '<input>', '<string>',
417 421 '<console>', '<BackgroundJob compilation>',
418 422 None):
419 423 return False
420 424 try:
421 425 if (self.autoedit_syntax and
422 426 not self.ask_yes_no(
423 427 'Return to editor to correct syntax error? '
424 428 '[Y/n] ', 'y')):
425 429 return False
426 430 except EOFError:
427 431 return False
428 432
429 433 def int0(x):
430 434 try:
431 435 return int(x)
432 436 except TypeError:
433 437 return 0
434 438
435 439 # always pass integer line and offset values to editor hook
436 440 try:
437 441 self.hooks.fix_error_editor(e.filename,
438 442 int0(e.lineno), int0(e.offset),
439 443 e.msg)
440 444 except TryNext:
441 445 warn('Could not open editor')
442 446 return False
443 447 return True
444 448
445 449 # Run !system commands directly, not through pipes, so terminal programs
446 450 # work correctly.
447 451 system = InteractiveShell.system_raw
448 452
449 453
450 454 if __name__ == '__main__':
451 455 TerminalInteractiveShell.instance().interact()
@@ -1,299 +1,300 b''
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.rst, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23 from __future__ import print_function
24 24
25 25 import sys
26 26
27 27 # This check is also made in IPython/__init__, don't forget to update both when
28 28 # changing Python version requirements.
29 29 v = sys.version_info
30 30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 32 print(error, file=sys.stderr)
33 33 sys.exit(1)
34 34
35 35 PY3 = (sys.version_info[0] >= 3)
36 36
37 37 # At least we're on the python version we need, move on.
38 38
39 39 #-------------------------------------------------------------------------------
40 40 # Imports
41 41 #-------------------------------------------------------------------------------
42 42
43 43 # Stdlib imports
44 44 import os
45 45
46 46 from glob import glob
47 47
48 48 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
49 49 # update it when the contents of directories change.
50 50 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
51 51
52 52 from distutils.core import setup
53 53
54 54 # Our own imports
55 55 from setupbase import target_update
56 56
57 57 from setupbase import (
58 58 setup_args,
59 59 find_packages,
60 60 find_package_data,
61 61 check_package_data_first,
62 62 find_entry_points,
63 63 build_scripts_entrypt,
64 64 find_data_files,
65 65 git_prebuild,
66 66 install_symlinked,
67 67 install_lib_symlink,
68 68 install_scripts_for_symlink,
69 69 unsymlink,
70 70 )
71 71
72 72 isfile = os.path.isfile
73 73 pjoin = os.path.join
74 74
75 75 #-------------------------------------------------------------------------------
76 76 # Handle OS specific things
77 77 #-------------------------------------------------------------------------------
78 78
79 79 if os.name in ('nt','dos'):
80 80 os_name = 'windows'
81 81 else:
82 82 os_name = os.name
83 83
84 84 # Under Windows, 'sdist' has not been supported. Now that the docs build with
85 85 # Sphinx it might work, but let's not turn it on until someone confirms that it
86 86 # actually works.
87 87 if os_name == 'windows' and 'sdist' in sys.argv:
88 88 print('The sdist command is not available under Windows. Exiting.')
89 89 sys.exit(1)
90 90
91 91
92 92 #-------------------------------------------------------------------------------
93 93 # Things related to the IPython documentation
94 94 #-------------------------------------------------------------------------------
95 95
96 96 # update the manuals when building a source dist
97 97 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
98 98
99 99 # List of things to be updated. Each entry is a triplet of args for
100 100 # target_update()
101 101 to_update = [
102 102 ('docs/man/ipython.1.gz',
103 103 ['docs/man/ipython.1'],
104 104 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
105 105 ]
106 106
107 107
108 108 [ target_update(*t) for t in to_update ]
109 109
110 110 #---------------------------------------------------------------------------
111 111 # Find all the packages, package data, and data_files
112 112 #---------------------------------------------------------------------------
113 113
114 114 packages = find_packages()
115 115 package_data = find_package_data()
116 116
117 117 data_files = find_data_files()
118 118
119 119 setup_args['packages'] = packages
120 120 setup_args['package_data'] = package_data
121 121 setup_args['data_files'] = data_files
122 122
123 123 #---------------------------------------------------------------------------
124 124 # custom distutils commands
125 125 #---------------------------------------------------------------------------
126 126 # imports here, so they are after setuptools import if there was one
127 127 from distutils.command.sdist import sdist
128 128 from distutils.command.upload import upload
129 129
130 130 class UploadWindowsInstallers(upload):
131 131
132 132 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
133 133 user_options = upload.user_options + [
134 134 ('files=', 'f', 'exe file (or glob) to upload')
135 135 ]
136 136 def initialize_options(self):
137 137 upload.initialize_options(self)
138 138 meta = self.distribution.metadata
139 139 base = '{name}-{version}'.format(
140 140 name=meta.get_name(),
141 141 version=meta.get_version()
142 142 )
143 143 self.files = os.path.join('dist', '%s.*.exe' % base)
144 144
145 145 def run(self):
146 146 for dist_file in glob(self.files):
147 147 self.upload_file('bdist_wininst', 'any', dist_file)
148 148
149 149 setup_args['cmdclass'] = {
150 150 'build_py': \
151 151 check_package_data_first(git_prebuild('IPython')),
152 152 'sdist' : git_prebuild('IPython', sdist),
153 153 'upload_wininst' : UploadWindowsInstallers,
154 154 'symlink': install_symlinked,
155 155 'install_lib_symlink': install_lib_symlink,
156 156 'install_scripts_sym': install_scripts_for_symlink,
157 157 'unsymlink': unsymlink,
158 158 }
159 159
160 160
161 161 #---------------------------------------------------------------------------
162 162 # Handle scripts, dependencies, and setuptools specific things
163 163 #---------------------------------------------------------------------------
164 164
165 165 # For some commands, use setuptools. Note that we do NOT list install here!
166 166 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
167 167 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
168 168 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
169 169 'egg_info', 'easy_install', 'upload', 'install_egg_info',
170 170 ))
171 171
172 172 if len(needs_setuptools.intersection(sys.argv)) > 0:
173 173 import setuptools
174 174
175 175 # This dict is used for passing extra arguments that are setuptools
176 176 # specific to setup
177 177 setuptools_extra_args = {}
178 178
179 179 # setuptools requirements
180 180
181 181 extras_require = dict(
182 182 parallel = ['ipyparallel'],
183 183 qtconsole = ['qtconsole'],
184 184 doc = ['Sphinx>=1.3'],
185 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments'],
185 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'path.py'],
186 186 terminal = [],
187 187 kernel = ['ipykernel'],
188 188 nbformat = ['nbformat'],
189 189 notebook = ['notebook', 'ipywidgets'],
190 190 nbconvert = ['nbconvert'],
191 191 )
192 192 install_requires = [
193 193 'setuptools>=18.5',
194 'jedi',
194 195 'decorator',
195 196 'pickleshare',
196 197 'simplegeneric>0.8',
197 198 'traitlets',
198 199 'prompt_toolkit>=0.60',
199 200 'pygments',
200 201 ]
201 202
202 203 # Platform-specific dependencies:
203 204 # This is the correct way to specify these,
204 205 # but requires pip >= 6. pip < 6 ignores these.
205 206
206 207 extras_require.update({
207 208 ':python_version == "2.7"': ['backports.shutil_get_terminal_size'],
208 209 ':python_version == "2.7" or python_version == "3.3"': ['pathlib2'],
209 210 ':sys_platform != "win32"': ['pexpect'],
210 211 ':sys_platform == "darwin"': ['appnope'],
211 212 ':sys_platform == "win32"': ['colorama'],
212 213 'test:python_version == "2.7"': ['mock'],
213 214 })
214 215 # FIXME: re-specify above platform dependencies for pip < 6
215 216 # These would result in non-portable bdists.
216 217 if not any(arg.startswith('bdist') for arg in sys.argv):
217 218 if sys.version_info < (3, 3):
218 219 extras_require['test'].append('mock')
219 220
220 221 if sys.platform == 'darwin':
221 222 install_requires.extend(['appnope'])
222 223 have_readline = False
223 224 try:
224 225 import readline
225 226 except ImportError:
226 227 pass
227 228 else:
228 229 if 'libedit' not in readline.__doc__:
229 230 have_readline = True
230 231 if not have_readline:
231 232 install_requires.extend(['gnureadline'])
232 233
233 234 if sys.platform.startswith('win'):
234 235 extras_require['terminal'].append('pyreadline>=2.0')
235 236 else:
236 237 install_requires.append('pexpect')
237 238
238 239 # workaround pypa/setuptools#147, where setuptools misspells
239 240 # platform_python_implementation as python_implementation
240 241 if 'setuptools' in sys.modules:
241 242 for key in list(extras_require):
242 243 if 'platform_python_implementation' in key:
243 244 new_key = key.replace('platform_python_implementation', 'python_implementation')
244 245 extras_require[new_key] = extras_require.pop(key)
245 246
246 247 everything = set()
247 248 for key, deps in extras_require.items():
248 249 if ':' not in key:
249 250 everything.update(deps)
250 251 extras_require['all'] = everything
251 252
252 253 if 'setuptools' in sys.modules:
253 254 setuptools_extra_args['zip_safe'] = False
254 255 setuptools_extra_args['entry_points'] = {
255 256 'console_scripts': find_entry_points(),
256 257 'pygments.lexers': [
257 258 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
258 259 'ipython = IPython.lib.lexers:IPythonLexer',
259 260 'ipython3 = IPython.lib.lexers:IPython3Lexer',
260 261 ],
261 262 }
262 263 setup_args['extras_require'] = extras_require
263 264 requires = setup_args['install_requires'] = install_requires
264 265
265 266 # Script to be run by the windows binary installer after the default setup
266 267 # routine, to add shortcuts and similar windows-only things. Windows
267 268 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
268 269 # doesn't find them.
269 270 if 'bdist_wininst' in sys.argv:
270 271 if len(sys.argv) > 2 and \
271 272 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
272 273 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
273 274 sys.exit(1)
274 275 setup_args['data_files'].append(
275 276 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
276 277 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
277 278 setup_args['options'] = {"bdist_wininst":
278 279 {"install_script":
279 280 "ipython_win_post_install.py"}}
280 281
281 282 else:
282 283 # scripts has to be a non-empty list, or install_scripts isn't called
283 284 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
284 285
285 286 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
286 287
287 288 #---------------------------------------------------------------------------
288 289 # Do the actual setup now
289 290 #---------------------------------------------------------------------------
290 291
291 292 setup_args.update(setuptools_extra_args)
292 293
293 294
294 295
295 296 def main():
296 297 setup(**setup_args)
297 298
298 299 if __name__ == '__main__':
299 300 main()
General Comments 0
You need to be logged in to leave comments. Login now