1"""Word completion for GNU readline. 2 3The completer completes keywords, built-ins and globals in a selectable 4namespace (which defaults to __main__); when completing NAME.NAME..., it 5evaluates (!) the expression up to the last dot and completes its attributes. 6 7It's very cool to do "import sys" type "sys.", hit the completion key (twice), 8and see the list of names defined by the sys module! 9 10Tip: to use the tab key as the completion key, call 11 12 readline.parse_and_bind("tab: complete") 13 14Notes: 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 32import atexit 33import builtins 34import inspect 35import __main__ 36 37__all__ = ["Completer"] 38 39class Completer: 40 def __init__(self, namespace = None): 41 """Create a new completer for the command line. 42 43 Completer([namespace]) -> completer instance. 44 45 If unspecified, the default namespace where completions are performed 46 is __main__ (technically, __main__.__dict__). Namespaces should be 47 given as dictionaries. 48 49 Completer instances should be used as the completion mechanism of 50 readline via the set_completer() call: 51 52 readline.set_completer(Completer(my_namespace).complete) 53 """ 54 55 if namespace and not isinstance(namespace, dict): 56 raise TypeError('namespace must be a dictionary') 57 58 # Don't bind to namespace quite yet, but flag whether the user wants a 59 # specific namespace or to use __main__.__dict__. This will allow us 60 # to bind to __main__.__dict__ at completion time, not now. 61 if namespace is None: 62 self.use_main_ns = 1 63 else: 64 self.use_main_ns = 0 65 self.namespace = namespace 66 67 def complete(self, text, state): 68 """Return the next possible completion for 'text'. 69 70 This is called successively with state == 0, 1, 2, ... until it 71 returns None. The completion should begin with 'text'. 72 73 """ 74 if self.use_main_ns: 75 self.namespace = __main__.__dict__ 76 77 if not text.strip(): 78 if state == 0: 79 if _readline_available: 80 readline.insert_text('\t') 81 readline.redisplay() 82 return '' 83 else: 84 return '\t' 85 else: 86 return None 87 88 if state == 0: 89 if "." in text: 90 self.matches = self.attr_matches(text) 91 else: 92 self.matches = self.global_matches(text) 93 try: 94 return self.matches[state] 95 except IndexError: 96 return None 97 98 def _callable_postfix(self, val, word): 99 if callable(val): 100 word += "(" 101 try: 102 if not inspect.signature(val).parameters: 103 word += ")" 104 except ValueError: 105 pass 106 107 return word 108 109 def global_matches(self, text): 110 """Compute matches when text is a simple name. 111 112 Return a list of all keywords, built-in functions and names currently 113 defined in self.namespace that match. 114 115 """ 116 import keyword 117 matches = [] 118 seen = {"__builtins__"} 119 n = len(text) 120 for word in keyword.kwlist: 121 if word[:n] == text: 122 seen.add(word) 123 if word in {'finally', 'try'}: 124 word = word + ':' 125 elif word not in {'False', 'None', 'True', 126 'break', 'continue', 'pass', 127 'else'}: 128 word = word + ' ' 129 matches.append(word) 130 for nspace in [self.namespace, builtins.__dict__]: 131 for word, val in nspace.items(): 132 if word[:n] == text and word not in seen: 133 seen.add(word) 134 matches.append(self._callable_postfix(val, word)) 135 return matches 136 137 def attr_matches(self, text): 138 """Compute matches when text contains a dot. 139 140 Assuming the text is of the form NAME.NAME....[NAME], and is 141 evaluable in self.namespace, it will be evaluated and its attributes 142 (as revealed by dir()) are used as possible completions. (For class 143 instances, class members are also considered.) 144 145 WARNING: this can still invoke arbitrary C code, if an object 146 with a __getattr__ hook is evaluated. 147 148 """ 149 import re 150 m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) 151 if not m: 152 return [] 153 expr, attr = m.group(1, 3) 154 try: 155 thisobject = eval(expr, self.namespace) 156 except Exception: 157 return [] 158 159 # get the content of the object, except __builtins__ 160 words = set(dir(thisobject)) 161 words.discard("__builtins__") 162 163 if hasattr(thisobject, '__class__'): 164 words.add('__class__') 165 words.update(get_class_members(thisobject.__class__)) 166 matches = [] 167 n = len(attr) 168 if attr == '': 169 noprefix = '_' 170 elif attr == '_': 171 noprefix = '__' 172 else: 173 noprefix = None 174 while True: 175 for word in words: 176 if (word[:n] == attr and 177 not (noprefix and word[:n+1] == noprefix)): 178 match = "%s.%s" % (expr, word) 179 if isinstance(getattr(type(thisobject), word, None), 180 property): 181 # bpo-44752: thisobject.word is a method decorated by 182 # `@property`. What follows applies a postfix if 183 # thisobject.word is callable, but know we know that 184 # this is not callable (because it is a property). 185 # Also, getattr(thisobject, word) will evaluate the 186 # property method, which is not desirable. 187 matches.append(match) 188 continue 189 if (value := getattr(thisobject, word, None)) is not None: 190 matches.append(self._callable_postfix(value, match)) 191 else: 192 matches.append(match) 193 if matches or not noprefix: 194 break 195 if noprefix == '_': 196 noprefix = '__' 197 else: 198 noprefix = None 199 matches.sort() 200 return matches 201 202def get_class_members(klass): 203 ret = dir(klass) 204 if hasattr(klass,'__bases__'): 205 for base in klass.__bases__: 206 ret = ret + get_class_members(base) 207 return ret 208 209try: 210 import readline 211except ImportError: 212 _readline_available = False 213else: 214 readline.set_completer(Completer().complete) 215 # Release references early at shutdown (the readline module's 216 # contents are quasi-immortal, and the completer function holds a 217 # reference to globals). 218 atexit.register(lambda: readline.set_completer(None)) 219 _readline_available = True 220