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