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