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