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