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 keyword 36import re 37import __main__ 38 39__all__ = ["Completer"] 40 41class Completer: 42 def __init__(self, namespace = None): 43 """Create a new completer for the command line. 44 45 Completer([namespace]) -> completer instance. 46 47 If unspecified, the default namespace where completions are performed 48 is __main__ (technically, __main__.__dict__). Namespaces should be 49 given as dictionaries. 50 51 Completer instances should be used as the completion mechanism of 52 readline via the set_completer() call: 53 54 readline.set_completer(Completer(my_namespace).complete) 55 """ 56 57 if namespace and not isinstance(namespace, dict): 58 raise TypeError('namespace must be a dictionary') 59 60 # Don't bind to namespace quite yet, but flag whether the user wants a 61 # specific namespace or to use __main__.__dict__. This will allow us 62 # to bind to __main__.__dict__ at completion time, not now. 63 if namespace is None: 64 self.use_main_ns = 1 65 else: 66 self.use_main_ns = 0 67 self.namespace = namespace 68 69 def complete(self, text, state): 70 """Return the next possible completion for 'text'. 71 72 This is called successively with state == 0, 1, 2, ... until it 73 returns None. The completion should begin with 'text'. 74 75 """ 76 if self.use_main_ns: 77 self.namespace = __main__.__dict__ 78 79 if not text.strip(): 80 if state == 0: 81 if _readline_available: 82 readline.insert_text('\t') 83 readline.redisplay() 84 return '' 85 else: 86 return '\t' 87 else: 88 return None 89 90 if state == 0: 91 if "." in text: 92 self.matches = self.attr_matches(text) 93 else: 94 self.matches = self.global_matches(text) 95 try: 96 return self.matches[state] 97 except IndexError: 98 return None 99 100 def _callable_postfix(self, val, word): 101 if callable(val): 102 word += "(" 103 try: 104 if not inspect.signature(val).parameters: 105 word += ")" 106 except ValueError: 107 pass 108 109 return word 110 111 def global_matches(self, text): 112 """Compute matches when text is a simple name. 113 114 Return a list of all keywords, built-in functions and names currently 115 defined in self.namespace that match. 116 117 """ 118 matches = [] 119 seen = {"__builtins__"} 120 n = len(text) 121 for word in keyword.kwlist + keyword.softkwlist: 122 if word[:n] == text: 123 seen.add(word) 124 if word in {'finally', 'try'}: 125 word = word + ':' 126 elif word not in {'False', 'None', 'True', 127 'break', 'continue', 'pass', 128 'else', '_'}: 129 word = word + ' ' 130 matches.append(word) 131 for nspace in [self.namespace, builtins.__dict__]: 132 for word, val in nspace.items(): 133 if word[:n] == text and word not in seen: 134 seen.add(word) 135 matches.append(self._callable_postfix(val, word)) 136 return matches 137 138 def attr_matches(self, text): 139 """Compute matches when text contains a dot. 140 141 Assuming the text is of the form NAME.NAME....[NAME], and is 142 evaluable in self.namespace, it will be evaluated and its attributes 143 (as revealed by dir()) are used as possible completions. (For class 144 instances, class members are also considered.) 145 146 WARNING: this can still invoke arbitrary C code, if an object 147 with a __getattr__ hook is evaluated. 148 149 """ 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