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