Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fa9ea04

Browse files
committed
Issue #25590: Merge rlcompleter change from 3.4 into 3.5
2 parents 75559af + 06622ea commit fa9ea04

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

Lib/rlcompleter.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,23 @@ def attr_matches(self, text):
136136
return []
137137

138138
# get the content of the object, except __builtins__
139-
words = dir(thisobject)
140-
if "__builtins__" in words:
141-
words.remove("__builtins__")
139+
words = set(dir(thisobject))
140+
words.discard("__builtins__")
142141

143142
if hasattr(thisobject, '__class__'):
144-
words.append('__class__')
145-
words.extend(get_class_members(thisobject.__class__))
143+
words.add('__class__')
144+
words.update(get_class_members(thisobject.__class__))
146145
matches = []
147146
n = len(attr)
148147
for word in words:
149-
if word[:n] == attr and hasattr(thisobject, word):
150-
val = getattr(thisobject, word)
148+
if word[:n] == attr:
149+
try:
150+
val = getattr(thisobject, word)
151+
except Exception:
152+
continue # Exclude properties that are not set
151153
word = self._callable_postfix(val, "%s.%s" % (expr, word))
152154
matches.append(word)
155+
matches.sort()
153156
return matches
154157

155158
def get_class_members(klass):

Lib/test/test_rlcompleter.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ def test_attr_matches(self):
6464
['egg.{}('.format(x) for x in dir(str)
6565
if x.startswith('s')])
6666

67+
def test_excessive_getattr(self):
68+
# Ensure getattr() is invoked no more than once per attribute
69+
class Foo:
70+
calls = 0
71+
@property
72+
def bar(self):
73+
self.calls += 1
74+
return None
75+
f = Foo()
76+
completer = rlcompleter.Completer(dict(f=f))
77+
self.assertEqual(completer.complete('f.b', 0), 'f.bar')
78+
self.assertEqual(f.calls, 1)
79+
6780
def test_complete(self):
6881
completer = rlcompleter.Completer()
6982
self.assertEqual(completer.complete('', 0), '\t')

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ Core and Builtins
6767
Library
6868
-------
6969

70+
- Issue #25590: In the Readline completer, only call getattr() once per
71+
attribute.
72+
7073
- Issue #25498: Fix a crash when garbage-collecting ctypes objects created
7174
by wrapping a memoryview. This was a regression made in 3.5a1. Based
7275
on patch by Eryksun.

0 commit comments

Comments
 (0)