@@ -167,9 +167,14 @@ def test_lookup_on_object(self):
167
167
self .assertEqual (get_attr_safe (b , "a" ), "a" )
168
168
self .assertEqual (get_attr_safe (b , "b" ), "b" )
169
169
170
+ self .assertEqual (has_attr_safe (b , "y" ), True )
171
+ self .assertEqual (has_attr_safe (b , "b" ), True )
172
+
173
+
170
174
def test_avoid_running_properties (self ):
171
175
p = Property ()
172
176
self .assertEqual (get_attr_safe (p , "prop" ), Property .prop )
177
+ self .assertEqual (has_attr_safe (p , "prop" ), True )
173
178
174
179
def test_lookup_with_slots (self ):
175
180
s = Slots ()
@@ -178,6 +183,8 @@ def test_lookup_with_slots(self):
178
183
with self .assertRaises (AttributeError ):
179
184
get_attr_safe (s , "s2" )
180
185
186
+ self .assertEqual (has_attr_safe (s , "s2" ), False )
187
+
181
188
def test_lookup_on_slots_classes (self ):
182
189
sga = get_attr_safe
183
190
s = SlotsSubclass ()
@@ -186,6 +193,9 @@ def test_lookup_on_slots_classes(self):
186
193
self .assertIsInstance (sga (SlotsSubclass , "s4" ), property )
187
194
self .assertIsInstance (sga (s , "s4" ), property )
188
195
196
+ self .assertEqual (has_attr_safe (s , "s1" ), True )
197
+ self .assertEqual (has_attr_safe (s , "s4" ), True )
198
+
189
199
@unittest .skipIf (py3 , "Py 3 doesn't allow slots and prop in same class" )
190
200
def test_lookup_with_property_and_slots (self ):
191
201
sga = get_attr_safe
@@ -206,6 +216,12 @@ def test_lookup_on_overridden_methods(self):
206
216
with self .assertRaises (AttributeError ):
207
217
sga (OverriddenMRO (), "b" )
208
218
219
+ self .assertEqual (has_attr_safe (OverriddenGetattr (), "b" ), False )
220
+ self .assertEqual (has_attr_safe (OverriddenGetattribute (), "b" ), False )
221
+ self .assertEqual (has_attr_safe (OverriddenMRO (), "b" ), False )
222
+
223
+
224
+
209
225
210
226
if __name__ == "__main__" :
211
227
unittest .main ()
0 commit comments