@@ -129,6 +129,34 @@ def test_object_hasattrstring(self):
129129 # CRASHES hasattrstring(obj, NULL)
130130 # CRASHES hasattrstring(NULL, b'a')
131131
132+ def test_object_hasattrwitherror (self ):
133+ xhasattr = _testcapi .object_hasattrwitherror
134+ obj = TestObject ()
135+ obj .a = 1
136+ setattr (obj , '\U0001f40d ' , 2 )
137+ self .assertTrue (xhasattr (obj , 'a' ))
138+ self .assertFalse (xhasattr (obj , 'b' ))
139+ self .assertTrue (xhasattr (obj , '\U0001f40d ' ))
140+
141+ self .assertRaises (RuntimeError , xhasattr , obj , 'evil' )
142+ self .assertRaises (TypeError , xhasattr , obj , 1 )
143+ # CRASHES xhasattr(obj, NULL)
144+ # CRASHES xhasattr(NULL, 'a')
145+
146+ def test_object_hasattrstringwitherror (self ):
147+ hasattrstring = _testcapi .object_hasattrstringwitherror
148+ obj = TestObject ()
149+ obj .a = 1
150+ setattr (obj , '\U0001f40d ' , 2 )
151+ self .assertTrue (hasattrstring (obj , b'a' ))
152+ self .assertFalse (hasattrstring (obj , b'b' ))
153+ self .assertTrue (hasattrstring (obj , '\U0001f40d ' .encode ()))
154+
155+ self .assertRaises (RuntimeError , hasattrstring , obj , b'evil' )
156+ self .assertRaises (UnicodeDecodeError , hasattrstring , obj , b'\xff ' )
157+ # CRASHES hasattrstring(obj, NULL)
158+ # CRASHES hasattrstring(NULL, b'a')
159+
132160 def test_object_setattr (self ):
133161 xsetattr = _testcapi .object_setattr
134162 obj = TestObject ()
@@ -339,6 +367,44 @@ def test_mapping_haskeystring(self):
339367 self .assertFalse (haskeystring ([], b'a' ))
340368 self .assertFalse (haskeystring (NULL , b'a' ))
341369
370+ def test_mapping_haskeywitherror (self ):
371+ haskey = _testcapi .mapping_haskeywitherror
372+ dct = {'a' : 1 , '\U0001f40d ' : 2 }
373+ self .assertTrue (haskey (dct , 'a' ))
374+ self .assertFalse (haskey (dct , 'b' ))
375+ self .assertTrue (haskey (dct , '\U0001f40d ' ))
376+
377+ dct2 = ProxyGetItem (dct )
378+ self .assertTrue (haskey (dct2 , 'a' ))
379+ self .assertFalse (haskey (dct2 , 'b' ))
380+
381+ self .assertTrue (haskey (['a' , 'b' , 'c' ], 1 ))
382+
383+ self .assertRaises (TypeError , haskey , 42 , 'a' )
384+ self .assertRaises (TypeError , haskey , {}, []) # unhashable
385+ self .assertRaises (IndexError , haskey , [], 1 )
386+ self .assertRaises (TypeError , haskey , [], 'a' )
387+
388+ # CRASHES haskey({}, NULL))
389+ # CRASHES haskey(NULL, 'a'))
390+
391+ def test_mapping_haskeystringwitherror (self ):
392+ haskeystring = _testcapi .mapping_haskeystringwitherror
393+ dct = {'a' : 1 , '\U0001f40d ' : 2 }
394+ self .assertTrue (haskeystring (dct , b'a' ))
395+ self .assertFalse (haskeystring (dct , b'b' ))
396+ self .assertTrue (haskeystring (dct , '\U0001f40d ' .encode ()))
397+
398+ dct2 = ProxyGetItem (dct )
399+ self .assertTrue (haskeystring (dct2 , b'a' ))
400+ self .assertFalse (haskeystring (dct2 , b'b' ))
401+
402+ self .assertRaises (TypeError , haskeystring , 42 , b'a' )
403+ self .assertRaises (UnicodeDecodeError , haskeystring , {}, b'\xff ' )
404+ self .assertRaises (SystemError , haskeystring , {}, NULL )
405+ self .assertRaises (TypeError , haskeystring , [], b'a' )
406+ # CRASHES haskeystring(NULL, b'a')
407+
342408 def test_object_setitem (self ):
343409 setitem = _testcapi .object_setitem
344410 dct = {}
0 commit comments