Home | History | Annotate | Download | only in Lib
      1 """Word completion for GNU readline.
      2 
      3 The completer completes keywords, built-ins and globals in a selectable
      4 namespace (which defaults to __main__); when completing NAME.NAME..., it
      5 evaluates (!) the expression up to the last dot and completes its attributes.
      6 
      7 It's very cool to do "import sys" type "sys.", hit the completion key (twice),
      8 and see the list of names defined by the sys module!
      9 
     10 Tip: to use the tab key as the completion key, call
     11 
     12     readline.parse_and_bind("tab: complete")
     13 
     14 Notes:
     15 
     16 - Exceptions raised by the completer function are *ignored* (and generally cause
     17   the completion to fail).  This is a feature -- since readline sets the tty
     18   device in raw (or cbreak) mode, printing a traceback wouldn't work well
     19   without some complicated hoopla to save, reset and restore the tty state.
     20 
     21 - The evaluation of the NAME.NAME... form may cause arbitrary application
     22   defined code to be executed if an object with a __getattr__ hook is found.
     23   Since it is the responsibility of the application (or the user) to enable this
     24   feature, I consider this an acceptable risk.  More complicated expressions
     25   (e.g. function calls or indexing operations) are *not* evaluated.
     26 
     27 - When the original stdin is not a tty device, GNU readline is never
     28   used, and this module (and the readline module) are silently inactive.
     29 
     30 """
     31 
     32 import atexit
     33 import builtins
     34 import __main__
     35 
     36 __all__ = ["Completer"]
     37 
     38 class Completer:
     39     def __init__(self, namespace = None):
     40         """Create a new completer for the command line.
     41 
     42         Completer([namespace]) -> completer instance.
     43 
     44         If unspecified, the default namespace where completions are performed
     45         is __main__ (technically, __main__.__dict__). Namespaces should be
     46         given as dictionaries.
     47 
     48         Completer instances should be used as the completion mechanism of
     49         readline via the set_completer() call:
     50 
     51         readline.set_completer(Completer(my_namespace).complete)
     52         """
     53 
     54         if namespace and not isinstance(namespace, dict):
     55             raise TypeError('namespace must be a dictionary')
     56 
     57         # Don't bind to namespace quite yet, but flag whether the user wants a
     58         # specific namespace or to use __main__.__dict__. This will allow us
     59         # to bind to __main__.__dict__ at completion time, not now.
     60         if namespace is None:
     61             self.use_main_ns = 1
     62         else:
     63             self.use_main_ns = 0
     64             self.namespace = namespace
     65 
     66     def complete(self, text, state):
     67         """Return the next possible completion for 'text'.
     68 
     69         This is called successively with state == 0, 1, 2, ... until it
     70         returns None.  The completion should begin with 'text'.
     71 
     72         """
     73         if self.use_main_ns:
     74             self.namespace = __main__.__dict__
     75 
     76         if not text.strip():
     77             if state == 0:
     78                 if _readline_available:
     79                     readline.insert_text('\t')
     80                     readline.redisplay()
     81                     return ''
     82                 else:
     83                     return '\t'
     84             else:
     85                 return None
     86 
     87         if state == 0:
     88             if "." in text:
     89                 self.matches = self.attr_matches(text)
     90             else:
     91                 self.matches = self.global_matches(text)
     92         try:
     93             return self.matches[state]
     94         except IndexError:
     95             return None
     96 
     97     def _callable_postfix(self, val, word):
     98         if callable(val):
     99             word = word + "("
    100         return word
    101 
    102     def global_matches(self, text):
    103         """Compute matches when text is a simple name.
    104 
    105         Return a list of all keywords, built-in functions and names currently
    106         defined in self.namespace that match.
    107 
    108         """
    109         import keyword
    110         matches = []
    111         seen = {"__builtins__"}
    112         n = len(text)
    113         for word in keyword.kwlist:
    114             if word[:n] == text:
    115                 seen.add(word)
    116                 if word in {'finally', 'try'}:
    117                     word = word + ':'
    118                 elif word not in {'False', 'None', 'True',
    119                                   'break', 'continue', 'pass',
    120                                   'else'}:
    121                     word = word + ' '
    122                 matches.append(word)
    123         for nspace in [self.namespace, builtins.__dict__]:
    124             for word, val in nspace.items():
    125                 if word[:n] == text and word not in seen:
    126                     seen.add(word)
    127                     matches.append(self._callable_postfix(val, word))
    128         return matches
    129 
    130     def attr_matches(self, text):
    131         """Compute matches when text contains a dot.
    132 
    133         Assuming the text is of the form NAME.NAME....[NAME], and is
    134         evaluable in self.namespace, it will be evaluated and its attributes
    135         (as revealed by dir()) are used as possible completions.  (For class
    136         instances, class members are also considered.)
    137 
    138         WARNING: this can still invoke arbitrary C code, if an object
    139         with a __getattr__ hook is evaluated.
    140 
    141         """
    142         import re
    143         m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
    144         if not m:
    145             return []
    146         expr, attr = m.group(1, 3)
    147         try:
    148             thisobject = eval(expr, self.namespace)
    149         except Exception:
    150             return []
    151 
    152         # get the content of the object, except __builtins__
    153         words = set(dir(thisobject))
    154         words.discard("__builtins__")
    155 
    156         if hasattr(thisobject, '__class__'):
    157             words.add('__class__')
    158             words.update(get_class_members(thisobject.__class__))
    159         matches = []
    160         n = len(attr)
    161         if attr == '':
    162             noprefix = '_'
    163         elif attr == '_':
    164             noprefix = '__'
    165         else:
    166             noprefix = None
    167         while True:
    168             for word in words:
    169                 if (word[:n] == attr and
    170                     not (noprefix and word[:n+1] == noprefix)):
    171                     match = "%s.%s" % (expr, word)
    172                     try:
    173                         val = getattr(thisobject, word)
    174                     except Exception:
    175                         pass  # Include even if attribute not set
    176                     else:
    177                         match = self._callable_postfix(val, match)
    178                     matches.append(match)
    179             if matches or not noprefix:
    180                 break
    181             if noprefix == '_':
    182                 noprefix = '__'
    183             else:
    184                 noprefix = None
    185         matches.sort()
    186         return matches
    187 
    188 def get_class_members(klass):
    189     ret = dir(klass)
    190     if hasattr(klass,'__bases__'):
    191         for base in klass.__bases__:
    192             ret = ret + get_class_members(base)
    193     return ret
    194 
    195 try:
    196     import readline
    197 except ImportError:
    198     _readline_available = False
    199 else:
    200     readline.set_completer(Completer().complete)
    201     # Release references early at shutdown (the readline module's
    202     # contents are quasi-immortal, and the completer function holds a
    203     # reference to globals).
    204     atexit.register(lambda: readline.set_completer(None))
    205     _readline_available = True
    206