Skip to content

Commit 4d26621

Browse files
committed
Move attr_{matches,lookup} to AttrCompleter
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
1 parent e83fb4a commit 4d26621

File tree

1 file changed

+49
-51
lines changed

1 file changed

+49
-51
lines changed

bpython/autocomplete.py

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ def format(self, filename):
199199
return filename
200200

201201

202+
attr_matches_re = LazyReCompile(r"(\w+(\.\w+)*)\.(\w*)")
203+
204+
202205
class AttrCompletion(BaseCompletionType):
203206

204207
def matches(self, cursor_offset, line, **kwargs):
@@ -222,7 +225,7 @@ def matches(self, cursor_offset, line, **kwargs):
222225
break
223226
methodtext = text[-i:]
224227
matches = set(''.join([text[:-i], m])
225-
for m in attr_matches(methodtext, locals_))
228+
for m in self.attr_matches(methodtext, locals_))
226229

227230
# TODO add open paren for methods via _callable_prefix (or decide not
228231
# to) unless the first character is a _ filter out all attributes
@@ -238,6 +241,51 @@ def locate(self, current_offset, line):
238241
def format(self, word):
239242
return after_last_dot(word)
240243

244+
def attr_matches(self, text, namespace):
245+
"""Taken from rlcompleter.py and bent to my will.
246+
"""
247+
248+
# Gna, Py 2.6's rlcompleter searches for __call__ inside the
249+
# instance instead of the type, so we monkeypatch to prevent
250+
# side-effects (__getattr__/__getattribute__)
251+
m = attr_matches_re.match(text)
252+
if not m:
253+
return []
254+
255+
expr, attr = m.group(1, 3)
256+
if expr.isdigit():
257+
# Special case: float literal, using attrs here will result in
258+
# a SyntaxError
259+
return []
260+
try:
261+
obj = safe_eval(expr, namespace)
262+
except EvaluationError:
263+
return []
264+
with inspection.AttrCleaner(obj):
265+
matches = self.attr_lookup(obj, expr, attr)
266+
return matches
267+
268+
def attr_lookup(self, obj, expr, attr):
269+
"""Second half of original attr_matches method factored out so it can
270+
be wrapped in a safe try/finally block in case anything bad happens to
271+
restore the original __getattribute__ method."""
272+
words = dir(obj)
273+
if hasattr(obj, '__class__'):
274+
words.append('__class__')
275+
words = words + rlcompleter.get_class_members(obj.__class__)
276+
if not isinstance(obj.__class__, abc.ABCMeta):
277+
try:
278+
words.remove('__abstractmethods__')
279+
except ValueError:
280+
pass
281+
282+
matches = []
283+
n = len(attr)
284+
for word in words:
285+
if method_match(word, n, attr) and word != "__builtins__":
286+
matches.append("%s.%s" % (expr, word))
287+
return matches
288+
241289

242290
class DictKeyCompletion(BaseCompletionType):
243291

@@ -498,56 +546,6 @@ def safe_eval(expr, namespace):
498546
raise EvaluationError
499547

500548

501-
attr_matches_re = LazyReCompile(r"(\w+(\.\w+)*)\.(\w*)")
502-
503-
504-
def attr_matches(text, namespace):
505-
"""Taken from rlcompleter.py and bent to my will.
506-
"""
507-
508-
# Gna, Py 2.6's rlcompleter searches for __call__ inside the
509-
# instance instead of the type, so we monkeypatch to prevent
510-
# side-effects (__getattr__/__getattribute__)
511-
m = attr_matches_re.match(text)
512-
if not m:
513-
return []
514-
515-
expr, attr = m.group(1, 3)
516-
if expr.isdigit():
517-
# Special case: float literal, using attrs here will result in
518-
# a SyntaxError
519-
return []
520-
try:
521-
obj = safe_eval(expr, namespace)
522-
except EvaluationError:
523-
return []
524-
with inspection.AttrCleaner(obj):
525-
matches = attr_lookup(obj, expr, attr)
526-
return matches
527-
528-
529-
def attr_lookup(obj, expr, attr):
530-
"""Second half of original attr_matches method factored out so it can
531-
be wrapped in a safe try/finally block in case anything bad happens to
532-
restore the original __getattribute__ method."""
533-
words = dir(obj)
534-
if hasattr(obj, '__class__'):
535-
words.append('__class__')
536-
words = words + rlcompleter.get_class_members(obj.__class__)
537-
if not isinstance(obj.__class__, abc.ABCMeta):
538-
try:
539-
words.remove('__abstractmethods__')
540-
except ValueError:
541-
pass
542-
543-
matches = []
544-
n = len(attr)
545-
for word in words:
546-
if method_match(word, n, attr) and word != "__builtins__":
547-
matches.append("%s.%s" % (expr, word))
548-
return matches
549-
550-
551549
def _callable_postfix(value, word):
552550
"""rlcompleter's _callable_postfix done right."""
553551
with inspection.AttrCleaner(value):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy