##// END OF EJS Templates
catch all exceptions raised by attr_matches completer for expressions with dots
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,629 +1,633 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 ---------------------------------------------------------------------------
10 10 Original rlcompleter documentation:
11 11
12 12 This requires the latest extension to the readline module (the
13 13 completes keywords, built-ins and globals in __main__; when completing
14 14 NAME.NAME..., it evaluates (!) the expression up to the last dot and
15 15 completes its attributes.
16 16
17 17 It's very cool to do "import string" type "string.", hit the
18 18 completion key (twice), and see the list of names defined by the
19 19 string module!
20 20
21 21 Tip: to use the tab key as the completion key, call
22 22
23 23 readline.parse_and_bind("tab: complete")
24 24
25 25 Notes:
26 26
27 27 - Exceptions raised by the completer function are *ignored* (and
28 28 generally cause the completion to fail). This is a feature -- since
29 29 readline sets the tty device in raw (or cbreak) mode, printing a
30 30 traceback wouldn't work well without some complicated hoopla to save,
31 31 reset and restore the tty state.
32 32
33 33 - The evaluation of the NAME.NAME... form may cause arbitrary
34 34 application defined code to be executed if an object with a
35 35 __getattr__ hook is found. Since it is the responsibility of the
36 36 application (or the user) to enable this feature, I consider this an
37 37 acceptable risk. More complicated expressions (e.g. function calls or
38 38 indexing operations) are *not* evaluated.
39 39
40 40 - GNU readline is also used by the built-in functions input() and
41 41 raw_input(), and thus these also benefit/suffer from the completer
42 42 features. Clearly an interactive application can benefit by
43 43 specifying its own completer function and using raw_input() for all
44 44 its input.
45 45
46 46 - When the original stdin is not a tty device, GNU readline is never
47 47 used, and this module (and the readline module) are silently inactive.
48 48
49 49 """
50 50
51 51 #*****************************************************************************
52 52 #
53 53 # Since this file is essentially a minimally modified copy of the rlcompleter
54 54 # module which is part of the standard Python distribution, I assume that the
55 55 # proper procedure is to maintain its copyright as belonging to the Python
56 56 # Software Foundation (in addition to my own, for all new code).
57 57 #
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
60 60 #
61 61 # Distributed under the terms of the BSD License. The full license is in
62 62 # the file COPYING, distributed as part of this software.
63 63 #
64 64 #*****************************************************************************
65 65
66 66 import __builtin__
67 67 import __main__
68 68 import glob
69 69 import keyword
70 70 import os
71 71 import re
72 72 import shlex
73 73 import sys
74 74 import IPython.rlineimpl as readline
75 75 import itertools
76 76 from IPython.ipstruct import Struct
77 77 from IPython import ipapi
78 78
79 79 import types
80 80
81 81 # Python 2.4 offers sets as a builtin
82 82 try:
83 83 set([1,2])
84 84 except NameError:
85 85 from sets import Set as set
86 86
87 87 from IPython.genutils import debugx
88 88
89 89 __all__ = ['Completer','IPCompleter']
90 90
91 91 def get_class_members(cls):
92 92 ret = dir(cls)
93 93 if hasattr(cls,'__bases__'):
94 94 for base in cls.__bases__:
95 95 ret.extend(get_class_members(base))
96 96 return ret
97 97
98 98 class Completer:
99 99 def __init__(self,namespace=None,global_namespace=None):
100 100 """Create a new completer for the command line.
101 101
102 102 Completer([namespace,global_namespace]) -> completer instance.
103 103
104 104 If unspecified, the default namespace where completions are performed
105 105 is __main__ (technically, __main__.__dict__). Namespaces should be
106 106 given as dictionaries.
107 107
108 108 An optional second namespace can be given. This allows the completer
109 109 to handle cases where both the local and global scopes need to be
110 110 distinguished.
111 111
112 112 Completer instances should be used as the completion mechanism of
113 113 readline via the set_completer() call:
114 114
115 115 readline.set_completer(Completer(my_namespace).complete)
116 116 """
117 117
118 118 # some minimal strict typechecks. For some core data structures, I
119 119 # want actual basic python types, not just anything that looks like
120 120 # one. This is especially true for namespaces.
121 121 for ns in (namespace,global_namespace):
122 122 if ns is not None and type(ns) != types.DictType:
123 123 raise TypeError,'namespace must be a dictionary'
124 124
125 125 # Don't bind to namespace quite yet, but flag whether the user wants a
126 126 # specific namespace or to use __main__.__dict__. This will allow us
127 127 # to bind to __main__.__dict__ at completion time, not now.
128 128 if namespace is None:
129 129 self.use_main_ns = 1
130 130 else:
131 131 self.use_main_ns = 0
132 132 self.namespace = namespace
133 133
134 134 # The global namespace, if given, can be bound directly
135 135 if global_namespace is None:
136 136 self.global_namespace = {}
137 137 else:
138 138 self.global_namespace = global_namespace
139 139
140 140 def complete(self, text, state):
141 141 """Return the next possible completion for 'text'.
142 142
143 143 This is called successively with state == 0, 1, 2, ... until it
144 144 returns None. The completion should begin with 'text'.
145 145
146 146 """
147 147 if self.use_main_ns:
148 148 self.namespace = __main__.__dict__
149 149
150 150 if state == 0:
151 151 if "." in text:
152 152 self.matches = self.attr_matches(text)
153 153 else:
154 154 self.matches = self.global_matches(text)
155 155 try:
156 156 return self.matches[state]
157 157 except IndexError:
158 158 return None
159 159
160 160 def global_matches(self, text):
161 161 """Compute matches when text is a simple name.
162 162
163 163 Return a list of all keywords, built-in functions and names currently
164 164 defined in self.namespace or self.global_namespace that match.
165 165
166 166 """
167 167 matches = []
168 168 match_append = matches.append
169 169 n = len(text)
170 170 for lst in [keyword.kwlist,
171 171 __builtin__.__dict__.keys(),
172 172 self.namespace.keys(),
173 173 self.global_namespace.keys()]:
174 174 for word in lst:
175 175 if word[:n] == text and word != "__builtins__":
176 176 match_append(word)
177 177 return matches
178 178
179 179 def attr_matches(self, text):
180 180 """Compute matches when text contains a dot.
181 181
182 182 Assuming the text is of the form NAME.NAME....[NAME], and is
183 183 evaluatable in self.namespace or self.global_namespace, it will be
184 184 evaluated and its attributes (as revealed by dir()) are used as
185 185 possible completions. (For class instances, class members are are
186 186 also considered.)
187 187
188 188 WARNING: this can still invoke arbitrary C code, if an object
189 189 with a __getattr__ hook is evaluated.
190 190
191 191 """
192 192 import re
193 193
194 194 # Another option, seems to work great. Catches things like ''.<tab>
195 195 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
196 196
197 197 if not m:
198 198 return []
199 199
200 200 expr, attr = m.group(1, 3)
201 201 try:
202 202 object = eval(expr, self.namespace)
203 203 except:
204 object = eval(expr, self.global_namespace)
204 try:
205 object = eval(expr, self.global_namespace)
206 except:
207 return []
208
205 209
206 210 # Start building the attribute list via dir(), and then complete it
207 211 # with a few extra special-purpose calls.
208 212 words = dir(object)
209 213
210 214 if hasattr(object,'__class__'):
211 215 words.append('__class__')
212 216 words.extend(get_class_members(object.__class__))
213 217
214 218 # this is the 'dir' function for objects with Enthought's traits
215 219 if hasattr(object, 'trait_names'):
216 220 try:
217 221 words.extend(object.trait_names())
218 222 # eliminate possible duplicates, as some traits may also
219 223 # appear as normal attributes in the dir() call.
220 224 words = set(words)
221 225 except TypeError:
222 226 # This will happen if `object` is a class and not an instance.
223 227 pass
224 228
225 229 # Support for PyCrust-style _getAttributeNames magic method.
226 230 if hasattr(object, '_getAttributeNames'):
227 231 try:
228 232 words.extend(object._getAttributeNames())
229 233 # Eliminate duplicates.
230 234 words = set(words)
231 235 except TypeError:
232 236 # `object` is a class and not an instance. Ignore
233 237 # this error.
234 238 pass
235 239
236 240 # filter out non-string attributes which may be stuffed by dir() calls
237 241 # and poor coding in third-party modules
238 242 words = [w for w in words
239 243 if isinstance(w, basestring) and w != "__builtins__"]
240 244 # Build match list to return
241 245 n = len(attr)
242 246 return ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
243 247
244 248 class IPCompleter(Completer):
245 249 """Extension of the completer class with IPython-specific features"""
246 250
247 251 def __init__(self,shell,namespace=None,global_namespace=None,
248 252 omit__names=0,alias_table=None):
249 253 """IPCompleter() -> completer
250 254
251 255 Return a completer object suitable for use by the readline library
252 256 via readline.set_completer().
253 257
254 258 Inputs:
255 259
256 260 - shell: a pointer to the ipython shell itself. This is needed
257 261 because this completer knows about magic functions, and those can
258 262 only be accessed via the ipython instance.
259 263
260 264 - namespace: an optional dict where completions are performed.
261 265
262 266 - global_namespace: secondary optional dict for completions, to
263 267 handle cases (such as IPython embedded inside functions) where
264 268 both Python scopes are visible.
265 269
266 270 - The optional omit__names parameter sets the completer to omit the
267 271 'magic' names (__magicname__) for python objects unless the text
268 272 to be completed explicitly starts with one or more underscores.
269 273
270 274 - If alias_table is supplied, it should be a dictionary of aliases
271 275 to complete. """
272 276
273 277 Completer.__init__(self,namespace,global_namespace)
274 278 self.magic_prefix = shell.name+'.magic_'
275 279 self.magic_escape = shell.ESC_MAGIC
276 280 self.readline = readline
277 281 delims = self.readline.get_completer_delims()
278 282 delims = delims.replace(self.magic_escape,'')
279 283 self.readline.set_completer_delims(delims)
280 284 self.get_line_buffer = self.readline.get_line_buffer
281 285 self.omit__names = omit__names
282 286 self.merge_completions = shell.rc.readline_merge_completions
283 287
284 288 if alias_table is None:
285 289 alias_table = {}
286 290 self.alias_table = alias_table
287 291 # Regexp to split filenames with spaces in them
288 292 self.space_name_re = re.compile(r'([^\\] )')
289 293 # Hold a local ref. to glob.glob for speed
290 294 self.glob = glob.glob
291 295
292 296 # Determine if we are running on 'dumb' terminals, like (X)Emacs
293 297 # buffers, to avoid completion problems.
294 298 term = os.environ.get('TERM','xterm')
295 299 self.dumb_terminal = term in ['dumb','emacs']
296 300
297 301 # Special handling of backslashes needed in win32 platforms
298 302 if sys.platform == "win32":
299 303 self.clean_glob = self._clean_glob_win32
300 304 else:
301 305 self.clean_glob = self._clean_glob
302 306 self.matchers = [self.python_matches,
303 307 self.file_matches,
304 308 self.alias_matches,
305 309 self.python_func_kw_matches]
306 310
307 311 # Code contributed by Alex Schmolck, for ipython/emacs integration
308 312 def all_completions(self, text):
309 313 """Return all possible completions for the benefit of emacs."""
310 314
311 315 completions = []
312 316 comp_append = completions.append
313 317 try:
314 318 for i in xrange(sys.maxint):
315 319 res = self.complete(text, i)
316 320
317 321 if not res: break
318 322
319 323 comp_append(res)
320 324 #XXX workaround for ``notDefined.<tab>``
321 325 except NameError:
322 326 pass
323 327 return completions
324 328 # /end Alex Schmolck code.
325 329
326 330 def _clean_glob(self,text):
327 331 return self.glob("%s*" % text)
328 332
329 333 def _clean_glob_win32(self,text):
330 334 return [f.replace("\\","/")
331 335 for f in self.glob("%s*" % text)]
332 336
333 337 def file_matches(self, text):
334 338 """Match filneames, expanding ~USER type strings.
335 339
336 340 Most of the seemingly convoluted logic in this completer is an
337 341 attempt to handle filenames with spaces in them. And yet it's not
338 342 quite perfect, because Python's readline doesn't expose all of the
339 343 GNU readline details needed for this to be done correctly.
340 344
341 345 For a filename with a space in it, the printed completions will be
342 346 only the parts after what's already been typed (instead of the
343 347 full completions, as is normally done). I don't think with the
344 348 current (as of Python 2.3) Python readline it's possible to do
345 349 better."""
346 350
347 351 #print 'Completer->file_matches: <%s>' % text # dbg
348 352
349 353 # chars that require escaping with backslash - i.e. chars
350 354 # that readline treats incorrectly as delimiters, but we
351 355 # don't want to treat as delimiters in filename matching
352 356 # when escaped with backslash
353 357
354 358 protectables = ' ()[]{}'
355 359
356 360 def protect_filename(s):
357 361 return "".join([(ch in protectables and '\\' + ch or ch)
358 362 for ch in s])
359 363
360 364 lbuf = self.lbuf
361 365 open_quotes = 0 # track strings with open quotes
362 366 try:
363 367 lsplit = shlex.split(lbuf)[-1]
364 368 except ValueError:
365 369 # typically an unmatched ", or backslash without escaped char.
366 370 if lbuf.count('"')==1:
367 371 open_quotes = 1
368 372 lsplit = lbuf.split('"')[-1]
369 373 elif lbuf.count("'")==1:
370 374 open_quotes = 1
371 375 lsplit = lbuf.split("'")[-1]
372 376 else:
373 377 return None
374 378 except IndexError:
375 379 # tab pressed on empty line
376 380 lsplit = ""
377 381
378 382 if lsplit != protect_filename(lsplit):
379 383 # if protectables are found, do matching on the whole escaped
380 384 # name
381 385 has_protectables = 1
382 386 text0,text = text,lsplit
383 387 else:
384 388 has_protectables = 0
385 389 text = os.path.expanduser(text)
386 390
387 391 if text == "":
388 392 return [protect_filename(f) for f in self.glob("*")]
389 393
390 394 m0 = self.clean_glob(text.replace('\\',''))
391 395 if has_protectables:
392 396 # If we had protectables, we need to revert our changes to the
393 397 # beginning of filename so that we don't double-write the part
394 398 # of the filename we have so far
395 399 len_lsplit = len(lsplit)
396 400 matches = [text0 + protect_filename(f[len_lsplit:]) for f in m0]
397 401 else:
398 402 if open_quotes:
399 403 # if we have a string with an open quote, we don't need to
400 404 # protect the names at all (and we _shouldn't_, as it
401 405 # would cause bugs when the filesystem call is made).
402 406 matches = m0
403 407 else:
404 408 matches = [protect_filename(f) for f in m0]
405 409 if len(matches) == 1 and os.path.isdir(matches[0]):
406 410 # Takes care of links to directories also. Use '/'
407 411 # explicitly, even under Windows, so that name completions
408 412 # don't end up escaped.
409 413 pjoin = os.path.join
410 414 d = matches[0]
411 415 matches = [ pjoin(d,p) for p in os.listdir(d) ]
412 416 return matches
413 417
414 418 def alias_matches(self, text):
415 419 """Match internal system aliases"""
416 420 #print 'Completer->alias_matches:',text,'lb',self.lbuf # dbg
417 421
418 422 # if we are not in the first 'item', alias matching
419 423 # doesn't make sense
420 424 if ' ' in self.lbuf:
421 425 return []
422 426 text = os.path.expanduser(text)
423 427 aliases = self.alias_table.keys()
424 428 if text == "":
425 429 return aliases
426 430 else:
427 431 return [alias for alias in aliases if alias.startswith(text)]
428 432
429 433 def python_matches(self,text):
430 434 """Match attributes or global python names"""
431 435
432 436 #print 'Completer->python_matches, txt=<%s>' % text # dbg
433 437 if "." in text:
434 438 try:
435 439 matches = self.attr_matches(text)
436 440 if text.endswith('.') and self.omit__names:
437 441 if self.omit__names == 1:
438 442 # true if txt is _not_ a __ name, false otherwise:
439 443 no__name = (lambda txt:
440 444 re.match(r'.*\.__.*?__',txt) is None)
441 445 else:
442 446 # true if txt is _not_ a _ name, false otherwise:
443 447 no__name = (lambda txt:
444 448 re.match(r'.*\._.*?',txt) is None)
445 449 matches = filter(no__name, matches)
446 450 except NameError:
447 451 # catches <undefined attributes>.<tab>
448 452 matches = []
449 453 else:
450 454 matches = self.global_matches(text)
451 455 # this is so completion finds magics when automagic is on:
452 456 if (matches == [] and
453 457 not text.startswith(os.sep) and
454 458 not ' ' in self.lbuf):
455 459 matches = self.attr_matches(self.magic_prefix+text)
456 460 return matches
457 461
458 462 def _default_arguments(self, obj):
459 463 """Return the list of default arguments of obj if it is callable,
460 464 or empty list otherwise."""
461 465
462 466 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
463 467 # for classes, check for __init__,__new__
464 468 if inspect.isclass(obj):
465 469 obj = (getattr(obj,'__init__',None) or
466 470 getattr(obj,'__new__',None))
467 471 # for all others, check if they are __call__able
468 472 elif hasattr(obj, '__call__'):
469 473 obj = obj.__call__
470 474 # XXX: is there a way to handle the builtins ?
471 475 try:
472 476 args,_,_1,defaults = inspect.getargspec(obj)
473 477 if defaults:
474 478 return args[-len(defaults):]
475 479 except TypeError: pass
476 480 return []
477 481
478 482 def python_func_kw_matches(self,text):
479 483 """Match named parameters (kwargs) of the last open function"""
480 484
481 485 if "." in text: # a parameter cannot be dotted
482 486 return []
483 487 try: regexp = self.__funcParamsRegex
484 488 except AttributeError:
485 489 regexp = self.__funcParamsRegex = re.compile(r'''
486 490 '.*?' | # single quoted strings or
487 491 ".*?" | # double quoted strings or
488 492 \w+ | # identifier
489 493 \S # other characters
490 494 ''', re.VERBOSE | re.DOTALL)
491 495 # 1. find the nearest identifier that comes before an unclosed
492 496 # parenthesis e.g. for "foo (1+bar(x), pa", the candidate is "foo"
493 497 tokens = regexp.findall(self.get_line_buffer())
494 498 tokens.reverse()
495 499 iterTokens = iter(tokens); openPar = 0
496 500 for token in iterTokens:
497 501 if token == ')':
498 502 openPar -= 1
499 503 elif token == '(':
500 504 openPar += 1
501 505 if openPar > 0:
502 506 # found the last unclosed parenthesis
503 507 break
504 508 else:
505 509 return []
506 510 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
507 511 ids = []
508 512 isId = re.compile(r'\w+$').match
509 513 while True:
510 514 try:
511 515 ids.append(iterTokens.next())
512 516 if not isId(ids[-1]):
513 517 ids.pop(); break
514 518 if not iterTokens.next() == '.':
515 519 break
516 520 except StopIteration:
517 521 break
518 522 # lookup the candidate callable matches either using global_matches
519 523 # or attr_matches for dotted names
520 524 if len(ids) == 1:
521 525 callableMatches = self.global_matches(ids[0])
522 526 else:
523 527 callableMatches = self.attr_matches('.'.join(ids[::-1]))
524 528 argMatches = []
525 529 for callableMatch in callableMatches:
526 530 try: namedArgs = self._default_arguments(eval(callableMatch,
527 531 self.namespace))
528 532 except: continue
529 533 for namedArg in namedArgs:
530 534 if namedArg.startswith(text):
531 535 argMatches.append("%s=" %namedArg)
532 536 return argMatches
533 537
534 538 def dispatch_custom_completer(self,text):
535 539 # print "Custom! '%s' %s" % (text, self.custom_completers) # dbg
536 540 line = self.full_lbuf
537 541 if not line.strip():
538 542 return None
539 543
540 544 event = Struct()
541 545 event.line = line
542 546 event.symbol = text
543 547 cmd = line.split(None,1)[0]
544 548 event.command = cmd
545 549 #print "\ncustom:{%s]\n" % event # dbg
546 550
547 551 # for foo etc, try also to find completer for %foo
548 552 if not cmd.startswith(self.magic_escape):
549 553 try_magic = self.custom_completers.s_matches(
550 554 self.magic_escape + cmd)
551 555 else:
552 556 try_magic = []
553 557
554 558
555 559 for c in itertools.chain(
556 560 self.custom_completers.s_matches(cmd),
557 561 try_magic,
558 562 self.custom_completers.flat_matches(self.lbuf)):
559 563 # print "try",c # dbg
560 564 try:
561 565 res = c(event)
562 566 return [r for r in res if r.lower().startswith(text.lower())]
563 567 except ipapi.TryNext:
564 568 pass
565 569
566 570 return None
567 571
568 572
569 573
570 574 def complete(self, text, state):
571 575 """Return the next possible completion for 'text'.
572 576
573 577 This is called successively with state == 0, 1, 2, ... until it
574 578 returns None. The completion should begin with 'text'. """
575 579
576 580 #print '\n*** COMPLETE: <%s> (%s)' % (text,state) # dbg
577 581
578 582 # if there is only a tab on a line with only whitespace, instead
579 583 # of the mostly useless 'do you want to see all million
580 584 # completions' message, just do the right thing and give the user
581 585 # his tab! Incidentally, this enables pasting of tabbed text from
582 586 # an editor (as long as autoindent is off).
583 587
584 588 # don't apply this on 'dumb' terminals, such as emacs buffers, so we
585 589 # don't interfere with their own tab-completion mechanism.
586 590 self.full_lbuf = self.get_line_buffer()
587 591 self.lbuf = self.full_lbuf[:self.readline.get_endidx()]
588 592 if not (self.dumb_terminal or self.get_line_buffer().strip()):
589 593 self.readline.insert_text('\t')
590 594 return None
591 595
592 596
593 597 magic_escape = self.magic_escape
594 598 magic_prefix = self.magic_prefix
595 599
596 600 try:
597 601 if text.startswith(magic_escape):
598 602 text = text.replace(magic_escape,magic_prefix)
599 603 elif text.startswith('~'):
600 604 text = os.path.expanduser(text)
601 605 if state == 0:
602 606 custom_res = self.dispatch_custom_completer(text)
603 607 if custom_res is not None:
604 608 # did custom completers produce something?
605 609 self.matches = custom_res
606 610 else:
607 611 # Extend the list of completions with the results of each
608 612 # matcher, so we return results to the user from all
609 613 # namespaces.
610 614 if self.merge_completions:
611 615 self.matches = []
612 616 for matcher in self.matchers:
613 617 self.matches.extend(matcher(text))
614 618 else:
615 619 for matcher in self.matchers:
616 620 self.matches = matcher(text)
617 621 if self.matches:
618 622 break
619 623
620 624 try:
621 625 return self.matches[state].replace(magic_prefix,magic_escape)
622 626 except IndexError:
623 627 return None
624 628 except:
625 629 from IPython.ultraTB import AutoFormattedTB; # dbg
626 630 tb=AutoFormattedTB('Verbose');tb() #dbg
627 631
628 632 # If completion fails, don't annoy the user.
629 633 return None
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now