| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,4 +5,6 @@ tags | |||
| 5 | 5 | _trial_temp | |
| 6 | 6 | .mo | |
| 7 | 7 | build/* | |
| 8 | + env | ||
| 9 | + .DS_Store | ||
| 8 | 10 | .idea/ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ Other contributors are (in alphabetical order): | |||
| 10 | 10 | * Martha Girdler <martha at cheezburger dot com> | |
| 11 | 11 | * Eike Hein <sho at eikehein dot com> | |
| 12 | 12 | * Allison Kaptur <allison dot kaptur at gmail dot com> | |
| 13 | + * Jason Laster <jason dot laster dot 11 at gmail dot com> | ||
| 13 | 14 | * Brandon Navra <brandon dot navra at gmail dot com> | |
| 14 | 15 | * Michele Orrù <maker dot py at gmail dot com> | |
| 15 | 16 | * Pavel Panchekha <pavpanchekha at gmail dot com> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,135 @@ | |||
| 1 | + # The MIT License | ||
| 2 | + # | ||
| 3 | + # Copyright (c) 2009-2012 the bpython authors. | ||
| 4 | + # | ||
| 5 | + # Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 6 | + # of this software and associated documentation files (the "Software"), to deal | ||
| 7 | + # in the Software without restriction, including without limitation the rights | ||
| 8 | + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 9 | + # copies of the Software, and to permit persons to whom the Software is | ||
| 10 | + # furnished to do so, subject to the following conditions: | ||
| 11 | + # | ||
| 12 | + # The above copyright notice and this permission notice shall be included in | ||
| 13 | + # all copies or substantial portions of the Software. | ||
| 14 | + # | ||
| 15 | + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 16 | + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 17 | + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 18 | + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 19 | + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 20 | + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 21 | + # THE SOFTWARE. | ||
| 22 | + # | ||
| 23 | + | ||
| 24 | + import __builtin__ | ||
| 25 | + import __main__ | ||
| 26 | + import rlcompleter | ||
| 27 | + import re | ||
| 28 | + from bpython import inspection | ||
| 29 | + | ||
| 30 | + # Needed for special handling of __abstractmethods__ | ||
| 31 | + # abc only exists since 2.6, so check both that it exists and that it's | ||
| 32 | + # the one we're expecting | ||
| 33 | + try: | ||
| 34 | + import abc | ||
| 35 | + abc.ABCMeta | ||
| 36 | + has_abc = True | ||
| 37 | + except (ImportError, AttributeError): | ||
| 38 | + has_abc = False | ||
| 39 | + | ||
| 40 | + # Autocomplete modes | ||
| 41 | + SIMPLE = 'simple' | ||
| 42 | + SUBSTRING = 'substring' | ||
| 43 | + FUZZY = 'fuzzy' | ||
| 44 | + | ||
| 45 | + class Autocomplete(rlcompleter.Completer): | ||
| 46 | + """ | ||
| 47 | + """ | ||
| 48 | + | ||
| 49 | + def __init__(self, namespace = None, config = None): | ||
| 50 | + rlcompleter.Completer.__init__(self, namespace) | ||
| 51 | + self.locals = namespace | ||
| 52 | + if hasattr(config, 'autocomplete_mode'): | ||
| 53 | + self.autocomplete_mode = config.autocomplete_mode | ||
| 54 | + else: | ||
| 55 | + self.autocomplete_mode = SUBSTRING | ||
| 56 | + | ||
| 57 | + def attr_matches(self, text): | ||
| 58 | + """Taken from rlcompleter.py and bent to my will. | ||
| 59 | + """ | ||
| 60 | + | ||
| 61 | + # Gna, Py 2.6's rlcompleter searches for __call__ inside the | ||
| 62 | + # instance instead of the type, so we monkeypatch to prevent | ||
| 63 | + # side-effects (__getattr__/__getattribute__) | ||
| 64 | + m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) | ||
| 65 | + if not m: | ||
| 66 | + return [] | ||
| 67 | + | ||
| 68 | + expr, attr = m.group(1, 3) | ||
| 69 | + if expr.isdigit(): | ||
| 70 | + # Special case: float literal, using attrs here will result in | ||
| 71 | + # a SyntaxError | ||
| 72 | + return [] | ||
| 73 | + obj = eval(expr, self.locals) | ||
| 74 | + with inspection.AttrCleaner(obj): | ||
| 75 | + matches = self.attr_lookup(obj, expr, attr) | ||
| 76 | + return matches | ||
| 77 | + | ||
| 78 | + def attr_lookup(self, obj, expr, attr): | ||
| 79 | + """Second half of original attr_matches method factored out so it can | ||
| 80 | + be wrapped in a safe try/finally block in case anything bad happens to | ||
| 81 | + restore the original __getattribute__ method.""" | ||
| 82 | + words = dir(obj) | ||
| 83 | + if hasattr(obj, '__class__'): | ||
| 84 | + words.append('__class__') | ||
| 85 | + words = words + rlcompleter.get_class_members(obj.__class__) | ||
| 86 | + if has_abc and not isinstance(obj.__class__, abc.ABCMeta): | ||
| 87 | + try: | ||
| 88 | + words.remove('__abstractmethods__') | ||
| 89 | + except ValueError: | ||
| 90 | + pass | ||
| 91 | + | ||
| 92 | + matches = [] | ||
| 93 | + n = len(attr) | ||
| 94 | + for word in words: | ||
| 95 | + if self.method_match(word, n, attr) and word != "__builtins__": | ||
| 96 | + matches.append("%s.%s" % (expr, word)) | ||
| 97 | + return matches | ||
| 98 | + | ||
| 99 | + def _callable_postfix(self, value, word): | ||
| 100 | + """rlcompleter's _callable_postfix done right.""" | ||
| 101 | + with inspection.AttrCleaner(value): | ||
| 102 | + if inspection.is_callable(value): | ||
| 103 | + word += '(' | ||
| 104 | + return word | ||
| 105 | + | ||
| 106 | + def global_matches(self, text): | ||
| 107 | + """Compute matches when text is a simple name. | ||
| 108 | + Return a list of all keywords, built-in functions and names currently | ||
| 109 | + defined in self.namespace that match. | ||
| 110 | + """ | ||
| 111 | + | ||
| 112 | + hash = {} | ||
| 113 | + n = len(text) | ||
| 114 | + import keyword | ||
| 115 | + for word in keyword.kwlist: | ||
| 116 | + if self.method_match(word, n, text): | ||
| 117 | + hash[word] = 1 | ||
| 118 | + for nspace in [__builtin__.__dict__, self.namespace]: | ||
| 119 | + for word, val in nspace.items(): | ||
| 120 | + if self.method_match(word, len(text), text) and word != "__builtins__": | ||
| 121 | + hash[self._callable_postfix(val, word)] = 1 | ||
| 122 | + matches = hash.keys() | ||
| 123 | + matches.sort() | ||
| 124 | + return matches | ||
| 125 | + | ||
| 126 | + def method_match(self, word, size, text): | ||
| 127 | + if self.autocomplete_mode == SIMPLE: | ||
| 128 | + return word[:size] == text | ||
| 129 | + elif self.autocomplete_mode == SUBSTRING: | ||
| 130 | + s = r'.*%s.*' % text | ||
| 131 | + return re.search(s, word) | ||
| 132 | + else: | ||
| 133 | + s = r'.*%s.*' % '.*'.join(list(text)) | ||
| 134 | + return re.search(s, word) | ||
| 135 | + | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments