diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/rlcompleter.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-win32-2.6.1/lib/rlcompleter.py Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,170 @@ +"""Word completion for GNU readline 2.0. + +This requires the latest extension to the readline module. The completer +completes keywords, built-ins and globals in a selectable namespace (which +defaults to __main__); when completing NAME.NAME..., it evaluates (!) the +expression up to the last dot and completes its attributes. + +It's very cool to do "import sys" type "sys.", hit the +completion key (twice), and see the list of names defined by the +sys module! + +Tip: to use the tab key as the completion key, call + + readline.parse_and_bind("tab: complete") + +Notes: + +- Exceptions raised by the completer function are *ignored* (and +generally cause the completion to fail). This is a feature -- since +readline sets the tty device in raw (or cbreak) mode, printing a +traceback wouldn't work well without some complicated hoopla to save, +reset and restore the tty state. + +- The evaluation of the NAME.NAME... form may cause arbitrary +application defined code to be executed if an object with a +__getattr__ hook is found. Since it is the responsibility of the +application (or the user) to enable this feature, I consider this an +acceptable risk. More complicated expressions (e.g. function calls or +indexing operations) are *not* evaluated. + +- GNU readline is also used by the built-in functions input() and +raw_input(), and thus these also benefit/suffer from the completer +features. Clearly an interactive application can benefit by +specifying its own completer function and using raw_input() for all +its input. + +- When the original stdin is not a tty device, GNU readline is never +used, and this module (and the readline module) are silently inactive. + +""" + +import __builtin__ +import __main__ + +__all__ = ["Completer"] + +class Completer: + def __init__(self, namespace = None): + """Create a new completer for the command line. + + Completer([namespace]) -> completer instance. + + If unspecified, the default namespace where completions are performed + is __main__ (technically, __main__.__dict__). Namespaces should be + given as dictionaries. + + Completer instances should be used as the completion mechanism of + readline via the set_completer() call: + + readline.set_completer(Completer(my_namespace).complete) + """ + + if namespace and not isinstance(namespace, dict): + 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 + # to bind to __main__.__dict__ at completion time, not now. + if namespace is None: + self.use_main_ns = 1 + else: + self.use_main_ns = 0 + self.namespace = namespace + + def complete(self, text, state): + """Return the next possible completion for 'text'. + + This is called successively with state == 0, 1, 2, ... until it + returns None. The completion should begin with 'text'. + + """ + if self.use_main_ns: + self.namespace = __main__.__dict__ + + if state == 0: + if "." in text: + self.matches = self.attr_matches(text) + else: + self.matches = self.global_matches(text) + try: + return self.matches[state] + except IndexError: + return None + + def _callable_postfix(self, val, word): + if hasattr(val, '__call__'): + word = word + "(" + return word + + def global_matches(self, text): + """Compute matches when text is a simple name. + + Return a list of all keywords, built-in functions and names currently + defined in self.namespace that match. + + """ + import keyword + matches = [] + n = len(text) + for word in keyword.kwlist: + if word[:n] == text: + matches.append(word) + for nspace in [__builtin__.__dict__, self.namespace]: + for word, val in nspace.items(): + if word[:n] == text and word != "__builtins__": + matches.append(self._callable_postfix(val, word)) + return matches + + def attr_matches(self, text): + """Compute matches when text contains a dot. + + Assuming the text is of the form NAME.NAME....[NAME], and is + evaluatable in self.namespace, it will be evaluated and its attributes + (as revealed by dir()) are used as possible completions. (For class + instances, class members are also considered.) + + WARNING: this can still invoke arbitrary C code, if an object + with a __getattr__ hook is evaluated. + + """ + import re + m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) + if not m: + return [] + expr, attr = m.group(1, 3) + try: + thisobject = eval(expr, self.namespace) + except Exception: + return [] + + # get the content of the object, except __builtins__ + words = dir(thisobject) + if "__builtins__" in words: + words.remove("__builtins__") + + if hasattr(thisobject, '__class__'): + words.append('__class__') + words.extend(get_class_members(thisobject.__class__)) + matches = [] + n = len(attr) + for word in words: + if word[:n] == attr and hasattr(thisobject, word): + val = getattr(thisobject, word) + word = self._callable_postfix(val, "%s.%s" % (expr, word)) + matches.append(word) + return matches + +def get_class_members(klass): + ret = dir(klass) + if hasattr(klass,'__bases__'): + for base in klass.__bases__: + ret = ret + get_class_members(base) + return ret + +try: + import readline +except ImportError: + pass +else: + readline.set_completer(Completer().complete)