diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/DebugClients/Python/FlexCompleter.py --- a/src/eric7/DebugClients/Python/FlexCompleter.py Wed Jul 13 11:16:20 2022 +0200 +++ b/src/eric7/DebugClients/Python/FlexCompleter.py Wed Jul 13 14:55:47 2022 +0200 @@ -58,6 +58,7 @@ """ Class implementing the command line completer object. """ + def __init__(self, namespace=None): """ Constructor @@ -72,13 +73,13 @@ readline via the set_completer() call: readline.set_completer(Completer(my_namespace).complete) - + @param namespace The namespace for the completer. @exception TypeError raised to indicate a wrong data structure of the namespace object """ if namespace and not isinstance(namespace, dict): - raise TypeError('namespace must be a dictionary') + raise TypeError("namespace must be a dictionary") # Don't bind to namespace quite yet, but flag whether the user wants a # specific namespace or to use __main__.__dict__. This will allow us @@ -95,14 +96,14 @@ This is called successively with state == 0, 1, 2, ... until it returns None. The completion should begin with 'text'. - + @param text The text to be completed. (string) @param state The state of the completion. (integer) @return The possible completions as a list of strings. """ if self.use_main_ns: self.namespace = __main__.__dict__ - + if state == 0: if "." in text: self.matches = self.attr_matches(text) @@ -116,7 +117,7 @@ def _callable_postfix(self, val, word): """ Protected method to check for a callable. - + @param val value to check (object) @param word word to ammend (string) @return ammended word (string) @@ -134,18 +135,25 @@ defined in self.namespace that match. """ import keyword + matches = [] seen = {"__builtins__"} n = len(text) for word in keyword.kwlist: if word[:n] == text: seen.add(word) - if word in {'finally', 'try'}: - word += ':' - elif word not in {'False', 'None', 'True', - 'break', 'continue', 'pass', - 'else'}: - word += ' ' + if word in {"finally", "try"}: + word += ":" + elif word not in { + "False", + "None", + "True", + "break", + "continue", + "pass", + "else", + }: + word += " " matches.append(word) for nspace in [self.namespace, builtins.__dict__]: for word, val in nspace.items(): @@ -165,7 +173,7 @@ <b>WARNING</b>: this can still invoke arbitrary C code, if an object with a __getattr__ hook is evaluated. - + @param text The text to be completed. (string) @return A list of all matches. """ @@ -176,7 +184,7 @@ return [] expr, attr = m.group(1, 3) try: - thisobject = eval(expr, self.namespace) # secok + thisobject = eval(expr, self.namespace) # secok except Exception: return [] @@ -184,32 +192,31 @@ words = set(dir(thisobject)) words.discard("__builtins__") - if hasattr(object, '__class__'): - words.add('__class__') + if hasattr(object, "__class__"): + words.add("__class__") words.update(get_class_members(thisobject.__class__)) matches = [] n = len(attr) - if attr == '': - noprefix = '_' - elif attr == '_': - noprefix = '__' + if attr == "": + noprefix = "_" + elif attr == "_": + noprefix = "__" else: noprefix = None while True: for word in words: - if (word[:n] == attr and - not (noprefix and word[:n + 1] == noprefix)): + if word[:n] == attr and not (noprefix and word[: n + 1] == noprefix): match = "{0}.{1}".format(expr, word) try: val = getattr(thisobject, word) - except Exception: # secok + except Exception: # secok pass # Include even if attribute not set else: match = self._callable_postfix(val, match) matches.append(match) if matches or not noprefix: break - noprefix = '__' if noprefix == '_' else None + noprefix = "__" if noprefix == "_" else None matches.sort() return matches @@ -217,15 +224,16 @@ def get_class_members(klass): """ Module function to retrieve the class members. - + @param klass The class object to be analysed. @return A list of all names defined in the class. """ ret = dir(klass) - if hasattr(klass, '__bases__'): + if hasattr(klass, "__bases__"): for base in klass.__bases__: ret += get_class_members(base) return ret + # # eflag: noqa = M111