##// END OF EJS Templates
Allow to completely deactivate jedi type inference....
Matthias Bussonnier -
Show More
@@ -1,1720 +1,1736 b''
1 1 # encoding: utf-8
2 2 """Completion for IPython.
3 3
4 4 This module started as fork of the rlcompleter module in the Python standard
5 5 library. The original enhancements made to rlcompleter have been sent
6 6 upstream and were accepted as of Python 2.3,
7 7
8 8 This module now support a wide variety of completion mechanism both available
9 9 for normal classic Python code, as well as completer for IPython specific
10 10 Syntax like magics.
11 11
12 12 Experimental
13 13 ============
14 14
15 15 Starting with IPython 6.0, this module can make use of the Jedi library to
16 16 generate completions both using static analysis of the code, and dynamically
17 17 inspecting multiple namespaces. The APIs attached to this new mechanism is
18 18 unstable and will raise unless use in an :any:`provisionalcompleter` context
19 19 manager.
20 20
21 21 You will find that the following are experimental:
22 22
23 23 - :any:`provisionalcompleter`
24 24 - :any:`IPCompleter.completions`
25 25 - :any:`Completion`
26 26 - :any:`rectify_completions`
27 27
28 28 .. note::
29 29
30 30 better name for :any:`rectify_completions` ?
31 31
32 32 We welcome any feedback on these new API, and we also encourage you to try this
33 33 module in debug mode (start IPython with ``--Completer.debug=True``) in order
34 34 to have extra logging information is :any:`jedi` is crashing, or if current
35 35 IPython completer pending deprecations are returning results not yet handled
36 36 by :any:`jedi`.
37 37
38 38 Using Jedi for tab completion allow snippets like the following to work without
39 39 having to execute any code:
40 40
41 41 >>> myvar = ['hello', 42]
42 42 ... myvar[1].bi<tab>
43 43
44 44 Tab completion will be able to infer that ``myvar[1]`` is a real number without
45 45 executing any code unlike the previously available ``IPCompleter.greedy``
46 46 option.
47 47
48 48 Be sure to update :any:`jedi` to the latest stable version or to try the
49 49 current development version to get better completions.
50 50 """
51 51
52 52 # skip module docstests
53 53 skip_doctest = True
54 54
55 55 # Copyright (c) IPython Development Team.
56 56 # Distributed under the terms of the Modified BSD License.
57 57 #
58 58 # Some of this code originated from rlcompleter in the Python standard library
59 59 # Copyright (C) 2001 Python Software Foundation, www.python.org
60 60
61 61
62 62 import __main__
63 63 import builtins as builtin_mod
64 64 import glob
65 65 import time
66 66 import inspect
67 67 import itertools
68 68 import keyword
69 69 import os
70 70 import re
71 71 import sys
72 72 import unicodedata
73 73 import string
74 74 import warnings
75 75
76 76 from contextlib import contextmanager
77 77 from importlib import import_module
78 78 from typing import Iterator, List
79 79 from types import SimpleNamespace
80 80
81 81 from traitlets.config.configurable import Configurable
82 82 from IPython.core.error import TryNext
83 83 from IPython.core.inputsplitter import ESC_MAGIC
84 84 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
85 85 from IPython.utils import generics
86 86 from IPython.utils.dir2 import dir2, get_real_method
87 87 from IPython.utils.process import arg_split
88 88 from IPython.utils.py3compat import cast_unicode_py2
89 from traitlets import Bool, Enum, observe
89 from traitlets import Bool, Enum, observe, Int
90 90
91 91 try:
92 92 import jedi
93 93 import jedi.api.helpers
94 94 JEDI_INSTALLED = True
95 95 except ImportError:
96 96 JEDI_INSTALLED = False
97 97 #-----------------------------------------------------------------------------
98 98 # Globals
99 99 #-----------------------------------------------------------------------------
100 100
101 101 # Public API
102 102 __all__ = ['Completer','IPCompleter']
103 103
104 104 if sys.platform == 'win32':
105 105 PROTECTABLES = ' '
106 106 else:
107 107 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
108 108
109 109
110 110 _deprecation_readline_sentinel = object()
111 111
112 112
113 113 class ProvisionalCompleterWarning(FutureWarning):
114 114 """
115 115 Exception raise by an experimental feature in this module.
116 116
117 117 Wrap code in :any:`provisionalcompleter` context manager if you
118 118 are certain you want to use an unstable feature.
119 119 """
120 120 pass
121 121
122 122 warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
123 123
124 124 @contextmanager
125 125 def provisionalcompleter(action='ignore'):
126 126 """
127 127
128 128
129 129 This contest manager has to be used in any place where unstable completer
130 130 behavior and API may be called.
131 131
132 132 >>> with provisionalcompleter():
133 133 ... completer.do_experimetal_things() # works
134 134
135 135 >>> completer.do_experimental_things() # raises.
136 136
137 137 .. note:: Unstable
138 138
139 139 By using this context manager you agree that the API in use may change
140 140 without warning, and that you won't complain if they do so.
141 141
142 142 You also understand that if the API is not to you liking you should report
143 143 a bug to explain your use case upstream and improve the API and will loose
144 144 credibility if you complain after the API is make stable.
145 145
146 146 We'll be happy to get your feedback , feature request and improvement on
147 147 any of the unstable APIs !
148 148 """
149 149 with warnings.catch_warnings():
150 150 warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
151 151 yield
152 152
153 153
154 154 def has_open_quotes(s):
155 155 """Return whether a string has open quotes.
156 156
157 157 This simply counts whether the number of quote characters of either type in
158 158 the string is odd.
159 159
160 160 Returns
161 161 -------
162 162 If there is an open quote, the quote character is returned. Else, return
163 163 False.
164 164 """
165 165 # We check " first, then ', so complex cases with nested quotes will get
166 166 # the " to take precedence.
167 167 if s.count('"') % 2:
168 168 return '"'
169 169 elif s.count("'") % 2:
170 170 return "'"
171 171 else:
172 172 return False
173 173
174 174
175 175 def protect_filename(s):
176 176 """Escape a string to protect certain characters."""
177 177 if set(s) & set(PROTECTABLES):
178 178 if sys.platform == "win32":
179 179 return '"' + s + '"'
180 180 else:
181 181 return "".join(("\\" + c if c in PROTECTABLES else c) for c in s)
182 182 else:
183 183 return s
184 184
185 185
186 186 def expand_user(path):
187 187 """Expand ``~``-style usernames in strings.
188 188
189 189 This is similar to :func:`os.path.expanduser`, but it computes and returns
190 190 extra information that will be useful if the input was being used in
191 191 computing completions, and you wish to return the completions with the
192 192 original '~' instead of its expanded value.
193 193
194 194 Parameters
195 195 ----------
196 196 path : str
197 197 String to be expanded. If no ~ is present, the output is the same as the
198 198 input.
199 199
200 200 Returns
201 201 -------
202 202 newpath : str
203 203 Result of ~ expansion in the input path.
204 204 tilde_expand : bool
205 205 Whether any expansion was performed or not.
206 206 tilde_val : str
207 207 The value that ~ was replaced with.
208 208 """
209 209 # Default values
210 210 tilde_expand = False
211 211 tilde_val = ''
212 212 newpath = path
213 213
214 214 if path.startswith('~'):
215 215 tilde_expand = True
216 216 rest = len(path)-1
217 217 newpath = os.path.expanduser(path)
218 218 if rest:
219 219 tilde_val = newpath[:-rest]
220 220 else:
221 221 tilde_val = newpath
222 222
223 223 return newpath, tilde_expand, tilde_val
224 224
225 225
226 226 def compress_user(path, tilde_expand, tilde_val):
227 227 """Does the opposite of expand_user, with its outputs.
228 228 """
229 229 if tilde_expand:
230 230 return path.replace(tilde_val, '~')
231 231 else:
232 232 return path
233 233
234 234
235 235 def completions_sorting_key(word):
236 236 """key for sorting completions
237 237
238 238 This does several things:
239 239
240 240 - Lowercase all completions, so they are sorted alphabetically with
241 241 upper and lower case words mingled
242 242 - Demote any completions starting with underscores to the end
243 243 - Insert any %magic and %%cellmagic completions in the alphabetical order
244 244 by their name
245 245 """
246 246 # Case insensitive sort
247 247 word = word.lower()
248 248
249 249 prio1, prio2 = 0, 0
250 250
251 251 if word.startswith('__'):
252 252 prio1 = 2
253 253 elif word.startswith('_'):
254 254 prio1 = 1
255 255
256 256 if word.endswith('='):
257 257 prio1 = -1
258 258
259 259 if word.startswith('%%'):
260 260 # If there's another % in there, this is something else, so leave it alone
261 261 if not "%" in word[2:]:
262 262 word = word[2:]
263 263 prio2 = 2
264 264 elif word.startswith('%'):
265 265 if not "%" in word[1:]:
266 266 word = word[1:]
267 267 prio2 = 1
268 268
269 269 return prio1, word, prio2
270 270
271 271
272 272 class _FakeJediCompletion:
273 273 """
274 274 This is a workaround to communicate to the UI that Jedi has crashed and to
275 275 report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
276 276
277 277 Added in IPython 6.0 so should likely be removed for 7.0
278 278
279 279 """
280 280
281 281 def __init__(self, name):
282 282
283 283 self.name = name
284 284 self.complete = name
285 285 self.type = 'crashed'
286 286 self.name_with_symbols = name
287 287
288 288 def __repr__(self):
289 289 return '<Fake completion object jedi has crashed>'
290 290
291 291
292 292 class Completion:
293 293 """
294 294 Completion object used and return by IPython completers.
295 295
296 296 .. warning:: Unstable
297 297
298 298 This function is unstable, API may change without warning.
299 299 It will also raise unless use in proper context manager.
300 300
301 301 This act as a middle ground :any:`Completion` object between the
302 302 :any:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
303 303 object. While Jedi need a lot of information about evaluator and how the
304 304 code should be ran/inspected, PromptToolkit (and other frontend) mostly
305 305 need user facing information.
306 306
307 307 - Which range should be replaced replaced by what.
308 308 - Some metadata (like completion type), or meta informations to displayed to
309 309 the use user.
310 310
311 311 For debugging purpose we can also store the origin of the completion (``jedi``,
312 312 ``IPython.python_matches``, ``IPython.magics_matches``...).
313 313 """
314 314
315 315 def __init__(self, start: int, end: int, text: str, *, type: str=None, _origin=''):
316 316 warnings.warn("``Completion`` is a provisional API (as of IPython 6.0). "
317 317 "It may change without warnings. "
318 318 "Use in corresponding context manager.",
319 319 category=ProvisionalCompleterWarning, stacklevel=2)
320 320
321 321 self.start = start
322 322 self.end = end
323 323 self.text = text
324 324 self.type = type
325 325 self._origin = _origin
326 326
327 327 def __repr__(self):
328 328 return '<Completion start=%s end=%s text=%r type=%r>' % (self.start, self.end, self.text, self.type or '?')
329 329
330 330 def __eq__(self, other)->Bool:
331 331 """
332 332 Equality and hash do not hash the type (as some completer may not be
333 333 able to infer the type), but are use to (partially) de-duplicate
334 334 completion.
335 335
336 336 Completely de-duplicating completion is a bit tricker that just
337 337 comparing as it depends on surrounding text, which Completions are not
338 338 aware of.
339 339 """
340 340 return self.start == other.start and \
341 341 self.end == other.end and \
342 342 self.text == other.text
343 343
344 344 def __hash__(self):
345 345 return hash((self.start, self.end, self.text))
346 346
347 347 _IC = Iterator[Completion]
348 348
349 349 def rectify_completions(text:str, completion:_IC, *, _debug=False)->_IC:
350 350 """
351 351 Rectify a set of completion to all have the same ``start`` and ``end``
352 352
353 353 .. warning:: Unstable
354 354
355 355 This function is unstable, API may change without warning.
356 356 It will also raise unless use in proper context manager.
357 357
358 358 Parameters
359 359 ----------
360 360 text: str
361 361 text that should be completed.
362 362 completion: Iterator[Completion]
363 363 iterator over the completions to rectify
364 364
365 365
366 366 :any:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
367 367 the Jupyter Protocol requires them to behave like so. This will readjust
368 368 the completion to have the same ``start`` and ``end` by padding both
369 369 extremities with surrounding text.
370 370
371 371 During stabilisation should support a ``_debug`` option to log which
372 372 completion are return by the IPython completer and not found in Jedi in
373 373 order to make upstream bug report.
374 374 """
375 375 warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
376 376 "It may change without warnings. "
377 377 "Use in corresponding context manager.",
378 378 category=ProvisionalCompleterWarning, stacklevel=2)
379 379
380 380 completions = list(completion)
381 381 if not completions:
382 382 return
383 383 starts = (c.start for c in completions)
384 384 ends = (c.end for c in completions)
385 385
386 386 new_start = min(starts)
387 387 new_end = max(ends)
388 388
389 389 seen_jedi = set()
390 390 seen_python_matches = set()
391 391 for c in completions:
392 392 new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
393 393 if c._origin == 'jedi':
394 394 seen_jedi.add(new_text)
395 395 elif c._origin == 'IPCompleter.python_matches':
396 396 seen_python_matches.add(new_text)
397 397 yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin)
398 398 diff = seen_python_matches.difference(seen_jedi)
399 399 if diff and _debug:
400 400 print('IPython.python matches have extras:', diff)
401 401
402 402
403 403 if sys.platform == 'win32':
404 404 DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
405 405 else:
406 406 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
407 407
408 408 GREEDY_DELIMS = ' =\r\n'
409 409
410 410
411 411 class CompletionSplitter(object):
412 412 """An object to split an input line in a manner similar to readline.
413 413
414 414 By having our own implementation, we can expose readline-like completion in
415 415 a uniform manner to all frontends. This object only needs to be given the
416 416 line of text to be split and the cursor position on said line, and it
417 417 returns the 'word' to be completed on at the cursor after splitting the
418 418 entire line.
419 419
420 420 What characters are used as splitting delimiters can be controlled by
421 421 setting the ``delims`` attribute (this is a property that internally
422 422 automatically builds the necessary regular expression)"""
423 423
424 424 # Private interface
425 425
426 426 # A string of delimiter characters. The default value makes sense for
427 427 # IPython's most typical usage patterns.
428 428 _delims = DELIMS
429 429
430 430 # The expression (a normal string) to be compiled into a regular expression
431 431 # for actual splitting. We store it as an attribute mostly for ease of
432 432 # debugging, since this type of code can be so tricky to debug.
433 433 _delim_expr = None
434 434
435 435 # The regular expression that does the actual splitting
436 436 _delim_re = None
437 437
438 438 def __init__(self, delims=None):
439 439 delims = CompletionSplitter._delims if delims is None else delims
440 440 self.delims = delims
441 441
442 442 @property
443 443 def delims(self):
444 444 """Return the string of delimiter characters."""
445 445 return self._delims
446 446
447 447 @delims.setter
448 448 def delims(self, delims):
449 449 """Set the delimiters for line splitting."""
450 450 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
451 451 self._delim_re = re.compile(expr)
452 452 self._delims = delims
453 453 self._delim_expr = expr
454 454
455 455 def split_line(self, line, cursor_pos=None):
456 456 """Split a line of text with a cursor at the given position.
457 457 """
458 458 l = line if cursor_pos is None else line[:cursor_pos]
459 459 return self._delim_re.split(l)[-1]
460 460
461 461
462 462
463 463 class Completer(Configurable):
464 464
465 465 greedy = Bool(False,
466 466 help="""Activate greedy completion
467 467 PENDING DEPRECTION. this is now mostly taken care of with Jedi.
468 468
469 469 This will enable completion on elements of lists, results of function calls, etc.,
470 470 but can be unsafe because the code is actually evaluated on TAB.
471 471 """
472 472 ).tag(config=True)
473 473
474 474 use_jedi = Bool(default_value=JEDI_INSTALLED,
475 475 help="Experimental: Use Jedi to generate autocompletions. "
476 476 "Default to True if jedi is installed").tag(config=True)
477 477
478 jedi_compute_type_timeout = Int(default_value=400,
479 help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
480 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
481 performance by preventing jedi to build its cache.
482 """).tag(config=True)
483
478 484 debug = Bool(default_value=False,
479 485 help='Enable debug for the Completer. Mostly print extra '
480 486 'information for experimental jedi integration.')\
481 487 .tag(config=True)
482 488
483 489
484 490 def __init__(self, namespace=None, global_namespace=None, **kwargs):
485 491 """Create a new completer for the command line.
486 492
487 493 Completer(namespace=ns, global_namespace=ns2) -> completer instance.
488 494
489 495 If unspecified, the default namespace where completions are performed
490 496 is __main__ (technically, __main__.__dict__). Namespaces should be
491 497 given as dictionaries.
492 498
493 499 An optional second namespace can be given. This allows the completer
494 500 to handle cases where both the local and global scopes need to be
495 501 distinguished.
496 502 """
497 503
498 504 # Don't bind to namespace quite yet, but flag whether the user wants a
499 505 # specific namespace or to use __main__.__dict__. This will allow us
500 506 # to bind to __main__.__dict__ at completion time, not now.
501 507 if namespace is None:
502 508 self.use_main_ns = True
503 509 else:
504 510 self.use_main_ns = False
505 511 self.namespace = namespace
506 512
507 513 # The global namespace, if given, can be bound directly
508 514 if global_namespace is None:
509 515 self.global_namespace = {}
510 516 else:
511 517 self.global_namespace = global_namespace
512 518
513 519 super(Completer, self).__init__(**kwargs)
514 520
515 521 def complete(self, text, state):
516 522 """Return the next possible completion for 'text'.
517 523
518 524 This is called successively with state == 0, 1, 2, ... until it
519 525 returns None. The completion should begin with 'text'.
520 526
521 527 """
522 528 if self.use_main_ns:
523 529 self.namespace = __main__.__dict__
524 530
525 531 if state == 0:
526 532 if "." in text:
527 533 self.matches = self.attr_matches(text)
528 534 else:
529 535 self.matches = self.global_matches(text)
530 536 try:
531 537 return self.matches[state]
532 538 except IndexError:
533 539 return None
534 540
535 541 def global_matches(self, text):
536 542 """Compute matches when text is a simple name.
537 543
538 544 Return a list of all keywords, built-in functions and names currently
539 545 defined in self.namespace or self.global_namespace that match.
540 546
541 547 """
542 548 matches = []
543 549 match_append = matches.append
544 550 n = len(text)
545 551 for lst in [keyword.kwlist,
546 552 builtin_mod.__dict__.keys(),
547 553 self.namespace.keys(),
548 554 self.global_namespace.keys()]:
549 555 for word in lst:
550 556 if word[:n] == text and word != "__builtins__":
551 557 match_append(word)
552 558 return [cast_unicode_py2(m) for m in matches]
553 559
554 560 def attr_matches(self, text):
555 561 """Compute matches when text contains a dot.
556 562
557 563 Assuming the text is of the form NAME.NAME....[NAME], and is
558 564 evaluatable in self.namespace or self.global_namespace, it will be
559 565 evaluated and its attributes (as revealed by dir()) are used as
560 566 possible completions. (For class instances, class members are are
561 567 also considered.)
562 568
563 569 WARNING: this can still invoke arbitrary C code, if an object
564 570 with a __getattr__ hook is evaluated.
565 571
566 572 """
567 573
568 574 # Another option, seems to work great. Catches things like ''.<tab>
569 575 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
570 576
571 577 if m:
572 578 expr, attr = m.group(1, 3)
573 579 elif self.greedy:
574 580 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
575 581 if not m2:
576 582 return []
577 583 expr, attr = m2.group(1,2)
578 584 else:
579 585 return []
580 586
581 587 try:
582 588 obj = eval(expr, self.namespace)
583 589 except:
584 590 try:
585 591 obj = eval(expr, self.global_namespace)
586 592 except:
587 593 return []
588 594
589 595 if self.limit_to__all__ and hasattr(obj, '__all__'):
590 596 words = get__all__entries(obj)
591 597 else:
592 598 words = dir2(obj)
593 599
594 600 try:
595 601 words = generics.complete_object(obj, words)
596 602 except TryNext:
597 603 pass
598 604 except AssertionError:
599 605 raise
600 606 except Exception:
601 607 # Silence errors from completion function
602 608 #raise # dbg
603 609 pass
604 610 # Build match list to return
605 611 n = len(attr)
606 612 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
607 613
608 614
609 615 def get__all__entries(obj):
610 616 """returns the strings in the __all__ attribute"""
611 617 try:
612 618 words = getattr(obj, '__all__')
613 619 except:
614 620 return []
615 621
616 622 return [cast_unicode_py2(w) for w in words if isinstance(w, str)]
617 623
618 624
619 625 def match_dict_keys(keys, prefix, delims):
620 626 """Used by dict_key_matches, matching the prefix to a list of keys"""
621 627 if not prefix:
622 628 return None, 0, [repr(k) for k in keys
623 629 if isinstance(k, (str, bytes))]
624 630 quote_match = re.search('["\']', prefix)
625 631 quote = quote_match.group()
626 632 try:
627 633 prefix_str = eval(prefix + quote, {})
628 634 except Exception:
629 635 return None, 0, []
630 636
631 637 pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
632 638 token_match = re.search(pattern, prefix, re.UNICODE)
633 639 token_start = token_match.start()
634 640 token_prefix = token_match.group()
635 641
636 642 # TODO: support bytes in Py3k
637 643 matched = []
638 644 for key in keys:
639 645 try:
640 646 if not key.startswith(prefix_str):
641 647 continue
642 648 except (AttributeError, TypeError, UnicodeError):
643 649 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
644 650 continue
645 651
646 652 # reformat remainder of key to begin with prefix
647 653 rem = key[len(prefix_str):]
648 654 # force repr wrapped in '
649 655 rem_repr = repr(rem + '"')
650 656 if rem_repr.startswith('u') and prefix[0] not in 'uU':
651 657 # Found key is unicode, but prefix is Py2 string.
652 658 # Therefore attempt to interpret key as string.
653 659 try:
654 660 rem_repr = repr(rem.encode('ascii') + '"')
655 661 except UnicodeEncodeError:
656 662 continue
657 663
658 664 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
659 665 if quote == '"':
660 666 # The entered prefix is quoted with ",
661 667 # but the match is quoted with '.
662 668 # A contained " hence needs escaping for comparison:
663 669 rem_repr = rem_repr.replace('"', '\\"')
664 670
665 671 # then reinsert prefix from start of token
666 672 matched.append('%s%s' % (token_prefix, rem_repr))
667 673 return quote, token_start, matched
668 674
669 675
670 676 def cursor_to_position(text:int, line:int, column:int)->int:
671 677 """
672 678
673 679 Convert the (line,column) position of the cursor in text to an offset in a
674 680 string.
675 681
676 682 Parameter
677 683 ---------
678 684
679 685 text : str
680 686 The text in which to calculate the cursor offset
681 687 line : int
682 688 Line of the cursor; 0-indexed
683 689 column : int
684 690 Column of the cursor 0-indexed
685 691
686 692 Return
687 693 ------
688 694 Position of the cursor in ``text``, 0-indexed.
689 695
690 696 See Also
691 697 --------
692 698 position_to_cursor: reciprocal of this function
693 699
694 700 """
695 701 lines = text.split('\n')
696 702 assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
697 703
698 704 return sum(len(l) + 1 for l in lines[:line]) + column
699 705
700 706 def position_to_cursor(text:str, offset:int)->(int, int):
701 707 """
702 708 Convert the position of the cursor in text (0 indexed) to a line
703 709 number(0-indexed) and a column number (0-indexed) pair
704 710
705 711 Position should be a valid position in ``text``.
706 712
707 713 Parameter
708 714 ---------
709 715
710 716 text : str
711 717 The text in which to calculate the cursor offset
712 718 offset : int
713 719 Position of the cursor in ``text``, 0-indexed.
714 720
715 721 Return
716 722 ------
717 723 (line, column) : (int, int)
718 724 Line of the cursor; 0-indexed, column of the cursor 0-indexed
719 725
720 726
721 727 See Also
722 728 --------
723 729 cursor_to_position : reciprocal of this function
724 730
725 731
726 732 """
727 733
728 734 assert 0 < offset <= len(text) , "0 < %s <= %s" % (offset , len(text))
729 735
730 736 before = text[:offset]
731 737 blines = before.split('\n') # ! splitnes trim trailing \n
732 738 line = before.count('\n')
733 739 col = len(blines[-1])
734 740 return line, col
735 741
736 742
737 743 def _safe_isinstance(obj, module, class_name):
738 744 """Checks if obj is an instance of module.class_name if loaded
739 745 """
740 746 return (module in sys.modules and
741 747 isinstance(obj, getattr(import_module(module), class_name)))
742 748
743 749
744 750 def back_unicode_name_matches(text):
745 751 u"""Match unicode characters back to unicode name
746 752
747 753 This does ``β˜ƒ`` -> ``\\snowman``
748 754
749 755 Note that snowman is not a valid python3 combining character but will be expanded.
750 756 Though it will not recombine back to the snowman character by the completion machinery.
751 757
752 758 This will not either back-complete standard sequences like \\n, \\b ...
753 759
754 760 Used on Python 3 only.
755 761 """
756 762 if len(text)<2:
757 763 return u'', ()
758 764 maybe_slash = text[-2]
759 765 if maybe_slash != '\\':
760 766 return u'', ()
761 767
762 768 char = text[-1]
763 769 # no expand on quote for completion in strings.
764 770 # nor backcomplete standard ascii keys
765 771 if char in string.ascii_letters or char in ['"',"'"]:
766 772 return u'', ()
767 773 try :
768 774 unic = unicodedata.name(char)
769 775 return '\\'+char,['\\'+unic]
770 776 except KeyError:
771 777 pass
772 778 return u'', ()
773 779
774 780 def back_latex_name_matches(text:str):
775 781 """Match latex characters back to unicode name
776 782
777 783 This does ``\\β„΅`` -> ``\\aleph``
778 784
779 785 Used on Python 3 only.
780 786 """
781 787 if len(text)<2:
782 788 return u'', ()
783 789 maybe_slash = text[-2]
784 790 if maybe_slash != '\\':
785 791 return u'', ()
786 792
787 793
788 794 char = text[-1]
789 795 # no expand on quote for completion in strings.
790 796 # nor backcomplete standard ascii keys
791 797 if char in string.ascii_letters or char in ['"',"'"]:
792 798 return u'', ()
793 799 try :
794 800 latex = reverse_latex_symbol[char]
795 801 # '\\' replace the \ as well
796 802 return '\\'+char,[latex]
797 803 except KeyError:
798 804 pass
799 805 return u'', ()
800 806
801 807
802 808 class IPCompleter(Completer):
803 809 """Extension of the completer class with IPython-specific features"""
804 810
805 811 @observe('greedy')
806 812 def _greedy_changed(self, change):
807 813 """update the splitter and readline delims when greedy is changed"""
808 814 if change['new']:
809 815 self.splitter.delims = GREEDY_DELIMS
810 816 else:
811 817 self.splitter.delims = DELIMS
812 818
813 819 merge_completions = Bool(True,
814 820 help="""Whether to merge completion results into a single list
815 821
816 822 If False, only the completion results from the first non-empty
817 823 completer will be returned.
818 824 """
819 825 ).tag(config=True)
820 826 omit__names = Enum((0,1,2), default_value=2,
821 827 help="""Instruct the completer to omit private method names
822 828
823 829 Specifically, when completing on ``object.<tab>``.
824 830
825 831 When 2 [default]: all names that start with '_' will be excluded.
826 832
827 833 When 1: all 'magic' names (``__foo__``) will be excluded.
828 834
829 835 When 0: nothing will be excluded.
830 836 """
831 837 ).tag(config=True)
832 838 limit_to__all__ = Bool(False,
833 839 help="""
834 840 DEPRECATED as of version 5.0.
835 841
836 842 Instruct the completer to use __all__ for the completion
837 843
838 844 Specifically, when completing on ``object.<tab>``.
839 845
840 846 When True: only those names in obj.__all__ will be included.
841 847
842 848 When False [default]: the __all__ attribute is ignored
843 849 """,
844 850 ).tag(config=True)
845 851
846 852 @observe('limit_to__all__')
847 853 def _limit_to_all_changed(self, change):
848 854 warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
849 855 'value has been deprecated since IPython 5.0, will be made to have '
850 856 'no effects and then removed in future version of IPython.',
851 857 UserWarning)
852 858
853 859 def __init__(self, shell=None, namespace=None, global_namespace=None,
854 860 use_readline=_deprecation_readline_sentinel, config=None, **kwargs):
855 861 """IPCompleter() -> completer
856 862
857 863 Return a completer object.
858 864
859 865 Parameters
860 866 ----------
861 867
862 868 shell
863 869 a pointer to the ipython shell itself. This is needed
864 870 because this completer knows about magic functions, and those can
865 871 only be accessed via the ipython instance.
866 872
867 873 namespace : dict, optional
868 874 an optional dict where completions are performed.
869 875
870 876 global_namespace : dict, optional
871 877 secondary optional dict for completions, to
872 878 handle cases (such as IPython embedded inside functions) where
873 879 both Python scopes are visible.
874 880
875 881 use_readline : bool, optional
876 882 DEPRECATED, ignored since IPython 6.0, will have no effects
877 883 """
878 884
879 885 self.magic_escape = ESC_MAGIC
880 886 self.splitter = CompletionSplitter()
881 887
882 888 if use_readline is not _deprecation_readline_sentinel:
883 889 warnings.warn('The `use_readline` parameter is deprecated and ignored since IPython 6.0.',
884 890 DeprecationWarning, stacklevel=2)
885 891
886 892 # _greedy_changed() depends on splitter and readline being defined:
887 893 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
888 894 config=config, **kwargs)
889 895
890 896 # List where completion matches will be stored
891 897 self.matches = []
892 898 self.shell = shell
893 899 # Regexp to split filenames with spaces in them
894 900 self.space_name_re = re.compile(r'([^\\] )')
895 901 # Hold a local ref. to glob.glob for speed
896 902 self.glob = glob.glob
897 903
898 904 # Determine if we are running on 'dumb' terminals, like (X)Emacs
899 905 # buffers, to avoid completion problems.
900 906 term = os.environ.get('TERM','xterm')
901 907 self.dumb_terminal = term in ['dumb','emacs']
902 908
903 909 # Special handling of backslashes needed in win32 platforms
904 910 if sys.platform == "win32":
905 911 self.clean_glob = self._clean_glob_win32
906 912 else:
907 913 self.clean_glob = self._clean_glob
908 914
909 915 #regexp to parse docstring for function signature
910 916 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
911 917 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
912 918 #use this if positional argument name is also needed
913 919 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
914 920
915 921 # All active matcher routines for completion
916 922 self.matchers = [
917 923 self.python_matches,
918 924 self.file_matches,
919 925 self.magic_matches,
920 926 self.python_func_kw_matches,
921 927 self.dict_key_matches,
922 928 ]
923 929
924 930 # This is set externally by InteractiveShell
925 931 self.custom_completers = None
926 932
927 933 def all_completions(self, text):
928 934 """
929 935 Wrapper around the complete method for the benefit of emacs.
930 936 """
931 937 return self.complete(text)[1]
932 938
933 939 def _clean_glob(self, text):
934 940 return self.glob("%s*" % text)
935 941
936 942 def _clean_glob_win32(self,text):
937 943 return [f.replace("\\","/")
938 944 for f in self.glob("%s*" % text)]
939 945
940 946 def file_matches(self, text):
941 947 """Match filenames, expanding ~USER type strings.
942 948
943 949 Most of the seemingly convoluted logic in this completer is an
944 950 attempt to handle filenames with spaces in them. And yet it's not
945 951 quite perfect, because Python's readline doesn't expose all of the
946 952 GNU readline details needed for this to be done correctly.
947 953
948 954 For a filename with a space in it, the printed completions will be
949 955 only the parts after what's already been typed (instead of the
950 956 full completions, as is normally done). I don't think with the
951 957 current (as of Python 2.3) Python readline it's possible to do
952 958 better."""
953 959
954 960 # chars that require escaping with backslash - i.e. chars
955 961 # that readline treats incorrectly as delimiters, but we
956 962 # don't want to treat as delimiters in filename matching
957 963 # when escaped with backslash
958 964 if text.startswith('!'):
959 965 text = text[1:]
960 966 text_prefix = u'!'
961 967 else:
962 968 text_prefix = u''
963 969
964 970 text_until_cursor = self.text_until_cursor
965 971 # track strings with open quotes
966 972 open_quotes = has_open_quotes(text_until_cursor)
967 973
968 974 if '(' in text_until_cursor or '[' in text_until_cursor:
969 975 lsplit = text
970 976 else:
971 977 try:
972 978 # arg_split ~ shlex.split, but with unicode bugs fixed by us
973 979 lsplit = arg_split(text_until_cursor)[-1]
974 980 except ValueError:
975 981 # typically an unmatched ", or backslash without escaped char.
976 982 if open_quotes:
977 983 lsplit = text_until_cursor.split(open_quotes)[-1]
978 984 else:
979 985 return []
980 986 except IndexError:
981 987 # tab pressed on empty line
982 988 lsplit = ""
983 989
984 990 if not open_quotes and lsplit != protect_filename(lsplit):
985 991 # if protectables are found, do matching on the whole escaped name
986 992 has_protectables = True
987 993 text0,text = text,lsplit
988 994 else:
989 995 has_protectables = False
990 996 text = os.path.expanduser(text)
991 997
992 998 if text == "":
993 999 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
994 1000
995 1001 # Compute the matches from the filesystem
996 1002 if sys.platform == 'win32':
997 1003 m0 = self.clean_glob(text)
998 1004 else:
999 1005 m0 = self.clean_glob(text.replace('\\', ''))
1000 1006
1001 1007 if has_protectables:
1002 1008 # If we had protectables, we need to revert our changes to the
1003 1009 # beginning of filename so that we don't double-write the part
1004 1010 # of the filename we have so far
1005 1011 len_lsplit = len(lsplit)
1006 1012 matches = [text_prefix + text0 +
1007 1013 protect_filename(f[len_lsplit:]) for f in m0]
1008 1014 else:
1009 1015 if open_quotes:
1010 1016 # if we have a string with an open quote, we don't need to
1011 1017 # protect the names at all (and we _shouldn't_, as it
1012 1018 # would cause bugs when the filesystem call is made).
1013 1019 matches = m0
1014 1020 else:
1015 1021 matches = [text_prefix +
1016 1022 protect_filename(f) for f in m0]
1017 1023
1018 1024 # Mark directories in input list by appending '/' to their names.
1019 1025 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
1020 1026
1021 1027 def magic_matches(self, text):
1022 1028 """Match magics"""
1023 1029 # Get all shell magics now rather than statically, so magics loaded at
1024 1030 # runtime show up too.
1025 1031 lsm = self.shell.magics_manager.lsmagic()
1026 1032 line_magics = lsm['line']
1027 1033 cell_magics = lsm['cell']
1028 1034 pre = self.magic_escape
1029 1035 pre2 = pre+pre
1030 1036
1031 1037 # Completion logic:
1032 1038 # - user gives %%: only do cell magics
1033 1039 # - user gives %: do both line and cell magics
1034 1040 # - no prefix: do both
1035 1041 # In other words, line magics are skipped if the user gives %% explicitly
1036 1042 bare_text = text.lstrip(pre)
1037 1043 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
1038 1044 if not text.startswith(pre2):
1039 1045 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
1040 1046 return [cast_unicode_py2(c) for c in comp]
1041 1047
1042 1048 def _jedi_matches(self, cursor_column:int, cursor_line:int, text:str):
1043 1049 """
1044 1050
1045 1051 Return a list of :any:`jedi.api.Completions` object from a ``text`` and
1046 1052 cursor position.
1047 1053
1048 1054 Parameters
1049 1055 ----------
1050 1056 cursor_column : int
1051 1057 column position of the cursor in ``text``, 0-indexed.
1052 1058 cursor_line : int
1053 1059 line position of the cursor in ``text``, 0-indexed
1054 1060 text : str
1055 1061 text to complete
1056 1062
1057 1063 Debugging
1058 1064 ---------
1059 1065
1060 1066 If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
1061 1067 object containing a string with the Jedi debug information attached.
1062 1068 """
1063 1069 namespaces = [self.namespace]
1064 1070 if self.global_namespace is not None:
1065 1071 namespaces.append(self.global_namespace)
1066 1072
1067 1073 # cursor_pos is an it, jedi wants line and column
1068 1074 offset = cursor_to_position(text, cursor_line, cursor_column)
1069 1075 if offset:
1070 1076 pre = text[offset-1]
1071 1077 completion_filter = lambda x:x
1072 1078 if pre == '.':
1073 1079 if self.omit__names == 2:
1074 1080 completion_filter = lambda c:not c.name.startswith('_')
1075 1081 elif self.omit__names == 1:
1076 1082 completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
1077 1083 elif self.omit__names == 0:
1078 1084 completion_filter = lambda x:x
1079 1085 else:
1080 1086 raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
1081 1087
1082 1088 interpreter = jedi.Interpreter(
1083 1089 text, namespaces, column=cursor_column, line=cursor_line + 1)
1084 1090 try:
1085 1091 return filter(completion_filter, interpreter.completions())
1086 1092 except Exception as e:
1087 1093 if self.debug:
1088 1094 return [_FakeJediCompletion('Opps Jedi has crash please report a bug with the following:\n"""\n%s\ns"""' % (e))]
1089 1095 else:
1090 1096 return []
1091 1097
1092 1098 def python_matches(self, text):
1093 1099 """Match attributes or global python names"""
1094 1100 if "." in text:
1095 1101 try:
1096 1102 matches = self.attr_matches(text)
1097 1103 if text.endswith('.') and self.omit__names:
1098 1104 if self.omit__names == 1:
1099 1105 # true if txt is _not_ a __ name, false otherwise:
1100 1106 no__name = (lambda txt:
1101 1107 re.match(r'.*\.__.*?__',txt) is None)
1102 1108 else:
1103 1109 # true if txt is _not_ a _ name, false otherwise:
1104 1110 no__name = (lambda txt:
1105 1111 re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
1106 1112 matches = filter(no__name, matches)
1107 1113 except NameError:
1108 1114 # catches <undefined attributes>.<tab>
1109 1115 matches = []
1110 1116 else:
1111 1117 matches = self.global_matches(text)
1112 1118 return matches
1113 1119
1114 1120 def _default_arguments_from_docstring(self, doc):
1115 1121 """Parse the first line of docstring for call signature.
1116 1122
1117 1123 Docstring should be of the form 'min(iterable[, key=func])\n'.
1118 1124 It can also parse cython docstring of the form
1119 1125 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
1120 1126 """
1121 1127 if doc is None:
1122 1128 return []
1123 1129
1124 1130 #care only the firstline
1125 1131 line = doc.lstrip().splitlines()[0]
1126 1132
1127 1133 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
1128 1134 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
1129 1135 sig = self.docstring_sig_re.search(line)
1130 1136 if sig is None:
1131 1137 return []
1132 1138 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
1133 1139 sig = sig.groups()[0].split(',')
1134 1140 ret = []
1135 1141 for s in sig:
1136 1142 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
1137 1143 ret += self.docstring_kwd_re.findall(s)
1138 1144 return ret
1139 1145
1140 1146 def _default_arguments(self, obj):
1141 1147 """Return the list of default arguments of obj if it is callable,
1142 1148 or empty list otherwise."""
1143 1149 call_obj = obj
1144 1150 ret = []
1145 1151 if inspect.isbuiltin(obj):
1146 1152 pass
1147 1153 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
1148 1154 if inspect.isclass(obj):
1149 1155 #for cython embededsignature=True the constructor docstring
1150 1156 #belongs to the object itself not __init__
1151 1157 ret += self._default_arguments_from_docstring(
1152 1158 getattr(obj, '__doc__', ''))
1153 1159 # for classes, check for __init__,__new__
1154 1160 call_obj = (getattr(obj, '__init__', None) or
1155 1161 getattr(obj, '__new__', None))
1156 1162 # for all others, check if they are __call__able
1157 1163 elif hasattr(obj, '__call__'):
1158 1164 call_obj = obj.__call__
1159 1165 ret += self._default_arguments_from_docstring(
1160 1166 getattr(call_obj, '__doc__', ''))
1161 1167
1162 1168 _keeps = (inspect.Parameter.KEYWORD_ONLY,
1163 1169 inspect.Parameter.POSITIONAL_OR_KEYWORD)
1164 1170
1165 1171 try:
1166 1172 sig = inspect.signature(call_obj)
1167 1173 ret.extend(k for k, v in sig.parameters.items() if
1168 1174 v.kind in _keeps)
1169 1175 except ValueError:
1170 1176 pass
1171 1177
1172 1178 return list(set(ret))
1173 1179
1174 1180 def python_func_kw_matches(self,text):
1175 1181 """Match named parameters (kwargs) of the last open function"""
1176 1182
1177 1183 if "." in text: # a parameter cannot be dotted
1178 1184 return []
1179 1185 try: regexp = self.__funcParamsRegex
1180 1186 except AttributeError:
1181 1187 regexp = self.__funcParamsRegex = re.compile(r'''
1182 1188 '.*?(?<!\\)' | # single quoted strings or
1183 1189 ".*?(?<!\\)" | # double quoted strings or
1184 1190 \w+ | # identifier
1185 1191 \S # other characters
1186 1192 ''', re.VERBOSE | re.DOTALL)
1187 1193 # 1. find the nearest identifier that comes before an unclosed
1188 1194 # parenthesis before the cursor
1189 1195 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
1190 1196 tokens = regexp.findall(self.text_until_cursor)
1191 1197 iterTokens = reversed(tokens); openPar = 0
1192 1198
1193 1199 for token in iterTokens:
1194 1200 if token == ')':
1195 1201 openPar -= 1
1196 1202 elif token == '(':
1197 1203 openPar += 1
1198 1204 if openPar > 0:
1199 1205 # found the last unclosed parenthesis
1200 1206 break
1201 1207 else:
1202 1208 return []
1203 1209 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
1204 1210 ids = []
1205 1211 isId = re.compile(r'\w+$').match
1206 1212
1207 1213 while True:
1208 1214 try:
1209 1215 ids.append(next(iterTokens))
1210 1216 if not isId(ids[-1]):
1211 1217 ids.pop(); break
1212 1218 if not next(iterTokens) == '.':
1213 1219 break
1214 1220 except StopIteration:
1215 1221 break
1216 1222
1217 1223 # Find all named arguments already assigned to, as to avoid suggesting
1218 1224 # them again
1219 1225 usedNamedArgs = set()
1220 1226 par_level = -1
1221 1227 for token, next_token in zip(tokens, tokens[1:]):
1222 1228 if token == '(':
1223 1229 par_level += 1
1224 1230 elif token == ')':
1225 1231 par_level -= 1
1226 1232
1227 1233 if par_level != 0:
1228 1234 continue
1229 1235
1230 1236 if next_token != '=':
1231 1237 continue
1232 1238
1233 1239 usedNamedArgs.add(token)
1234 1240
1235 1241 # lookup the candidate callable matches either using global_matches
1236 1242 # or attr_matches for dotted names
1237 1243 if len(ids) == 1:
1238 1244 callableMatches = self.global_matches(ids[0])
1239 1245 else:
1240 1246 callableMatches = self.attr_matches('.'.join(ids[::-1]))
1241 1247 argMatches = []
1242 1248 for callableMatch in callableMatches:
1243 1249 try:
1244 1250 namedArgs = self._default_arguments(eval(callableMatch,
1245 1251 self.namespace))
1246 1252 except:
1247 1253 continue
1248 1254
1249 1255 # Remove used named arguments from the list, no need to show twice
1250 1256 for namedArg in set(namedArgs) - usedNamedArgs:
1251 1257 if namedArg.startswith(text):
1252 1258 argMatches.append(u"%s=" %namedArg)
1253 1259 return argMatches
1254 1260
1255 1261 def dict_key_matches(self, text):
1256 1262 "Match string keys in a dictionary, after e.g. 'foo[' "
1257 1263 def get_keys(obj):
1258 1264 # Objects can define their own completions by defining an
1259 1265 # _ipy_key_completions_() method.
1260 1266 method = get_real_method(obj, '_ipython_key_completions_')
1261 1267 if method is not None:
1262 1268 return method()
1263 1269
1264 1270 # Special case some common in-memory dict-like types
1265 1271 if isinstance(obj, dict) or\
1266 1272 _safe_isinstance(obj, 'pandas', 'DataFrame'):
1267 1273 try:
1268 1274 return list(obj.keys())
1269 1275 except Exception:
1270 1276 return []
1271 1277 elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
1272 1278 _safe_isinstance(obj, 'numpy', 'void'):
1273 1279 return obj.dtype.names or []
1274 1280 return []
1275 1281
1276 1282 try:
1277 1283 regexps = self.__dict_key_regexps
1278 1284 except AttributeError:
1279 1285 dict_key_re_fmt = r'''(?x)
1280 1286 ( # match dict-referring expression wrt greedy setting
1281 1287 %s
1282 1288 )
1283 1289 \[ # open bracket
1284 1290 \s* # and optional whitespace
1285 1291 ([uUbB]? # string prefix (r not handled)
1286 1292 (?: # unclosed string
1287 1293 '(?:[^']|(?<!\\)\\')*
1288 1294 |
1289 1295 "(?:[^"]|(?<!\\)\\")*
1290 1296 )
1291 1297 )?
1292 1298 $
1293 1299 '''
1294 1300 regexps = self.__dict_key_regexps = {
1295 1301 False: re.compile(dict_key_re_fmt % '''
1296 1302 # identifiers separated by .
1297 1303 (?!\d)\w+
1298 1304 (?:\.(?!\d)\w+)*
1299 1305 '''),
1300 1306 True: re.compile(dict_key_re_fmt % '''
1301 1307 .+
1302 1308 ''')
1303 1309 }
1304 1310
1305 1311 match = regexps[self.greedy].search(self.text_until_cursor)
1306 1312 if match is None:
1307 1313 return []
1308 1314
1309 1315 expr, prefix = match.groups()
1310 1316 try:
1311 1317 obj = eval(expr, self.namespace)
1312 1318 except Exception:
1313 1319 try:
1314 1320 obj = eval(expr, self.global_namespace)
1315 1321 except Exception:
1316 1322 return []
1317 1323
1318 1324 keys = get_keys(obj)
1319 1325 if not keys:
1320 1326 return keys
1321 1327 closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
1322 1328 if not matches:
1323 1329 return matches
1324 1330
1325 1331 # get the cursor position of
1326 1332 # - the text being completed
1327 1333 # - the start of the key text
1328 1334 # - the start of the completion
1329 1335 text_start = len(self.text_until_cursor) - len(text)
1330 1336 if prefix:
1331 1337 key_start = match.start(2)
1332 1338 completion_start = key_start + token_offset
1333 1339 else:
1334 1340 key_start = completion_start = match.end()
1335 1341
1336 1342 # grab the leading prefix, to make sure all completions start with `text`
1337 1343 if text_start > key_start:
1338 1344 leading = ''
1339 1345 else:
1340 1346 leading = text[text_start:completion_start]
1341 1347
1342 1348 # the index of the `[` character
1343 1349 bracket_idx = match.end(1)
1344 1350
1345 1351 # append closing quote and bracket as appropriate
1346 1352 # this is *not* appropriate if the opening quote or bracket is outside
1347 1353 # the text given to this method
1348 1354 suf = ''
1349 1355 continuation = self.line_buffer[len(self.text_until_cursor):]
1350 1356 if key_start > text_start and closing_quote:
1351 1357 # quotes were opened inside text, maybe close them
1352 1358 if continuation.startswith(closing_quote):
1353 1359 continuation = continuation[len(closing_quote):]
1354 1360 else:
1355 1361 suf += closing_quote
1356 1362 if bracket_idx > text_start:
1357 1363 # brackets were opened inside text, maybe close them
1358 1364 if not continuation.startswith(']'):
1359 1365 suf += ']'
1360 1366
1361 1367 return [leading + k + suf for k in matches]
1362 1368
1363 1369 def unicode_name_matches(self, text):
1364 1370 u"""Match Latex-like syntax for unicode characters base
1365 1371 on the name of the character.
1366 1372
1367 1373 This does ``\\GREEK SMALL LETTER ETA`` -> ``Ξ·``
1368 1374
1369 1375 Works only on valid python 3 identifier, or on combining characters that
1370 1376 will combine to form a valid identifier.
1371 1377
1372 1378 Used on Python 3 only.
1373 1379 """
1374 1380 slashpos = text.rfind('\\')
1375 1381 if slashpos > -1:
1376 1382 s = text[slashpos+1:]
1377 1383 try :
1378 1384 unic = unicodedata.lookup(s)
1379 1385 # allow combining chars
1380 1386 if ('a'+unic).isidentifier():
1381 1387 return '\\'+s,[unic]
1382 1388 except KeyError:
1383 1389 pass
1384 1390 return u'', []
1385 1391
1386 1392
1387 1393 def latex_matches(self, text):
1388 1394 u"""Match Latex syntax for unicode characters.
1389 1395
1390 1396 This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``Ξ±``
1391 1397
1392 1398 Used on Python 3 only.
1393 1399 """
1394 1400 slashpos = text.rfind('\\')
1395 1401 if slashpos > -1:
1396 1402 s = text[slashpos:]
1397 1403 if s in latex_symbols:
1398 1404 # Try to complete a full latex symbol to unicode
1399 1405 # \\alpha -> Ξ±
1400 1406 return s, [latex_symbols[s]]
1401 1407 else:
1402 1408 # If a user has partially typed a latex symbol, give them
1403 1409 # a full list of options \al -> [\aleph, \alpha]
1404 1410 matches = [k for k in latex_symbols if k.startswith(s)]
1405 1411 return s, matches
1406 1412 return u'', []
1407 1413
1408 1414 def dispatch_custom_completer(self, text):
1409 1415 if not self.custom_completers:
1410 1416 return
1411 1417
1412 1418 line = self.line_buffer
1413 1419 if not line.strip():
1414 1420 return None
1415 1421
1416 1422 # Create a little structure to pass all the relevant information about
1417 1423 # the current completion to any custom completer.
1418 1424 event = SimpleNamespace()
1419 1425 event.line = line
1420 1426 event.symbol = text
1421 1427 cmd = line.split(None,1)[0]
1422 1428 event.command = cmd
1423 1429 event.text_until_cursor = self.text_until_cursor
1424 1430
1425 1431 # for foo etc, try also to find completer for %foo
1426 1432 if not cmd.startswith(self.magic_escape):
1427 1433 try_magic = self.custom_completers.s_matches(
1428 1434 self.magic_escape + cmd)
1429 1435 else:
1430 1436 try_magic = []
1431 1437
1432 1438 for c in itertools.chain(self.custom_completers.s_matches(cmd),
1433 1439 try_magic,
1434 1440 self.custom_completers.flat_matches(self.text_until_cursor)):
1435 1441 try:
1436 1442 res = c(event)
1437 1443 if res:
1438 1444 # first, try case sensitive match
1439 1445 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1440 1446 if withcase:
1441 1447 return withcase
1442 1448 # if none, then case insensitive ones are ok too
1443 1449 text_low = text.lower()
1444 1450 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1445 1451 except TryNext:
1446 1452 pass
1447 1453
1448 1454 return None
1449 1455
1450 1456 def completions(self, text: str, offset: int)->Iterator[Completion]:
1451 1457 """
1452 1458 Returns an iterator over the possible completions
1453 1459
1454 1460 .. warning:: Unstable
1455 1461
1456 1462 This function is unstable, API may change without warning.
1457 1463 It will also raise unless use in proper context manager.
1458 1464
1459 1465 Parameters
1460 1466 ----------
1461 1467
1462 1468 text:str
1463 1469 Full text of the current input, multi line string.
1464 1470 offset:int
1465 1471 Integer representing the position of the cursor in ``text``. Offset
1466 1472 is 0-based indexed.
1467 1473
1468 1474 Yields
1469 1475 ------
1470 1476 :any:`Completion` object
1471 1477
1472 1478
1473 1479 The cursor on a text can either be seen as being "in between"
1474 1480 characters or "On" a character depending on the interface visible to
1475 1481 the user. For consistency the cursor being on "in between" characters X
1476 1482 and Y is equivalent to the cursor being "on" character Y, that is to say
1477 1483 the character the cursor is on is considered as being after the cursor.
1478 1484
1479 1485 Combining characters may span more that one position in the
1480 1486 text.
1481 1487
1482 1488
1483 1489 .. note::
1484 1490
1485 1491 If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--``
1486 1492 fake Completion token to distinguish completion returned by Jedi
1487 1493 and usual IPython completion.
1488 1494
1489 1495 """
1490 1496 warnings.warn("_complete is a provisional API (as of IPython 6.0). "
1491 1497 "It may change without warnings. "
1492 1498 "Use in corresponding context manager.",
1493 1499 category=ProvisionalCompleterWarning, stacklevel=2)
1494 1500
1495 1501 # Possible Improvements / Known limitation
1496 1502 ##########################################
1497 1503 # Completions may be identical even if they have different ranges and
1498 1504 # text. For example:
1499 1505 # >>> a=1
1500 1506 # >>> a.<tab>
1501 1507 # May returns:
1502 1508 # - `a.real` from 0 to 2
1503 1509 # - `.real` from 1 to 2
1504 1510 # the current code does not (yet) check for such equivalence
1505 1511 seen = set()
1506 for c in self._completions(text, offset):
1512 for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
1507 1513 if c and (c in seen):
1508 1514 continue
1509 1515 yield c
1510 1516 seen.add(c)
1511 1517
1512 def _completions(self, full_text: str, offset: int, *, _timeout=0.4)->Iterator[Completion]:
1518 def _completions(self, full_text: str, offset: int, *, _timeout)->Iterator[Completion]:
1513 1519 """
1514 1520 Core completion module.Same signature as :any:`completions`, with the
1515 1521 extra `timeout` parameter (in seconds).
1516 1522
1517 1523
1518 1524 Computing jedi's completion ``.type`` can be quite expensive (it is a
1519 1525 lazy property) and can require some warm-up, more warm up than just
1520 1526 computing the ``name`` of a completion. The warm-up can be :
1521 1527
1522 1528 - Long warm-up the fisrt time a module is encountered after
1523 1529 install/update: actually build parse/inference tree.
1524 1530
1525 1531 - first time the module is encountered in a session: load tree from
1526 1532 disk.
1527 1533
1528 1534 We don't want to block completions for tens of seconds so we give the
1529 1535 completer a "budget" of ``_timeout`` seconds per invocation to compute
1530 1536 completions types, the completions that have not yet been computed will
1531 1537 be marked as "unknown" an will have a chance to be computed next round
1532 1538 are things get cached.
1533 1539
1534 1540 Keep in mind that Jedi is not the only thing treating the completion so
1535 1541 keep the timeout short-ish as if we take more than 0.3 second we still
1536 1542 have lots of processing to do.
1537 1543
1538 1544 """
1539 1545 deadline = time.monotonic() + _timeout
1540 1546
1541 1547
1542 1548 before = full_text[:offset]
1543 1549 cursor_line, cursor_column = position_to_cursor(full_text, offset)
1544 1550
1545 1551 matched_text, matches, matches_origin, jedi_matches = self._complete(
1546 1552 full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column)
1547 1553
1548 1554 iter_jm = iter(jedi_matches)
1549 for jm in iter_jm:
1550 delta = len(jm.name_with_symbols) - len(jm.complete)
1551 yield Completion(start=offset - delta, end=offset, text=jm.name_with_symbols, type=jm.type, _origin='jedi')
1552 if time.monotonic() > deadline:
1553 break
1555 if _timeout:
1556 for jm in iter_jm:
1557 delta = len(jm.name_with_symbols) - len(jm.complete)
1558 yield Completion(start=offset - delta,
1559 end=offset,
1560 text=jm.name_with_symbols,
1561 type=jm.type,
1562 _origin='jedi')
1563
1564 if time.monotonic() > deadline:
1565 break
1554 1566
1555 1567 for jm in iter_jm:
1556 1568 delta = len(jm.name_with_symbols) - len(jm.complete)
1557 yield Completion(start=offset - delta, end=offset, text=jm.name_with_symbols+'?', type='<unknown>', _origin='jedi')
1569 yield Completion(start=offset - delta,
1570 end=offset,
1571 text=jm.name_with_symbols,
1572 type='<unknown>', # don't compute type for speed
1573 _origin='jedi')
1558 1574
1559 1575
1560 1576 start_offset = before.rfind(matched_text)
1561 1577
1562 1578 # TODO:
1563 1579 # Supress this, right now just for debug.
1564 1580 if jedi_matches and matches and self.debug:
1565 1581 yield Completion(start=start_offset, end=offset, text='--jedi/ipython--', _origin='debug')
1566 1582
1567 1583 # I'm unsure if this is always true, so let's assert and see if it
1568 1584 # crash
1569 1585 assert before.endswith(matched_text)
1570 1586 for m, t in zip(matches, matches_origin):
1571 1587 yield Completion(start=start_offset, end=offset, text=m, _origin=t)
1572 1588
1573 1589
1574 1590 def complete(self, text=None, line_buffer=None, cursor_pos=None):
1575 1591 """Find completions for the given text and line context.
1576 1592
1577 1593 Note that both the text and the line_buffer are optional, but at least
1578 1594 one of them must be given.
1579 1595
1580 1596 Parameters
1581 1597 ----------
1582 1598 text : string, optional
1583 1599 Text to perform the completion on. If not given, the line buffer
1584 1600 is split using the instance's CompletionSplitter object.
1585 1601
1586 1602 line_buffer : string, optional
1587 1603 If not given, the completer attempts to obtain the current line
1588 1604 buffer via readline. This keyword allows clients which are
1589 1605 requesting for text completions in non-readline contexts to inform
1590 1606 the completer of the entire text.
1591 1607
1592 1608 cursor_pos : int, optional
1593 1609 Index of the cursor in the full line buffer. Should be provided by
1594 1610 remote frontends where kernel has no access to frontend state.
1595 1611
1596 1612 Returns
1597 1613 -------
1598 1614 text : str
1599 1615 Text that was actually used in the completion.
1600 1616
1601 1617 matches : list
1602 1618 A list of completion matches.
1603 1619
1604 1620
1605 1621 .. note::
1606 1622
1607 1623 This API is likely to be deprecated and replaced by
1608 1624 :any:`IPCompleter.completions` in the future.
1609 1625
1610 1626
1611 1627 """
1612 1628 warnings.warn('`Completer.complete` is pending deprecation since '
1613 1629 'IPython 6.0 and will be replaced by `Completer.completions`.',
1614 1630 PendingDeprecationWarning)
1615 1631 # potential todo, FOLD the 3rd throw away argument of _complete
1616 1632 # into the first 2 one.
1617 1633 return self._complete(line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0)[:2]
1618 1634
1619 1635 def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
1620 1636 full_text=None, return_jedi_results=True) -> (str, List[str], List[object]):
1621 1637 """
1622 1638
1623 1639 Like complete but can also returns raw jedi completions as well as the
1624 1640 origin of the completion text. This could (and should) be made much
1625 1641 cleaner but that will be simpler once we drop the old (and stateful)
1626 1642 :any:`complete` API.
1627 1643
1628 1644
1629 1645 With current provisional API, cursor_pos act both (depending on the
1630 1646 caller) as the offset in the ``text`` or ``line_buffer``, or as the
1631 1647 ``column`` when passing multiline strings this could/should be renamed
1632 1648 but would add extra noise.
1633 1649 """
1634 1650
1635 1651 # if the cursor position isn't given, the only sane assumption we can
1636 1652 # make is that it's at the end of the line (the common case)
1637 1653 if cursor_pos is None:
1638 1654 cursor_pos = len(line_buffer) if text is None else len(text)
1639 1655
1640 1656 if self.use_main_ns:
1641 1657 self.namespace = __main__.__dict__
1642 1658
1643 1659 # if text is either None or an empty string, rely on the line buffer
1644 1660 if (not line_buffer) and full_text:
1645 1661 line_buffer = full_text.split('\n')[cursor_line]
1646 1662 if not text:
1647 1663 text = self.splitter.split_line(line_buffer, cursor_pos)
1648 1664
1649 1665 base_text = text if not line_buffer else line_buffer[:cursor_pos]
1650 1666 latex_text, latex_matches = self.latex_matches(base_text)
1651 1667 if latex_matches:
1652 1668 return latex_text, latex_matches, ['latex_matches']*len(latex_matches), ()
1653 1669 name_text = ''
1654 1670 name_matches = []
1655 1671 for meth in (self.unicode_name_matches, back_latex_name_matches, back_unicode_name_matches):
1656 1672 name_text, name_matches = meth(base_text)
1657 1673 if name_text:
1658 1674 return name_text, name_matches, [meth.__qualname__]*len(name_matches), {}
1659 1675
1660 1676
1661 1677 # If no line buffer is given, assume the input text is all there was
1662 1678 if line_buffer is None:
1663 1679 line_buffer = text
1664 1680
1665 1681 self.line_buffer = line_buffer
1666 1682 self.text_until_cursor = self.line_buffer[:cursor_pos]
1667 1683
1668 1684 # Start with a clean slate of completions
1669 1685 matches = []
1670 1686 custom_res = self.dispatch_custom_completer(text)
1671 1687 # FIXME: we should extend our api to return a dict with completions for
1672 1688 # different types of objects. The rlcomplete() method could then
1673 1689 # simply collapse the dict into a list for readline, but we'd have
1674 1690 # richer completion semantics in other evironments.
1675 1691 completions = ()
1676 1692 if self.use_jedi and return_jedi_results:
1677 1693 if not full_text:
1678 1694 full_text = line_buffer
1679 1695 completions = self._jedi_matches(
1680 1696 cursor_pos, cursor_line, full_text)
1681 1697 if custom_res is not None:
1682 1698 # did custom completers produce something?
1683 1699 matches = [(m, 'custom') for m in custom_res]
1684 1700 else:
1685 1701 # Extend the list of completions with the results of each
1686 1702 # matcher, so we return results to the user from all
1687 1703 # namespaces.
1688 1704 if self.merge_completions:
1689 1705 matches = []
1690 1706 for matcher in self.matchers:
1691 1707 try:
1692 1708 matches.extend([(m, matcher.__qualname__)
1693 1709 for m in matcher(text)])
1694 1710 except:
1695 1711 # Show the ugly traceback if the matcher causes an
1696 1712 # exception, but do NOT crash the kernel!
1697 1713 sys.excepthook(*sys.exc_info())
1698 1714 else:
1699 1715 for matcher in self.matchers:
1700 1716 matches = [(m, matcher.__qualname__)
1701 1717 for m in matcher(text)]
1702 1718 if matches:
1703 1719 break
1704 1720 seen = set()
1705 1721 filtered_matches = set()
1706 1722 for m in matches:
1707 1723 t, c = m
1708 1724 if t not in seen:
1709 1725 filtered_matches.add(m)
1710 1726 seen.add(t)
1711 1727
1712 1728 filtered_matches = sorted(
1713 1729 set(filtered_matches), key=lambda x: completions_sorting_key(x[0]))
1714 1730
1715 1731 matches = [m[0] for m in filtered_matches]
1716 1732 origins = [m[1] for m in filtered_matches]
1717 1733
1718 1734 self.matches = matches
1719 1735
1720 1736 return text, matches, origins, completions
General Comments 0
You need to be logged in to leave comments. Login now