|
8 | 8 | import keyword |
9 | 9 | import types |
10 | 10 |
|
| 11 | + |
| 12 | +def safe_getattr(obj, name): |
| 13 | + # Mirror rlcompleter's safeguards so completion does not |
| 14 | + # call properties or reify lazy module attributes. |
| 15 | + if isinstance(getattr(type(obj), name, None), property): |
| 16 | + return None |
| 17 | + if (isinstance(obj, types.ModuleType) |
| 18 | + and isinstance(obj.__dict__.get(name), types.LazyImportType) |
| 19 | + ): |
| 20 | + return obj.__dict__.get(name) |
| 21 | + return getattr(obj, name, None) |
| 22 | + |
| 23 | + |
11 | 24 | class Completer(rlcompleter.Completer): |
12 | 25 | """ |
13 | 26 | When doing something like a.b.<tab>, keep the full a.b.attr completion |
@@ -143,21 +156,7 @@ def _attr_matches(self, text): |
143 | 156 | word[:n] == attr |
144 | 157 | and not (noprefix and word[:n+1] == noprefix) |
145 | 158 | ): |
146 | | - # Mirror rlcompleter's safeguards so completion does not |
147 | | - # call properties or reify lazy module attributes. |
148 | | - if isinstance(getattr(type(thisobject), word, None), property): |
149 | | - value = None |
150 | | - elif ( |
151 | | - isinstance(thisobject, types.ModuleType) |
152 | | - and isinstance( |
153 | | - thisobject.__dict__.get(word), |
154 | | - types.LazyImportType, |
155 | | - ) |
156 | | - ): |
157 | | - value = thisobject.__dict__.get(word) |
158 | | - else: |
159 | | - value = getattr(thisobject, word, None) |
160 | | - |
| 159 | + value = safe_getattr(thisobject, word) |
161 | 160 | names.append(word) |
162 | 161 | values.append(value) |
163 | 162 | if names or not noprefix: |
|
0 commit comments