File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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
155158def get_class_members (klass ):
Original file line number Diff line number Diff 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 ' )
Original file line number Diff line number Diff line change @@ -67,6 +67,9 @@ Core and Builtins
6767Library
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.
You can’t perform that action at this time.
0 commit comments