##// END OF EJS Templates
Make dict key completion more conservative...
Joel Nothman -
Show More
@@ -1,1115 +1,1131 b''
1 1 """Word completion for IPython.
2 2
3 3 This module is a fork of the rlcompleter module in the Python standard
4 4 library. The original enhancements made to rlcompleter have been sent
5 5 upstream and were accepted as of Python 2.3, but we need a lot more
6 6 functionality specific to IPython, so this module will continue to live as an
7 7 IPython-specific utility.
8 8
9 9 Original rlcompleter documentation:
10 10
11 11 This requires the latest extension to the readline module (the
12 12 completes keywords, built-ins and globals in __main__; when completing
13 13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 14 completes its attributes.
15 15
16 16 It's very cool to do "import string" type "string.", hit the
17 17 completion key (twice), and see the list of names defined by the
18 18 string module!
19 19
20 20 Tip: to use the tab key as the completion key, call
21 21
22 22 readline.parse_and_bind("tab: complete")
23 23
24 24 Notes:
25 25
26 26 - Exceptions raised by the completer function are *ignored* (and
27 27 generally cause the completion to fail). This is a feature -- since
28 28 readline sets the tty device in raw (or cbreak) mode, printing a
29 29 traceback wouldn't work well without some complicated hoopla to save,
30 30 reset and restore the tty state.
31 31
32 32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 33 application defined code to be executed if an object with a
34 34 ``__getattr__`` hook is found. Since it is the responsibility of the
35 35 application (or the user) to enable this feature, I consider this an
36 36 acceptable risk. More complicated expressions (e.g. function calls or
37 37 indexing operations) are *not* evaluated.
38 38
39 39 - GNU readline is also used by the built-in functions input() and
40 40 raw_input(), and thus these also benefit/suffer from the completer
41 41 features. Clearly an interactive application can benefit by
42 42 specifying its own completer function and using raw_input() for all
43 43 its input.
44 44
45 45 - When the original stdin is not a tty device, GNU readline is never
46 46 used, and this module (and the readline module) are silently inactive.
47 47 """
48 48
49 49 #*****************************************************************************
50 50 #
51 51 # Since this file is essentially a minimally modified copy of the rlcompleter
52 52 # module which is part of the standard Python distribution, I assume that the
53 53 # proper procedure is to maintain its copyright as belonging to the Python
54 54 # Software Foundation (in addition to my own, for all new code).
55 55 #
56 56 # Copyright (C) 2008 IPython Development Team
57 57 # Copyright (C) 2001 Fernando Perez. <fperez@colorado.edu>
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 #
60 60 # Distributed under the terms of the BSD License. The full license is in
61 61 # the file COPYING, distributed as part of this software.
62 62 #
63 63 #*****************************************************************************
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # Imports
67 67 #-----------------------------------------------------------------------------
68 68
69 69 import __main__
70 70 import glob
71 71 import inspect
72 72 import itertools
73 73 import keyword
74 74 import os
75 75 import re
76 76 import sys
77 77
78 78 from IPython.config.configurable import Configurable
79 79 from IPython.core.error import TryNext
80 80 from IPython.core.inputsplitter import ESC_MAGIC
81 81 from IPython.utils import generics
82 82 from IPython.utils import io
83 83 from IPython.utils.dir2 import dir2
84 84 from IPython.utils.process import arg_split
85 85 from IPython.utils.py3compat import builtin_mod, string_types
86 86 from IPython.utils.traitlets import CBool, Enum
87 87
88 88 #-----------------------------------------------------------------------------
89 89 # Globals
90 90 #-----------------------------------------------------------------------------
91 91
92 92 # Public API
93 93 __all__ = ['Completer','IPCompleter']
94 94
95 95 if sys.platform == 'win32':
96 96 PROTECTABLES = ' '
97 97 else:
98 98 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
99 99
100
101 # For dict key completion
102 try:
103 import numpy
104 except ImportError:
105 STRUCT_ARRAY_TYPES = ()
106 else:
107 STRUCT_ARRAY_TYPES = (numpy.ndarray,)
108 try:
109 import pandas
110 except ImportError:
111 KEYED_DICT_TYPES = (dict,)
112 else:
113 KEYED_DICT_TYPES = (dict, pandas.DataFrame)
114
100 115 #-----------------------------------------------------------------------------
101 116 # Main functions and classes
102 117 #-----------------------------------------------------------------------------
103 118
104 119 def has_open_quotes(s):
105 120 """Return whether a string has open quotes.
106 121
107 122 This simply counts whether the number of quote characters of either type in
108 123 the string is odd.
109 124
110 125 Returns
111 126 -------
112 127 If there is an open quote, the quote character is returned. Else, return
113 128 False.
114 129 """
115 130 # We check " first, then ', so complex cases with nested quotes will get
116 131 # the " to take precedence.
117 132 if s.count('"') % 2:
118 133 return '"'
119 134 elif s.count("'") % 2:
120 135 return "'"
121 136 else:
122 137 return False
123 138
124 139
125 140 def protect_filename(s):
126 141 """Escape a string to protect certain characters."""
127 142
128 143 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
129 144 for ch in s])
130 145
131 146 def expand_user(path):
132 147 """Expand '~'-style usernames in strings.
133 148
134 149 This is similar to :func:`os.path.expanduser`, but it computes and returns
135 150 extra information that will be useful if the input was being used in
136 151 computing completions, and you wish to return the completions with the
137 152 original '~' instead of its expanded value.
138 153
139 154 Parameters
140 155 ----------
141 156 path : str
142 157 String to be expanded. If no ~ is present, the output is the same as the
143 158 input.
144 159
145 160 Returns
146 161 -------
147 162 newpath : str
148 163 Result of ~ expansion in the input path.
149 164 tilde_expand : bool
150 165 Whether any expansion was performed or not.
151 166 tilde_val : str
152 167 The value that ~ was replaced with.
153 168 """
154 169 # Default values
155 170 tilde_expand = False
156 171 tilde_val = ''
157 172 newpath = path
158 173
159 174 if path.startswith('~'):
160 175 tilde_expand = True
161 176 rest = len(path)-1
162 177 newpath = os.path.expanduser(path)
163 178 if rest:
164 179 tilde_val = newpath[:-rest]
165 180 else:
166 181 tilde_val = newpath
167 182
168 183 return newpath, tilde_expand, tilde_val
169 184
170 185
171 186 def compress_user(path, tilde_expand, tilde_val):
172 187 """Does the opposite of expand_user, with its outputs.
173 188 """
174 189 if tilde_expand:
175 190 return path.replace(tilde_val, '~')
176 191 else:
177 192 return path
178 193
179 194
180 195
181 196 def penalize_magics_key(word):
182 197 """key for sorting that penalizes magic commands in the ordering
183 198
184 199 Normal words are left alone.
185 200
186 201 Magic commands have the initial % moved to the end, e.g.
187 202 %matplotlib is transformed as follows:
188 203
189 204 %matplotlib -> matplotlib%
190 205
191 206 [The choice of the final % is arbitrary.]
192 207
193 208 Since "matplotlib" < "matplotlib%" as strings,
194 209 "timeit" will appear before the magic "%timeit" in the ordering
195 210
196 211 For consistency, move "%%" to the end, so cell magics appear *after*
197 212 line magics with the same name.
198 213
199 214 A check is performed that there are no other "%" in the string;
200 215 if there are, then the string is not a magic command and is left unchanged.
201 216
202 217 """
203 218
204 219 # Move any % signs from start to end of the key
205 220 # provided there are no others elsewhere in the string
206 221
207 222 if word[:2] == "%%":
208 223 if not "%" in word[2:]:
209 224 return word[2:] + "%%"
210 225
211 226 if word[:1] == "%":
212 227 if not "%" in word[1:]:
213 228 return word[1:] + "%"
214 229
215 230 return word
216 231
217 232
218 233
219 234 class Bunch(object): pass
220 235
221 236
222 237 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
223 238 GREEDY_DELIMS = ' =\r\n'
224 239
225 240
226 241 class CompletionSplitter(object):
227 242 """An object to split an input line in a manner similar to readline.
228 243
229 244 By having our own implementation, we can expose readline-like completion in
230 245 a uniform manner to all frontends. This object only needs to be given the
231 246 line of text to be split and the cursor position on said line, and it
232 247 returns the 'word' to be completed on at the cursor after splitting the
233 248 entire line.
234 249
235 250 What characters are used as splitting delimiters can be controlled by
236 251 setting the `delims` attribute (this is a property that internally
237 252 automatically builds the necessary regular expression)"""
238 253
239 254 # Private interface
240 255
241 256 # A string of delimiter characters. The default value makes sense for
242 257 # IPython's most typical usage patterns.
243 258 _delims = DELIMS
244 259
245 260 # The expression (a normal string) to be compiled into a regular expression
246 261 # for actual splitting. We store it as an attribute mostly for ease of
247 262 # debugging, since this type of code can be so tricky to debug.
248 263 _delim_expr = None
249 264
250 265 # The regular expression that does the actual splitting
251 266 _delim_re = None
252 267
253 268 def __init__(self, delims=None):
254 269 delims = CompletionSplitter._delims if delims is None else delims
255 270 self.delims = delims
256 271
257 272 @property
258 273 def delims(self):
259 274 """Return the string of delimiter characters."""
260 275 return self._delims
261 276
262 277 @delims.setter
263 278 def delims(self, delims):
264 279 """Set the delimiters for line splitting."""
265 280 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
266 281 self._delim_re = re.compile(expr)
267 282 self._delims = delims
268 283 self._delim_expr = expr
269 284
270 285 def split_line(self, line, cursor_pos=None):
271 286 """Split a line of text with a cursor at the given position.
272 287 """
273 288 l = line if cursor_pos is None else line[:cursor_pos]
274 289 return self._delim_re.split(l)[-1]
275 290
276 291
277 292 class Completer(Configurable):
278 293
279 294 greedy = CBool(False, config=True,
280 295 help="""Activate greedy completion
281 296
282 297 This will enable completion on elements of lists, results of function calls, etc.,
283 298 but can be unsafe because the code is actually evaluated on TAB.
284 299 """
285 300 )
286 301
287 302
288 303 def __init__(self, namespace=None, global_namespace=None, **kwargs):
289 304 """Create a new completer for the command line.
290 305
291 306 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
292 307
293 308 If unspecified, the default namespace where completions are performed
294 309 is __main__ (technically, __main__.__dict__). Namespaces should be
295 310 given as dictionaries.
296 311
297 312 An optional second namespace can be given. This allows the completer
298 313 to handle cases where both the local and global scopes need to be
299 314 distinguished.
300 315
301 316 Completer instances should be used as the completion mechanism of
302 317 readline via the set_completer() call:
303 318
304 319 readline.set_completer(Completer(my_namespace).complete)
305 320 """
306 321
307 322 # Don't bind to namespace quite yet, but flag whether the user wants a
308 323 # specific namespace or to use __main__.__dict__. This will allow us
309 324 # to bind to __main__.__dict__ at completion time, not now.
310 325 if namespace is None:
311 326 self.use_main_ns = 1
312 327 else:
313 328 self.use_main_ns = 0
314 329 self.namespace = namespace
315 330
316 331 # The global namespace, if given, can be bound directly
317 332 if global_namespace is None:
318 333 self.global_namespace = {}
319 334 else:
320 335 self.global_namespace = global_namespace
321 336
322 337 super(Completer, self).__init__(**kwargs)
323 338
324 339 def complete(self, text, state):
325 340 """Return the next possible completion for 'text'.
326 341
327 342 This is called successively with state == 0, 1, 2, ... until it
328 343 returns None. The completion should begin with 'text'.
329 344
330 345 """
331 346 if self.use_main_ns:
332 347 self.namespace = __main__.__dict__
333 348
334 349 if state == 0:
335 350 if "." in text:
336 351 self.matches = self.attr_matches(text)
337 352 else:
338 353 self.matches = self.global_matches(text)
339 354 try:
340 355 return self.matches[state]
341 356 except IndexError:
342 357 return None
343 358
344 359 def global_matches(self, text):
345 360 """Compute matches when text is a simple name.
346 361
347 362 Return a list of all keywords, built-in functions and names currently
348 363 defined in self.namespace or self.global_namespace that match.
349 364
350 365 """
351 366 #print 'Completer->global_matches, txt=%r' % text # dbg
352 367 matches = []
353 368 match_append = matches.append
354 369 n = len(text)
355 370 for lst in [keyword.kwlist,
356 371 builtin_mod.__dict__.keys(),
357 372 self.namespace.keys(),
358 373 self.global_namespace.keys()]:
359 374 for word in lst:
360 375 if word[:n] == text and word != "__builtins__":
361 376 match_append(word)
362 377 return matches
363 378
364 379 def attr_matches(self, text):
365 380 """Compute matches when text contains a dot.
366 381
367 382 Assuming the text is of the form NAME.NAME....[NAME], and is
368 383 evaluatable in self.namespace or self.global_namespace, it will be
369 384 evaluated and its attributes (as revealed by dir()) are used as
370 385 possible completions. (For class instances, class members are are
371 386 also considered.)
372 387
373 388 WARNING: this can still invoke arbitrary C code, if an object
374 389 with a __getattr__ hook is evaluated.
375 390
376 391 """
377 392
378 393 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
379 394 # Another option, seems to work great. Catches things like ''.<tab>
380 395 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
381 396
382 397 if m:
383 398 expr, attr = m.group(1, 3)
384 399 elif self.greedy:
385 400 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
386 401 if not m2:
387 402 return []
388 403 expr, attr = m2.group(1,2)
389 404 else:
390 405 return []
391 406
392 407 try:
393 408 obj = eval(expr, self.namespace)
394 409 except:
395 410 try:
396 411 obj = eval(expr, self.global_namespace)
397 412 except:
398 413 return []
399 414
400 415 if self.limit_to__all__ and hasattr(obj, '__all__'):
401 416 words = get__all__entries(obj)
402 417 else:
403 418 words = dir2(obj)
404 419
405 420 try:
406 421 words = generics.complete_object(obj, words)
407 422 except TryNext:
408 423 pass
409 424 except Exception:
410 425 # Silence errors from completion function
411 426 #raise # dbg
412 427 pass
413 428 # Build match list to return
414 429 n = len(attr)
415 430 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
416 431 return res
417 432
418 433
419 434 def get__all__entries(obj):
420 435 """returns the strings in the __all__ attribute"""
421 436 try:
422 437 words = getattr(obj, '__all__')
423 438 except:
424 439 return []
425 440
426 441 return [w for w in words if isinstance(w, string_types)]
427 442
428 443
429 444 def match_dict_keys(keys, prefix):
430 445 """Used by dict_key_matches, matching the prefix to a list of keys"""
431 446 if not prefix:
432 447 return None, [repr(k) for k in keys
433 448 if isinstance(k, (string_types, bytes))]
434 449 quote_match = re.search('["\']', prefix)
435 450 quote = quote_match.group()
436 451 try:
437 452 prefix_str = eval(prefix + quote, {})
438 453 except Exception:
439 454 return None, []
440 455
441 456 token_prefix = re.search('\w*$', prefix).group()
442 457
443 458 # TODO: support bytes in Py3k
444 459 matched = []
445 460 for key in keys:
446 461 try:
447 462 if not key.startswith(prefix_str):
448 463 continue
449 464 except (AttributeError, TypeError, UnicodeError):
450 465 # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
451 466 continue
452 467
453 468 # reformat remainder of key to begin with prefix
454 469 rem = key[len(prefix_str):]
455 470 # force repr wrapped in '
456 471 rem_repr = repr(rem + '"')
457 472 if rem_repr.startswith('u') and prefix[0] not in 'uU':
458 473 # Found key is unicode, but prefix is Py2 string.
459 474 # Therefore attempt to interpret key as string.
460 475 try:
461 476 rem_repr = repr(rem.encode('ascii') + '"')
462 477 except UnicodeEncodeError:
463 478 continue
464 479
465 480 rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
466 481 if quote == '"':
467 482 # The entered prefix is quoted with ",
468 483 # but the match is quoted with '.
469 484 # A contained " hence needs escaping for comparison:
470 485 rem_repr = rem_repr.replace('"', '\\"')
471 486
472 487 # then reinsert prefix from start of token
473 488 matched.append('%s%s' % (token_prefix, rem_repr))
474 489 return quote, matched
475 490
476 491
477 492
478 493 class IPCompleter(Completer):
479 494 """Extension of the completer class with IPython-specific features"""
480 495
481 496 def _greedy_changed(self, name, old, new):
482 497 """update the splitter and readline delims when greedy is changed"""
483 498 if new:
484 499 self.splitter.delims = GREEDY_DELIMS
485 500 else:
486 501 self.splitter.delims = DELIMS
487 502
488 503 if self.readline:
489 504 self.readline.set_completer_delims(self.splitter.delims)
490 505
491 506 merge_completions = CBool(True, config=True,
492 507 help="""Whether to merge completion results into a single list
493 508
494 509 If False, only the completion results from the first non-empty
495 510 completer will be returned.
496 511 """
497 512 )
498 513 omit__names = Enum((0,1,2), default_value=2, config=True,
499 514 help="""Instruct the completer to omit private method names
500 515
501 516 Specifically, when completing on ``object.<tab>``.
502 517
503 518 When 2 [default]: all names that start with '_' will be excluded.
504 519
505 520 When 1: all 'magic' names (``__foo__``) will be excluded.
506 521
507 522 When 0: nothing will be excluded.
508 523 """
509 524 )
510 525 limit_to__all__ = CBool(default_value=False, config=True,
511 526 help="""Instruct the completer to use __all__ for the completion
512 527
513 528 Specifically, when completing on ``object.<tab>``.
514 529
515 530 When True: only those names in obj.__all__ will be included.
516 531
517 532 When False [default]: the __all__ attribute is ignored
518 533 """
519 534 )
520 535
521 536 def __init__(self, shell=None, namespace=None, global_namespace=None,
522 537 use_readline=True, config=None, **kwargs):
523 538 """IPCompleter() -> completer
524 539
525 540 Return a completer object suitable for use by the readline library
526 541 via readline.set_completer().
527 542
528 543 Inputs:
529 544
530 545 - shell: a pointer to the ipython shell itself. This is needed
531 546 because this completer knows about magic functions, and those can
532 547 only be accessed via the ipython instance.
533 548
534 549 - namespace: an optional dict where completions are performed.
535 550
536 551 - global_namespace: secondary optional dict for completions, to
537 552 handle cases (such as IPython embedded inside functions) where
538 553 both Python scopes are visible.
539 554
540 555 use_readline : bool, optional
541 556 If true, use the readline library. This completer can still function
542 557 without readline, though in that case callers must provide some extra
543 558 information on each call about the current line."""
544 559
545 560 self.magic_escape = ESC_MAGIC
546 561 self.splitter = CompletionSplitter()
547 562
548 563 # Readline configuration, only used by the rlcompleter method.
549 564 if use_readline:
550 565 # We store the right version of readline so that later code
551 566 import IPython.utils.rlineimpl as readline
552 567 self.readline = readline
553 568 else:
554 569 self.readline = None
555 570
556 571 # _greedy_changed() depends on splitter and readline being defined:
557 572 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
558 573 config=config, **kwargs)
559 574
560 575 # List where completion matches will be stored
561 576 self.matches = []
562 577 self.shell = shell
563 578 # Regexp to split filenames with spaces in them
564 579 self.space_name_re = re.compile(r'([^\\] )')
565 580 # Hold a local ref. to glob.glob for speed
566 581 self.glob = glob.glob
567 582
568 583 # Determine if we are running on 'dumb' terminals, like (X)Emacs
569 584 # buffers, to avoid completion problems.
570 585 term = os.environ.get('TERM','xterm')
571 586 self.dumb_terminal = term in ['dumb','emacs']
572 587
573 588 # Special handling of backslashes needed in win32 platforms
574 589 if sys.platform == "win32":
575 590 self.clean_glob = self._clean_glob_win32
576 591 else:
577 592 self.clean_glob = self._clean_glob
578 593
579 594 #regexp to parse docstring for function signature
580 595 self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
581 596 self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
582 597 #use this if positional argument name is also needed
583 598 #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
584 599
585 600 # All active matcher routines for completion
586 601 self.matchers = [self.python_matches,
587 602 self.file_matches,
588 603 self.magic_matches,
589 604 self.python_func_kw_matches,
590 605 self.dict_key_matches,
591 606 ]
592 607
593 608 def all_completions(self, text):
594 609 """
595 610 Wrapper around the complete method for the benefit of emacs
596 611 and pydb.
597 612 """
598 613 return self.complete(text)[1]
599 614
600 615 def _clean_glob(self,text):
601 616 return self.glob("%s*" % text)
602 617
603 618 def _clean_glob_win32(self,text):
604 619 return [f.replace("\\","/")
605 620 for f in self.glob("%s*" % text)]
606 621
607 622 def file_matches(self, text):
608 623 """Match filenames, expanding ~USER type strings.
609 624
610 625 Most of the seemingly convoluted logic in this completer is an
611 626 attempt to handle filenames with spaces in them. And yet it's not
612 627 quite perfect, because Python's readline doesn't expose all of the
613 628 GNU readline details needed for this to be done correctly.
614 629
615 630 For a filename with a space in it, the printed completions will be
616 631 only the parts after what's already been typed (instead of the
617 632 full completions, as is normally done). I don't think with the
618 633 current (as of Python 2.3) Python readline it's possible to do
619 634 better."""
620 635
621 636 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
622 637
623 638 # chars that require escaping with backslash - i.e. chars
624 639 # that readline treats incorrectly as delimiters, but we
625 640 # don't want to treat as delimiters in filename matching
626 641 # when escaped with backslash
627 642 if text.startswith('!'):
628 643 text = text[1:]
629 644 text_prefix = '!'
630 645 else:
631 646 text_prefix = ''
632 647
633 648 text_until_cursor = self.text_until_cursor
634 649 # track strings with open quotes
635 650 open_quotes = has_open_quotes(text_until_cursor)
636 651
637 652 if '(' in text_until_cursor or '[' in text_until_cursor:
638 653 lsplit = text
639 654 else:
640 655 try:
641 656 # arg_split ~ shlex.split, but with unicode bugs fixed by us
642 657 lsplit = arg_split(text_until_cursor)[-1]
643 658 except ValueError:
644 659 # typically an unmatched ", or backslash without escaped char.
645 660 if open_quotes:
646 661 lsplit = text_until_cursor.split(open_quotes)[-1]
647 662 else:
648 663 return []
649 664 except IndexError:
650 665 # tab pressed on empty line
651 666 lsplit = ""
652 667
653 668 if not open_quotes and lsplit != protect_filename(lsplit):
654 669 # if protectables are found, do matching on the whole escaped name
655 670 has_protectables = True
656 671 text0,text = text,lsplit
657 672 else:
658 673 has_protectables = False
659 674 text = os.path.expanduser(text)
660 675
661 676 if text == "":
662 677 return [text_prefix + protect_filename(f) for f in self.glob("*")]
663 678
664 679 # Compute the matches from the filesystem
665 680 m0 = self.clean_glob(text.replace('\\',''))
666 681
667 682 if has_protectables:
668 683 # If we had protectables, we need to revert our changes to the
669 684 # beginning of filename so that we don't double-write the part
670 685 # of the filename we have so far
671 686 len_lsplit = len(lsplit)
672 687 matches = [text_prefix + text0 +
673 688 protect_filename(f[len_lsplit:]) for f in m0]
674 689 else:
675 690 if open_quotes:
676 691 # if we have a string with an open quote, we don't need to
677 692 # protect the names at all (and we _shouldn't_, as it
678 693 # would cause bugs when the filesystem call is made).
679 694 matches = m0
680 695 else:
681 696 matches = [text_prefix +
682 697 protect_filename(f) for f in m0]
683 698
684 699 #io.rprint('mm', matches) # dbg
685 700
686 701 # Mark directories in input list by appending '/' to their names.
687 702 matches = [x+'/' if os.path.isdir(x) else x for x in matches]
688 703 return matches
689 704
690 705 def magic_matches(self, text):
691 706 """Match magics"""
692 707 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
693 708 # Get all shell magics now rather than statically, so magics loaded at
694 709 # runtime show up too.
695 710 lsm = self.shell.magics_manager.lsmagic()
696 711 line_magics = lsm['line']
697 712 cell_magics = lsm['cell']
698 713 pre = self.magic_escape
699 714 pre2 = pre+pre
700 715
701 716 # Completion logic:
702 717 # - user gives %%: only do cell magics
703 718 # - user gives %: do both line and cell magics
704 719 # - no prefix: do both
705 720 # In other words, line magics are skipped if the user gives %% explicitly
706 721 bare_text = text.lstrip(pre)
707 722 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
708 723 if not text.startswith(pre2):
709 724 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
710 725 return comp
711 726
712 727 def python_matches(self,text):
713 728 """Match attributes or global python names"""
714 729
715 730 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
716 731 if "." in text:
717 732 try:
718 733 matches = self.attr_matches(text)
719 734 if text.endswith('.') and self.omit__names:
720 735 if self.omit__names == 1:
721 736 # true if txt is _not_ a __ name, false otherwise:
722 737 no__name = (lambda txt:
723 738 re.match(r'.*\.__.*?__',txt) is None)
724 739 else:
725 740 # true if txt is _not_ a _ name, false otherwise:
726 741 no__name = (lambda txt:
727 742 re.match(r'.*\._.*?',txt) is None)
728 743 matches = filter(no__name, matches)
729 744 except NameError:
730 745 # catches <undefined attributes>.<tab>
731 746 matches = []
732 747 else:
733 748 matches = self.global_matches(text)
734 749
735 750 return matches
736 751
737 752 def _default_arguments_from_docstring(self, doc):
738 753 """Parse the first line of docstring for call signature.
739 754
740 755 Docstring should be of the form 'min(iterable[, key=func])\n'.
741 756 It can also parse cython docstring of the form
742 757 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
743 758 """
744 759 if doc is None:
745 760 return []
746 761
747 762 #care only the firstline
748 763 line = doc.lstrip().splitlines()[0]
749 764
750 765 #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
751 766 #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
752 767 sig = self.docstring_sig_re.search(line)
753 768 if sig is None:
754 769 return []
755 770 # iterable[, key=func]' -> ['iterable[' ,' key=func]']
756 771 sig = sig.groups()[0].split(',')
757 772 ret = []
758 773 for s in sig:
759 774 #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
760 775 ret += self.docstring_kwd_re.findall(s)
761 776 return ret
762 777
763 778 def _default_arguments(self, obj):
764 779 """Return the list of default arguments of obj if it is callable,
765 780 or empty list otherwise."""
766 781 call_obj = obj
767 782 ret = []
768 783 if inspect.isbuiltin(obj):
769 784 pass
770 785 elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
771 786 if inspect.isclass(obj):
772 787 #for cython embededsignature=True the constructor docstring
773 788 #belongs to the object itself not __init__
774 789 ret += self._default_arguments_from_docstring(
775 790 getattr(obj, '__doc__', ''))
776 791 # for classes, check for __init__,__new__
777 792 call_obj = (getattr(obj, '__init__', None) or
778 793 getattr(obj, '__new__', None))
779 794 # for all others, check if they are __call__able
780 795 elif hasattr(obj, '__call__'):
781 796 call_obj = obj.__call__
782 797
783 798 ret += self._default_arguments_from_docstring(
784 799 getattr(call_obj, '__doc__', ''))
785 800
786 801 try:
787 802 args,_,_1,defaults = inspect.getargspec(call_obj)
788 803 if defaults:
789 804 ret+=args[-len(defaults):]
790 805 except TypeError:
791 806 pass
792 807
793 808 return list(set(ret))
794 809
795 810 def python_func_kw_matches(self,text):
796 811 """Match named parameters (kwargs) of the last open function"""
797 812
798 813 if "." in text: # a parameter cannot be dotted
799 814 return []
800 815 try: regexp = self.__funcParamsRegex
801 816 except AttributeError:
802 817 regexp = self.__funcParamsRegex = re.compile(r'''
803 818 '.*?(?<!\\)' | # single quoted strings or
804 819 ".*?(?<!\\)" | # double quoted strings or
805 820 \w+ | # identifier
806 821 \S # other characters
807 822 ''', re.VERBOSE | re.DOTALL)
808 823 # 1. find the nearest identifier that comes before an unclosed
809 824 # parenthesis before the cursor
810 825 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
811 826 tokens = regexp.findall(self.text_until_cursor)
812 827 tokens.reverse()
813 828 iterTokens = iter(tokens); openPar = 0
814 829
815 830 for token in iterTokens:
816 831 if token == ')':
817 832 openPar -= 1
818 833 elif token == '(':
819 834 openPar += 1
820 835 if openPar > 0:
821 836 # found the last unclosed parenthesis
822 837 break
823 838 else:
824 839 return []
825 840 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
826 841 ids = []
827 842 isId = re.compile(r'\w+$').match
828 843
829 844 while True:
830 845 try:
831 846 ids.append(next(iterTokens))
832 847 if not isId(ids[-1]):
833 848 ids.pop(); break
834 849 if not next(iterTokens) == '.':
835 850 break
836 851 except StopIteration:
837 852 break
838 853 # lookup the candidate callable matches either using global_matches
839 854 # or attr_matches for dotted names
840 855 if len(ids) == 1:
841 856 callableMatches = self.global_matches(ids[0])
842 857 else:
843 858 callableMatches = self.attr_matches('.'.join(ids[::-1]))
844 859 argMatches = []
845 860 for callableMatch in callableMatches:
846 861 try:
847 862 namedArgs = self._default_arguments(eval(callableMatch,
848 863 self.namespace))
849 864 except:
850 865 continue
851 866
852 867 for namedArg in namedArgs:
853 868 if namedArg.startswith(text):
854 869 argMatches.append("%s=" %namedArg)
855 870 return argMatches
856 871
857 872 def dict_key_matches(self, text):
858 873 def get_keys(obj):
859 if not callable(getattr(obj, '__getitem__', None)):
860 return []
861 if hasattr(obj, 'keys'):
874 # Only allow completion for known in-memory dict-like types
875 if isinstance(obj, KEYED_DICT_TYPES):
862 876 try:
863 877 return list(obj.keys())
864 878 except Exception:
865 879 return []
866 return getattr(getattr(obj, 'dtype', None), 'names', [])
880 elif isinstance(obj, STRUCT_ARRAY_TYPES):
881 return obj.dtype.names or []
882 return []
867 883
868 884 try:
869 885 regexps = self.__dict_key_regexps
870 886 except AttributeError:
871 887 dict_key_re_fmt = r'''(?x)
872 888 ( # match dict-referring expression wrt greedy setting
873 889 %s
874 890 )
875 891 \[ # open bracket
876 892 \s* # and optional whitespace
877 893 ([uUbB]? # string prefix (r not handled)
878 894 (?: # unclosed string
879 895 '(?:[^']|(?<!\\)\\')*
880 896 |
881 897 "(?:[^"]|(?<!\\)\\")*
882 898 )
883 899 )?
884 900 $
885 901 '''
886 902 regexps = self.__dict_key_regexps = {
887 903 False: re.compile(dict_key_re_fmt % '''
888 904 # identifiers separated by .
889 905 (?!\d)\w+
890 906 (?:\.(?!\d)\w+)*
891 907 '''),
892 908 True: re.compile(dict_key_re_fmt % '''
893 909 .+
894 910 ''')
895 911 }
896 912
897 913 match = regexps[self.greedy].search(self.text_until_cursor)
898 914 if match is None:
899 915 return []
900 916
901 917 expr, prefix = match.groups()
902 918 try:
903 919 obj = eval(expr, self.namespace)
904 920 except Exception:
905 921 try:
906 922 obj = eval(expr, self.global_namespace)
907 923 except Exception:
908 924 return []
909 925
910 926 keys = get_keys(obj)
911 927 if not keys:
912 928 return keys
913 929 closing_quote, matches = match_dict_keys(keys, prefix)
914 930
915 931 # append closing quote and bracket as appropriate
916 932 continuation = self.line_buffer[len(self.text_until_cursor):]
917 933 if closing_quote and continuation.startswith(closing_quote):
918 934 suf = ''
919 935 elif continuation.startswith(']'):
920 936 suf = closing_quote or ''
921 937 else:
922 938 suf = (closing_quote or '') + ']'
923 939 return [k + suf for k in matches]
924 940
925 941 def dispatch_custom_completer(self, text):
926 942 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
927 943 line = self.line_buffer
928 944 if not line.strip():
929 945 return None
930 946
931 947 # Create a little structure to pass all the relevant information about
932 948 # the current completion to any custom completer.
933 949 event = Bunch()
934 950 event.line = line
935 951 event.symbol = text
936 952 cmd = line.split(None,1)[0]
937 953 event.command = cmd
938 954 event.text_until_cursor = self.text_until_cursor
939 955
940 956 #print "\ncustom:{%s]\n" % event # dbg
941 957
942 958 # for foo etc, try also to find completer for %foo
943 959 if not cmd.startswith(self.magic_escape):
944 960 try_magic = self.custom_completers.s_matches(
945 961 self.magic_escape + cmd)
946 962 else:
947 963 try_magic = []
948 964
949 965 for c in itertools.chain(self.custom_completers.s_matches(cmd),
950 966 try_magic,
951 967 self.custom_completers.flat_matches(self.text_until_cursor)):
952 968 #print "try",c # dbg
953 969 try:
954 970 res = c(event)
955 971 if res:
956 972 # first, try case sensitive match
957 973 withcase = [r for r in res if r.startswith(text)]
958 974 if withcase:
959 975 return withcase
960 976 # if none, then case insensitive ones are ok too
961 977 text_low = text.lower()
962 978 return [r for r in res if r.lower().startswith(text_low)]
963 979 except TryNext:
964 980 pass
965 981
966 982 return None
967 983
968 984 def complete(self, text=None, line_buffer=None, cursor_pos=None):
969 985 """Find completions for the given text and line context.
970 986
971 987 This is called successively with state == 0, 1, 2, ... until it
972 988 returns None. The completion should begin with 'text'.
973 989
974 990 Note that both the text and the line_buffer are optional, but at least
975 991 one of them must be given.
976 992
977 993 Parameters
978 994 ----------
979 995 text : string, optional
980 996 Text to perform the completion on. If not given, the line buffer
981 997 is split using the instance's CompletionSplitter object.
982 998
983 999 line_buffer : string, optional
984 1000 If not given, the completer attempts to obtain the current line
985 1001 buffer via readline. This keyword allows clients which are
986 1002 requesting for text completions in non-readline contexts to inform
987 1003 the completer of the entire text.
988 1004
989 1005 cursor_pos : int, optional
990 1006 Index of the cursor in the full line buffer. Should be provided by
991 1007 remote frontends where kernel has no access to frontend state.
992 1008
993 1009 Returns
994 1010 -------
995 1011 text : str
996 1012 Text that was actually used in the completion.
997 1013
998 1014 matches : list
999 1015 A list of completion matches.
1000 1016 """
1001 1017 #io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1002 1018
1003 1019 # if the cursor position isn't given, the only sane assumption we can
1004 1020 # make is that it's at the end of the line (the common case)
1005 1021 if cursor_pos is None:
1006 1022 cursor_pos = len(line_buffer) if text is None else len(text)
1007 1023
1008 1024 # if text is either None or an empty string, rely on the line buffer
1009 1025 if not text:
1010 1026 text = self.splitter.split_line(line_buffer, cursor_pos)
1011 1027
1012 1028 # If no line buffer is given, assume the input text is all there was
1013 1029 if line_buffer is None:
1014 1030 line_buffer = text
1015 1031
1016 1032 self.line_buffer = line_buffer
1017 1033 self.text_until_cursor = self.line_buffer[:cursor_pos]
1018 1034 #io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
1019 1035
1020 1036 # Start with a clean slate of completions
1021 1037 self.matches[:] = []
1022 1038 custom_res = self.dispatch_custom_completer(text)
1023 1039 if custom_res is not None:
1024 1040 # did custom completers produce something?
1025 1041 self.matches = custom_res
1026 1042 else:
1027 1043 # Extend the list of completions with the results of each
1028 1044 # matcher, so we return results to the user from all
1029 1045 # namespaces.
1030 1046 if self.merge_completions:
1031 1047 self.matches = []
1032 1048 for matcher in self.matchers:
1033 1049 try:
1034 1050 self.matches.extend(matcher(text))
1035 1051 except:
1036 1052 # Show the ugly traceback if the matcher causes an
1037 1053 # exception, but do NOT crash the kernel!
1038 1054 sys.excepthook(*sys.exc_info())
1039 1055 else:
1040 1056 for matcher in self.matchers:
1041 1057 self.matches = matcher(text)
1042 1058 if self.matches:
1043 1059 break
1044 1060 # FIXME: we should extend our api to return a dict with completions for
1045 1061 # different types of objects. The rlcomplete() method could then
1046 1062 # simply collapse the dict into a list for readline, but we'd have
1047 1063 # richer completion semantics in other evironments.
1048 1064
1049 1065 # use penalize_magics_key to put magics after variables with same name
1050 1066 self.matches = sorted(set(self.matches), key=penalize_magics_key)
1051 1067
1052 1068 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
1053 1069 return text, self.matches
1054 1070
1055 1071 def rlcomplete(self, text, state):
1056 1072 """Return the state-th possible completion for 'text'.
1057 1073
1058 1074 This is called successively with state == 0, 1, 2, ... until it
1059 1075 returns None. The completion should begin with 'text'.
1060 1076
1061 1077 Parameters
1062 1078 ----------
1063 1079 text : string
1064 1080 Text to perform the completion on.
1065 1081
1066 1082 state : int
1067 1083 Counter used by readline.
1068 1084 """
1069 1085 if state==0:
1070 1086
1071 1087 self.line_buffer = line_buffer = self.readline.get_line_buffer()
1072 1088 cursor_pos = self.readline.get_endidx()
1073 1089
1074 1090 #io.rprint("\nRLCOMPLETE: %r %r %r" %
1075 1091 # (text, line_buffer, cursor_pos) ) # dbg
1076 1092
1077 1093 # if there is only a tab on a line with only whitespace, instead of
1078 1094 # the mostly useless 'do you want to see all million completions'
1079 1095 # message, just do the right thing and give the user his tab!
1080 1096 # Incidentally, this enables pasting of tabbed text from an editor
1081 1097 # (as long as autoindent is off).
1082 1098
1083 1099 # It should be noted that at least pyreadline still shows file
1084 1100 # completions - is there a way around it?
1085 1101
1086 1102 # don't apply this on 'dumb' terminals, such as emacs buffers, so
1087 1103 # we don't interfere with their own tab-completion mechanism.
1088 1104 if not (self.dumb_terminal or line_buffer.strip()):
1089 1105 self.readline.insert_text('\t')
1090 1106 sys.stdout.flush()
1091 1107 return None
1092 1108
1093 1109 # Note: debugging exceptions that may occur in completion is very
1094 1110 # tricky, because readline unconditionally silences them. So if
1095 1111 # during development you suspect a bug in the completion code, turn
1096 1112 # this flag on temporarily by uncommenting the second form (don't
1097 1113 # flip the value in the first line, as the '# dbg' marker can be
1098 1114 # automatically detected and is used elsewhere).
1099 1115 DEBUG = False
1100 1116 #DEBUG = True # dbg
1101 1117 if DEBUG:
1102 1118 try:
1103 1119 self.complete(text, line_buffer, cursor_pos)
1104 1120 except:
1105 1121 import traceback; traceback.print_exc()
1106 1122 else:
1107 1123 # The normal production version is here
1108 1124
1109 1125 # This method computes the self.matches array
1110 1126 self.complete(text, line_buffer, cursor_pos)
1111 1127
1112 1128 try:
1113 1129 return self.matches[state]
1114 1130 except IndexError:
1115 1131 return None
@@ -1,642 +1,627 b''
1 1 """Tests for the IPython tab-completion machinery.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Module imports
5 5 #-----------------------------------------------------------------------------
6 6
7 7 # stdlib
8 8 import os
9 9 import sys
10 10 import unittest
11 11
12 12 # third party
13 13 import nose.tools as nt
14 14
15 15 # our own packages
16 16 from IPython.config.loader import Config
17 17 from IPython.core import completer
18 18 from IPython.external.decorators import knownfailureif
19 19 from IPython.utils.tempdir import TemporaryDirectory
20 20 from IPython.utils.generics import complete_object
21 21 from IPython.utils import py3compat
22 22 from IPython.utils.py3compat import string_types, unicode_type
23 23 from IPython.testing import decorators as dec
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Test functions
27 27 #-----------------------------------------------------------------------------
28 28 def test_protect_filename():
29 29 pairs = [ ('abc','abc'),
30 30 (' abc',r'\ abc'),
31 31 ('a bc',r'a\ bc'),
32 32 ('a bc',r'a\ \ bc'),
33 33 (' bc',r'\ \ bc'),
34 34 ]
35 35 # On posix, we also protect parens and other special characters
36 36 if sys.platform != 'win32':
37 37 pairs.extend( [('a(bc',r'a\(bc'),
38 38 ('a)bc',r'a\)bc'),
39 39 ('a( )bc',r'a\(\ \)bc'),
40 40 ('a[1]bc', r'a\[1\]bc'),
41 41 ('a{1}bc', r'a\{1\}bc'),
42 42 ('a#bc', r'a\#bc'),
43 43 ('a?bc', r'a\?bc'),
44 44 ('a=bc', r'a\=bc'),
45 45 ('a\\bc', r'a\\bc'),
46 46 ('a|bc', r'a\|bc'),
47 47 ('a;bc', r'a\;bc'),
48 48 ('a:bc', r'a\:bc'),
49 49 ("a'bc", r"a\'bc"),
50 50 ('a*bc', r'a\*bc'),
51 51 ('a"bc', r'a\"bc'),
52 52 ('a^bc', r'a\^bc'),
53 53 ('a&bc', r'a\&bc'),
54 54 ] )
55 55 # run the actual tests
56 56 for s1, s2 in pairs:
57 57 s1p = completer.protect_filename(s1)
58 58 nt.assert_equal(s1p, s2)
59 59
60 60
61 61 def check_line_split(splitter, test_specs):
62 62 for part1, part2, split in test_specs:
63 63 cursor_pos = len(part1)
64 64 line = part1+part2
65 65 out = splitter.split_line(line, cursor_pos)
66 66 nt.assert_equal(out, split)
67 67
68 68
69 69 def test_line_split():
70 70 """Basic line splitter test with default specs."""
71 71 sp = completer.CompletionSplitter()
72 72 # The format of the test specs is: part1, part2, expected answer. Parts 1
73 73 # and 2 are joined into the 'line' sent to the splitter, as if the cursor
74 74 # was at the end of part1. So an empty part2 represents someone hitting
75 75 # tab at the end of the line, the most common case.
76 76 t = [('run some/scrip', '', 'some/scrip'),
77 77 ('run scripts/er', 'ror.py foo', 'scripts/er'),
78 78 ('echo $HOM', '', 'HOM'),
79 79 ('print sys.pa', '', 'sys.pa'),
80 80 ('print(sys.pa', '', 'sys.pa'),
81 81 ("execfile('scripts/er", '', 'scripts/er'),
82 82 ('a[x.', '', 'x.'),
83 83 ('a[x.', 'y', 'x.'),
84 84 ('cd "some_file/', '', 'some_file/'),
85 85 ]
86 86 check_line_split(sp, t)
87 87 # Ensure splitting works OK with unicode by re-running the tests with
88 88 # all inputs turned into unicode
89 89 check_line_split(sp, [ map(unicode_type, p) for p in t] )
90 90
91 91
92 92 def test_custom_completion_error():
93 93 """Test that errors from custom attribute completers are silenced."""
94 94 ip = get_ipython()
95 95 class A(object): pass
96 96 ip.user_ns['a'] = A()
97 97
98 98 @complete_object.when_type(A)
99 99 def complete_A(a, existing_completions):
100 100 raise TypeError("this should be silenced")
101 101
102 102 ip.complete("a.")
103 103
104 104
105 105 def test_unicode_completions():
106 106 ip = get_ipython()
107 107 # Some strings that trigger different types of completion. Check them both
108 108 # in str and unicode forms
109 109 s = ['ru', '%ru', 'cd /', 'floa', 'float(x)/']
110 110 for t in s + list(map(unicode_type, s)):
111 111 # We don't need to check exact completion values (they may change
112 112 # depending on the state of the namespace, but at least no exceptions
113 113 # should be thrown and the return value should be a pair of text, list
114 114 # values.
115 115 text, matches = ip.complete(t)
116 116 nt.assert_true(isinstance(text, string_types))
117 117 nt.assert_true(isinstance(matches, list))
118 118
119 119
120 120 class CompletionSplitterTestCase(unittest.TestCase):
121 121 def setUp(self):
122 122 self.sp = completer.CompletionSplitter()
123 123
124 124 def test_delim_setting(self):
125 125 self.sp.delims = ' '
126 126 nt.assert_equal(self.sp.delims, ' ')
127 127 nt.assert_equal(self.sp._delim_expr, '[\ ]')
128 128
129 129 def test_spaces(self):
130 130 """Test with only spaces as split chars."""
131 131 self.sp.delims = ' '
132 132 t = [('foo', '', 'foo'),
133 133 ('run foo', '', 'foo'),
134 134 ('run foo', 'bar', 'foo'),
135 135 ]
136 136 check_line_split(self.sp, t)
137 137
138 138
139 139 def test_has_open_quotes1():
140 140 for s in ["'", "'''", "'hi' '"]:
141 141 nt.assert_equal(completer.has_open_quotes(s), "'")
142 142
143 143
144 144 def test_has_open_quotes2():
145 145 for s in ['"', '"""', '"hi" "']:
146 146 nt.assert_equal(completer.has_open_quotes(s), '"')
147 147
148 148
149 149 def test_has_open_quotes3():
150 150 for s in ["''", "''' '''", "'hi' 'ipython'"]:
151 151 nt.assert_false(completer.has_open_quotes(s))
152 152
153 153
154 154 def test_has_open_quotes4():
155 155 for s in ['""', '""" """', '"hi" "ipython"']:
156 156 nt.assert_false(completer.has_open_quotes(s))
157 157
158 158
159 159 @knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows")
160 160 def test_abspath_file_completions():
161 161 ip = get_ipython()
162 162 with TemporaryDirectory() as tmpdir:
163 163 prefix = os.path.join(tmpdir, 'foo')
164 164 suffixes = ['1', '2']
165 165 names = [prefix+s for s in suffixes]
166 166 for n in names:
167 167 open(n, 'w').close()
168 168
169 169 # Check simple completion
170 170 c = ip.complete(prefix)[1]
171 171 nt.assert_equal(c, names)
172 172
173 173 # Now check with a function call
174 174 cmd = 'a = f("%s' % prefix
175 175 c = ip.complete(prefix, cmd)[1]
176 176 comp = [prefix+s for s in suffixes]
177 177 nt.assert_equal(c, comp)
178 178
179 179
180 180 def test_local_file_completions():
181 181 ip = get_ipython()
182 182 cwd = py3compat.getcwd()
183 183 try:
184 184 with TemporaryDirectory() as tmpdir:
185 185 os.chdir(tmpdir)
186 186 prefix = './foo'
187 187 suffixes = ['1', '2']
188 188 names = [prefix+s for s in suffixes]
189 189 for n in names:
190 190 open(n, 'w').close()
191 191
192 192 # Check simple completion
193 193 c = ip.complete(prefix)[1]
194 194 nt.assert_equal(c, names)
195 195
196 196 # Now check with a function call
197 197 cmd = 'a = f("%s' % prefix
198 198 c = ip.complete(prefix, cmd)[1]
199 199 comp = [prefix+s for s in suffixes]
200 200 nt.assert_equal(c, comp)
201 201 finally:
202 202 # prevent failures from making chdir stick
203 203 os.chdir(cwd)
204 204
205 205
206 206 def test_greedy_completions():
207 207 ip = get_ipython()
208 208 greedy_original = ip.Completer.greedy
209 209 try:
210 210 ip.Completer.greedy = False
211 211 ip.ex('a=list(range(5))')
212 212 _,c = ip.complete('.',line='a[0].')
213 213 nt.assert_false('a[0].real' in c,
214 214 "Shouldn't have completed on a[0]: %s"%c)
215 215 ip.Completer.greedy = True
216 216 _,c = ip.complete('.',line='a[0].')
217 217 nt.assert_true('a[0].real' in c, "Should have completed on a[0]: %s"%c)
218 218 finally:
219 219 ip.Completer.greedy = greedy_original
220 220
221 221
222 222 def test_omit__names():
223 223 # also happens to test IPCompleter as a configurable
224 224 ip = get_ipython()
225 225 ip._hidden_attr = 1
226 226 c = ip.Completer
227 227 ip.ex('ip=get_ipython()')
228 228 cfg = Config()
229 229 cfg.IPCompleter.omit__names = 0
230 230 c.update_config(cfg)
231 231 s,matches = c.complete('ip.')
232 232 nt.assert_in('ip.__str__', matches)
233 233 nt.assert_in('ip._hidden_attr', matches)
234 234 cfg.IPCompleter.omit__names = 1
235 235 c.update_config(cfg)
236 236 s,matches = c.complete('ip.')
237 237 nt.assert_not_in('ip.__str__', matches)
238 238 nt.assert_in('ip._hidden_attr', matches)
239 239 cfg.IPCompleter.omit__names = 2
240 240 c.update_config(cfg)
241 241 s,matches = c.complete('ip.')
242 242 nt.assert_not_in('ip.__str__', matches)
243 243 nt.assert_not_in('ip._hidden_attr', matches)
244 244 del ip._hidden_attr
245 245
246 246
247 247 def test_limit_to__all__False_ok():
248 248 ip = get_ipython()
249 249 c = ip.Completer
250 250 ip.ex('class D: x=24')
251 251 ip.ex('d=D()')
252 252 cfg = Config()
253 253 cfg.IPCompleter.limit_to__all__ = False
254 254 c.update_config(cfg)
255 255 s, matches = c.complete('d.')
256 256 nt.assert_in('d.x', matches)
257 257
258 258
259 259 def test_limit_to__all__True_ok():
260 260 ip = get_ipython()
261 261 c = ip.Completer
262 262 ip.ex('class D: x=24')
263 263 ip.ex('d=D()')
264 264 ip.ex("d.__all__=['z']")
265 265 cfg = Config()
266 266 cfg.IPCompleter.limit_to__all__ = True
267 267 c.update_config(cfg)
268 268 s, matches = c.complete('d.')
269 269 nt.assert_in('d.z', matches)
270 270 nt.assert_not_in('d.x', matches)
271 271
272 272
273 273 def test_get__all__entries_ok():
274 274 class A(object):
275 275 __all__ = ['x', 1]
276 276 words = completer.get__all__entries(A())
277 277 nt.assert_equal(words, ['x'])
278 278
279 279
280 280 def test_get__all__entries_no__all__ok():
281 281 class A(object):
282 282 pass
283 283 words = completer.get__all__entries(A())
284 284 nt.assert_equal(words, [])
285 285
286 286
287 287 def test_func_kw_completions():
288 288 ip = get_ipython()
289 289 c = ip.Completer
290 290 ip.ex('def myfunc(a=1,b=2): return a+b')
291 291 s, matches = c.complete(None, 'myfunc(1,b')
292 292 nt.assert_in('b=', matches)
293 293 # Simulate completing with cursor right after b (pos==10):
294 294 s, matches = c.complete(None, 'myfunc(1,b)', 10)
295 295 nt.assert_in('b=', matches)
296 296 s, matches = c.complete(None, 'myfunc(a="escaped\\")string",b')
297 297 nt.assert_in('b=', matches)
298 298 #builtin function
299 299 s, matches = c.complete(None, 'min(k, k')
300 300 nt.assert_in('key=', matches)
301 301
302 302
303 303 def test_default_arguments_from_docstring():
304 304 doc = min.__doc__
305 305 ip = get_ipython()
306 306 c = ip.Completer
307 307 kwd = c._default_arguments_from_docstring(
308 308 'min(iterable[, key=func]) -> value')
309 309 nt.assert_equal(kwd, ['key'])
310 310 #with cython type etc
311 311 kwd = c._default_arguments_from_docstring(
312 312 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
313 313 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
314 314 #white spaces
315 315 kwd = c._default_arguments_from_docstring(
316 316 '\n Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)\n')
317 317 nt.assert_equal(kwd, ['ncall', 'resume', 'nsplit'])
318 318
319 319 def test_line_magics():
320 320 ip = get_ipython()
321 321 c = ip.Completer
322 322 s, matches = c.complete(None, 'lsmag')
323 323 nt.assert_in('%lsmagic', matches)
324 324 s, matches = c.complete(None, '%lsmag')
325 325 nt.assert_in('%lsmagic', matches)
326 326
327 327
328 328 def test_cell_magics():
329 329 from IPython.core.magic import register_cell_magic
330 330
331 331 @register_cell_magic
332 332 def _foo_cellm(line, cell):
333 333 pass
334 334
335 335 ip = get_ipython()
336 336 c = ip.Completer
337 337
338 338 s, matches = c.complete(None, '_foo_ce')
339 339 nt.assert_in('%%_foo_cellm', matches)
340 340 s, matches = c.complete(None, '%%_foo_ce')
341 341 nt.assert_in('%%_foo_cellm', matches)
342 342
343 343
344 344 def test_line_cell_magics():
345 345 from IPython.core.magic import register_line_cell_magic
346 346
347 347 @register_line_cell_magic
348 348 def _bar_cellm(line, cell):
349 349 pass
350 350
351 351 ip = get_ipython()
352 352 c = ip.Completer
353 353
354 354 # The policy here is trickier, see comments in completion code. The
355 355 # returned values depend on whether the user passes %% or not explicitly,
356 356 # and this will show a difference if the same name is both a line and cell
357 357 # magic.
358 358 s, matches = c.complete(None, '_bar_ce')
359 359 nt.assert_in('%_bar_cellm', matches)
360 360 nt.assert_in('%%_bar_cellm', matches)
361 361 s, matches = c.complete(None, '%_bar_ce')
362 362 nt.assert_in('%_bar_cellm', matches)
363 363 nt.assert_in('%%_bar_cellm', matches)
364 364 s, matches = c.complete(None, '%%_bar_ce')
365 365 nt.assert_not_in('%_bar_cellm', matches)
366 366 nt.assert_in('%%_bar_cellm', matches)
367 367
368 368
369 369 def test_magic_completion_order():
370 370
371 371 ip = get_ipython()
372 372 c = ip.Completer
373 373
374 374 # Test ordering of magics and non-magics with the same name
375 375 # We want the non-magic first
376 376
377 377 # Before importing matplotlib, there should only be one option:
378 378
379 379 text, matches = c.complete('mat')
380 380 nt.assert_equal(matches, ["%matplotlib"])
381 381
382 382
383 383 ip.run_cell("matplotlib = 1") # introduce name into namespace
384 384
385 385 # After the import, there should be two options, ordered like this:
386 386 text, matches = c.complete('mat')
387 387 nt.assert_equal(matches, ["matplotlib", "%matplotlib"])
388 388
389 389
390 390 ip.run_cell("timeit = 1") # define a user variable called 'timeit'
391 391
392 392 # Order of user variable and line and cell magics with same name:
393 393 text, matches = c.complete('timeit')
394 394 nt.assert_equal(matches, ["timeit", "%timeit","%%timeit"])
395 395
396 396
397 397
398 398 def test_dict_key_completion_string():
399 399 """Test dictionary key completion for string keys"""
400 400 ip = get_ipython()
401 401 complete = ip.Completer.complete
402 402
403 403 ip.user_ns['d'] = {'abc': None}
404 404
405 405 # check completion at different stages
406 406 _, matches = complete(line_buffer="d[")
407 407 nt.assert_in("'abc']", matches)
408 408
409 409 _, matches = complete(line_buffer="d['")
410 410 nt.assert_in("abc']", matches)
411 411
412 412 _, matches = complete(line_buffer="d['a")
413 413 nt.assert_in("abc']", matches)
414 414
415 415 # check use of different quoting
416 416 _, matches = complete(line_buffer="d[\"")
417 417 nt.assert_in("abc\"]", matches)
418 418
419 419 _, matches = complete(line_buffer="d[\"a")
420 420 nt.assert_in("abc\"]", matches)
421 421
422 422 # check sensitivity to following context
423 423 _, matches = complete(line_buffer="d[]", cursor_pos=2)
424 424 nt.assert_in("'abc'", matches)
425 425
426 426 _, matches = complete(line_buffer="d['']", cursor_pos=3)
427 427 nt.assert_in("abc", matches)
428 428
429 429 # check multiple solutions are correctly returned and that noise is not
430 430 ip.user_ns['d'] = {'abc': None, 'abd': None, 'bad': None, object(): None,
431 431 5: None}
432 432
433 433 _, matches = complete(line_buffer="d['a")
434 434 nt.assert_in("abc']", matches)
435 435 nt.assert_in("abd']", matches)
436 436 nt.assert_not_in("bad']", matches)
437 437
438 438 # check escaping and whitespace
439 439 ip.user_ns['d'] = {'a\nb': None, 'a\'b': None, 'a"b': None, 'a word': None}
440 440 _, matches = complete(line_buffer="d['a")
441 441 nt.assert_in("a\\nb']", matches)
442 442 nt.assert_in("a\\'b']", matches)
443 443 nt.assert_in("a\"b']", matches)
444 444 nt.assert_in("a word']", matches)
445 445
446 446 # - can complete on non-initial word of the string
447 447 _, matches = complete(line_buffer="d['a w")
448 448 nt.assert_in("word']", matches)
449 449
450 450 # - understands quote escaping
451 451 _, matches = complete(line_buffer="d['a\\'")
452 452 nt.assert_in("b']", matches)
453 453
454 454 # - default quoting should work like repr
455 455 _, matches = complete(line_buffer="d[")
456 456 nt.assert_in("\"a'b\"]", matches)
457 457
458 458 # - when opening quote with ", possible to match with unescaped apostrophe
459 459 _, matches = complete(line_buffer="d[\"a'")
460 460 nt.assert_in("b\"]", matches)
461 461
462 462
463 463 def test_dict_key_completion_contexts():
464 464 """Test expression contexts in which dict key completion occurs"""
465 465 ip = get_ipython()
466 466 complete = ip.Completer.complete
467 467 d = {'abc': None}
468 468 ip.user_ns['d'] = d
469 469
470 470 class C:
471 471 data = d
472 472 ip.user_ns['C'] = C
473 473 ip.user_ns['get'] = lambda: d
474 474
475 475 def assert_no_completion(**kwargs):
476 476 _, matches = complete(**kwargs)
477 477 nt.assert_not_in('abc', matches)
478 478 nt.assert_not_in('abc\'', matches)
479 479 nt.assert_not_in('abc\']', matches)
480 480 nt.assert_not_in('\'abc\'', matches)
481 481 nt.assert_not_in('\'abc\']', matches)
482 482
483 483 def assert_completion(**kwargs):
484 484 _, matches = complete(**kwargs)
485 485 nt.assert_in("'abc']", matches)
486 486
487 487 # no completion after string closed, even if reopened
488 488 ip.Completer.greedy = False
489 489 assert_no_completion(line_buffer="d['a'")
490 490 assert_no_completion(line_buffer="d[\"a\"")
491 491 assert_no_completion(line_buffer="d['a' + ")
492 492 assert_no_completion(line_buffer="d['a' + '")
493 493
494 494 # completion in non-trivial expressions
495 495 assert_completion(line_buffer="+ d[")
496 496 assert_completion(line_buffer="(d[")
497 497 assert_completion(line_buffer="C.data[")
498 498
499 499 # greedy flag
500 500 assert_no_completion(line_buffer="get()[")
501 501 ip.Completer.greedy = True
502 502 assert_completion(line_buffer="get()[")
503 503
504 504
505 505
506 506 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
507 507 def test_dict_key_completion_bytes():
508 508 """Test handling of bytes in dict key completion"""
509 509 ip = get_ipython()
510 510 complete = ip.Completer.complete
511 511
512 512 ip.user_ns['d'] = {'abc': None, b'abd': None}
513 513
514 514 _, matches = complete(line_buffer="d[")
515 515 nt.assert_in("'abc']", matches)
516 516 nt.assert_in("b'abd']", matches)
517 517
518 518 if False: # not currently implemented
519 519 _, matches = complete(line_buffer="d[b")
520 520 nt.assert_in("b'abd']", matches)
521 521 nt.assert_not_in("b'abc']", matches)
522 522
523 523 _, matches = complete(line_buffer="d[b'")
524 524 nt.assert_in("abd']", matches)
525 525 nt.assert_not_in("abc']", matches)
526 526
527 527 _, matches = complete(line_buffer="d[B'")
528 528 nt.assert_in("abd']", matches)
529 529 nt.assert_not_in("abc']", matches)
530 530
531 531 _, matches = complete(line_buffer="d['")
532 532 nt.assert_in("abc']", matches)
533 533 nt.assert_not_in("abd']", matches)
534 534
535 535
536 536 @dec.onlyif(sys.version_info[0] < 3, 'This test only applies in Py<3')
537 537 def test_dict_key_completion_unicode_py2():
538 538 """Test handling of unicode in dict key completion"""
539 539 ip = get_ipython()
540 540 complete = ip.Completer.complete
541 541
542 542 ip.user_ns['d'] = {u'abc': None,
543 543 unicode_type('a\xd7\x90', 'utf8'): None}
544 544
545 545 _, matches = complete(line_buffer="d[")
546 546 nt.assert_in("u'abc']", matches)
547 547 nt.assert_in("u'a\\u05d0']", matches)
548 548
549 549 _, matches = complete(line_buffer="d['a")
550 550 nt.assert_in("abc']", matches)
551 551 nt.assert_not_in("a\\u05d0']", matches)
552 552
553 553 _, matches = complete(line_buffer="d[u'a")
554 554 nt.assert_in("abc']", matches)
555 555 nt.assert_in("a\\u05d0']", matches)
556 556
557 557 _, matches = complete(line_buffer="d[U'a")
558 558 nt.assert_in("abc']", matches)
559 559 nt.assert_in("a\\u05d0']", matches)
560 560
561 561 # query using escape
562 562 _, matches = complete(line_buffer="d[u'a\\u05d0")
563 563 nt.assert_in("u05d0']", matches) # tokenized after \\
564 564
565 565 # query using character
566 566 _, matches = complete(line_buffer=unicode_type("d[u'a\xd7\x90", 'utf8'))
567 567 nt.assert_in("']", matches)
568 568
569 569
570 570 @dec.onlyif(sys.version_info[0] >= 3, 'This test only applies in Py>=3')
571 571 def test_dict_key_completion_unicode_py3():
572 572 """Test handling of unicode in dict key completion"""
573 573 ip = get_ipython()
574 574 complete = ip.Completer.complete
575 575
576 576 ip.user_ns['d'] = {unicode_type(b'a\xd7\x90', 'utf8'): None}
577 577
578 578 # query using escape
579 579 _, matches = complete(line_buffer="d['a\\u05d0")
580 580 nt.assert_in("u05d0']", matches) # tokenized after \\
581 581
582 582 # query using character
583 583 _, matches = complete(line_buffer=unicode_type(b"d['a\xd7\x90", 'utf8'))
584 584 nt.assert_in(unicode_type(b"a\xd7\x90']", 'utf8'), matches)
585 585
586 586
587 def test_dict_like_key_completion():
588 """Test dict key completion applies where __getitem__ and keys exist"""
589 class D(object):
590 def __getitem__(self):
591 pass
592 def keys(self):
593 return iter(['hello', 'world'])
594 ip = get_ipython()
595 complete = ip.Completer.complete
596 ip.user_ns['d'] = D()
597 _, matches = complete(line_buffer="d['")
598 nt.assert_in("hello']", matches)
599 nt.assert_in("world']", matches)
600
601
602 587 @dec.skip_without('numpy')
603 588 def test_struct_array_key_completion():
604 589 """Test dict key completion applies to numpy struct arrays"""
605 590 import numpy
606 591 ip = get_ipython()
607 592 complete = ip.Completer.complete
608 593 ip.user_ns['d'] = numpy.array([], dtype=[('hello', 'f'), ('world', 'f')])
609 594 _, matches = complete(line_buffer="d['")
610 595 nt.assert_in("hello']", matches)
611 596 nt.assert_in("world']", matches)
612 597
613 598
614 599 @dec.skip_without('pandas')
615 600 def test_dataframe_key_completion():
616 601 """Test dict key completion applies to pandas DataFrames"""
617 602 import pandas
618 603 ip = get_ipython()
619 604 complete = ip.Completer.complete
620 605 ip.user_ns['d'] = pandas.DataFrame({'hello': [1], 'world': [2]})
621 606 _, matches = complete(line_buffer="d['")
622 607 nt.assert_in("hello']", matches)
623 608 nt.assert_in("world']", matches)
624 609
625 610
626 611 def test_dict_key_completion_invalids():
627 612 """Smoke test cases dict key completion can't handle"""
628 613 ip = get_ipython()
629 614 complete = ip.Completer.complete
630 615
631 616 ip.user_ns['no_getitem'] = None
632 617 ip.user_ns['no_keys'] = []
633 618 ip.user_ns['cant_call_keys'] = dict
634 619 ip.user_ns['empty'] = {}
635 620 ip.user_ns['d'] = {'abc': 5}
636 621
637 622 _, matches = complete(line_buffer="no_getitem['")
638 623 _, matches = complete(line_buffer="no_keys['")
639 624 _, matches = complete(line_buffer="cant_call_keys['")
640 625 _, matches = complete(line_buffer="empty['")
641 626 _, matches = complete(line_buffer="name_error['")
642 627 _, matches = complete(line_buffer="d['\\") # incomplete escape
General Comments 0
You need to be logged in to leave comments. Login now