src/extras/pyrepl/completer.py
author Vijayan <ts.vijayan@nokia.com>
Tue, 16 Feb 2010 10:07:05 +0530
changeset 0 ca70ae20a155
permissions -rw-r--r--
Base Python2.0 code
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     1
#   Copyright 2000-2004 Michael Hudson mwh@python.net
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     2
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     3
#                        All Rights Reserved
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     4
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     5
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     6
# Permission to use, copy, modify, and distribute this software and
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     7
# its documentation for any purpose is hereby granted without fee,
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     8
# provided that the above copyright notice appear in all copies and
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     9
# that both that copyright notice and this permission notice appear in
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    10
# supporting documentation.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    11
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    12
# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    13
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    14
# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    15
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    16
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    17
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    18
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    19
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    20
import __builtin__
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    21
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    22
class Completer:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    23
    def __init__(self, ns):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    24
        self.ns = ns
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    25
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    26
    def complete(self, text):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    27
        if "." in text:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    28
            return self.attr_matches(text)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    29
        else:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    30
            return self.global_matches(text)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    31
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    32
    def global_matches(self, text):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    33
        """Compute matches when text is a simple name.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    34
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    35
        Return a list of all keywords, built-in functions and names
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    36
        currently defines in __main__ that match.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    37
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    38
        """
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    39
        import keyword
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    40
        matches = []
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    41
        n = len(text)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    42
        for list in [keyword.kwlist,
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    43
                     __builtin__.__dict__.keys(),
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    44
                     self.ns.keys()]:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    45
            for word in list:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    46
                if word[:n] == text and word != "__builtins__":
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    47
                    matches.append(word)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    48
        return matches
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    49
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    50
    def attr_matches(self, text):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    51
        """Compute matches when text contains a dot.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    52
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    53
        Assuming the text is of the form NAME.NAME....[NAME], and is
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    54
        evaluatable in the globals of __main__, it will be evaluated
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    55
        and its attributes (as revealed by dir()) are used as possible
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    56
        completions.  (For class instances, class members are are also
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    57
        considered.)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    58
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    59
        WARNING: this can still invoke arbitrary C code, if an object
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    60
        with a __getattr__ hook is evaluated.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    61
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    62
        """
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    63
        import re
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    64
        m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    65
        if not m:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    66
            return []
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    67
        expr, attr = m.group(1, 3)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    68
        object = eval(expr, self.ns)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    69
        words = dir(object)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    70
        if hasattr(object, '__class__'):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    71
            words.append('__class__')
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    72
            words = words + get_class_members(object.__class__)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    73
        matches = []
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    74
        n = len(attr)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    75
        for word in words:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    76
            if word[:n] == attr and word != "__builtins__":
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    77
                matches.append("%s.%s" % (expr, word))
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    78
        return matches
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    79
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    80
def get_class_members(klass):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    81
    ret = dir(klass)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    82
    if hasattr(klass, '__bases__'):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    83
        for base in klass.__bases__:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    84
            ret = ret + get_class_members(base)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    85
    return ret
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    86
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    87