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