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 inspect
35 import keyword
36 import re
37 import __main__
38
39 __all__ = ["Completer"]
40
41 class ESC[4;38;5;81mCompleter:
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
202 def 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
209 try:
210 import readline
211 except ImportError:
212 _readline_available = False
213 else:
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