22# these are all functions _testcapi exports whose name begins with 'test_'.
33
44from collections import OrderedDict
5+ import importlib .machinery
6+ import importlib .util
57import os
68import pickle
79import random
1315import time
1416import unittest
1517import weakref
16- import importlib .machinery
17- import importlib .util
1818from test import support
1919from test .support import MISSING_C_DOCSTRINGS
2020from test .support import import_helper
3535Py_DEBUG = hasattr (sys , 'gettotalrefcount' )
3636
3737
38+ def decode_stderr (err ):
39+ return err .decode ('utf-8' , 'replace' ).replace ('\r ' , '' )
40+
41+
3842def testfunction (self ):
3943 """some doc"""
4044 return self
@@ -207,23 +211,22 @@ def test_return_null_without_error(self):
207211 _testcapi.return_null_without_error()
208212 """ )
209213 rc , out , err = assert_python_failure ('-c' , code )
210- self .assertRegex (err .replace (b'\r ' , b'' ),
211- br'Fatal Python error: _Py_CheckFunctionResult: '
212- br'a function returned NULL '
213- br'without setting an error\n'
214- br'Python runtime state: initialized\n'
215- br'SystemError: <built-in function '
216- br'return_null_without_error> returned NULL '
217- br'without setting an error\n'
218- br'\n'
219- br'Current thread.*:\n'
220- br' File .*", line 6 in <module>' )
214+ err = decode_stderr (err )
215+ self .assertRegex (err ,
216+ r'Fatal Python error: _Py_CheckFunctionResult: '
217+ r'a function returned NULL without setting an exception\n'
218+ r'Python runtime state: initialized\n'
219+ r'SystemError: <built-in function return_null_without_error> '
220+ r'returned NULL without setting an exception\n'
221+ r'\n'
222+ r'Current thread.*:\n'
223+ r' File .*", line 6 in <module>\n' )
221224 else :
222225 with self .assertRaises (SystemError ) as cm :
223226 _testcapi .return_null_without_error ()
224227 self .assertRegex (str (cm .exception ),
225228 'return_null_without_error.* '
226- 'returned NULL without setting an error ' )
229+ 'returned NULL without setting an exception ' )
227230
228231 def test_return_result_with_error (self ):
229232 # Issue #23571: A function must not return a result with an error set
@@ -236,28 +239,58 @@ def test_return_result_with_error(self):
236239 _testcapi.return_result_with_error()
237240 """ )
238241 rc , out , err = assert_python_failure ('-c' , code )
239- self . assertRegex ( err . replace ( b' \r ' , b'' ),
240- br'Fatal Python error: _Py_CheckFunctionResult: '
241- br'a function returned a result '
242- br' with an error set\n'
243- br 'Python runtime state: initialized\n'
244- br 'ValueError\n'
245- br '\n'
246- br 'The above exception was the direct cause '
247- br 'of the following exception:\n'
248- br '\n'
249- br 'SystemError: <built-in '
250- br 'function return_result_with_error> '
251- br 'returned a result with an error set\n'
252- br '\n'
253- br 'Current thread.*:\n'
254- br ' File .*, line 6 in <module>' )
242+ err = decode_stderr ( err )
243+ self . assertRegex ( err ,
244+ r'Fatal Python error: _Py_CheckFunctionResult: '
245+ r'a function returned a result with an exception set\n'
246+ r 'Python runtime state: initialized\n'
247+ r 'ValueError\n'
248+ r '\n'
249+ r 'The above exception was the direct cause '
250+ r 'of the following exception:\n'
251+ r '\n'
252+ r 'SystemError: <built-in '
253+ r 'function return_result_with_error> '
254+ r 'returned a result with an exception set\n'
255+ r '\n'
256+ r 'Current thread.*:\n'
257+ r ' File .*, line 6 in <module>\n ' )
255258 else :
256259 with self .assertRaises (SystemError ) as cm :
257260 _testcapi .return_result_with_error ()
258261 self .assertRegex (str (cm .exception ),
259262 'return_result_with_error.* '
260- 'returned a result with an error set' )
263+ 'returned a result with an exception set' )
264+
265+ def test_getitem_with_error (self ):
266+ # Test _Py_CheckSlotResult(). Raise an exception and then calls
267+ # PyObject_GetItem(): check that the assertion catchs the bug.
268+ # PyObject_GetItem() must not be called with an exception set.
269+ code = textwrap .dedent ("""
270+ import _testcapi
271+ from test import support
272+
273+ with support.SuppressCrashReport():
274+ _testcapi.getitem_with_error({1: 2}, 1)
275+ """ )
276+ rc , out , err = assert_python_failure ('-c' , code )
277+ err = decode_stderr (err )
278+ if 'SystemError: ' not in err :
279+ self .assertRegex (err ,
280+ r'Fatal Python error: _Py_CheckSlotResult: '
281+ r'Slot __getitem__ of type dict succeeded '
282+ r'with an exception set\n'
283+ r'Python runtime state: initialized\n'
284+ r'ValueError: bug\n'
285+ r'\n'
286+ r'Current thread .* \(most recent call first\):\n'
287+ r' File .*, line 6 in <module>\n'
288+ r'\n'
289+ r'Extension modules: _testcapi \(total: 1\)\n' )
290+ else :
291+ # Python built with NDEBUG macro defined:
292+ # test _Py_CheckFunctionResult() instead.
293+ self .assertIn ('returned a result with an exception set' , err )
261294
262295 def test_buildvalue_N (self ):
263296 _testcapi .test_buildvalue_N ()
@@ -551,7 +584,7 @@ def check_fatal_error(self, code, expected, not_expected=()):
551584 with support .SuppressCrashReport ():
552585 rc , out , err = assert_python_failure ('-sSI' , '-c' , code )
553586
554- err = err . replace ( b' \r ' , b'' ). decode ( 'ascii' , 'replace' )
587+ err = decode_stderr ( err )
555588 self .assertIn ('Fatal Python error: test_fatal_error: MESSAGE\n ' ,
556589 err )
557590
0 commit comments