[3.12] gh-108082: C API: Add tests for PyErr_WriteUnraisable() (GH-111455) (GH-111507)

Also document the behavior when called with NULL.
(cherry picked from commit bca3305429)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Miss Islington (bot) 2023-10-30 18:36:00 +01:00 committed by GitHub
parent e5b6744f30
commit 748bc48648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 0 deletions

View file

@ -17,6 +17,10 @@ _testcapi = import_helper.import_module('_testcapi')
NULL = None
class CustomError(Exception):
pass
class Test_Exceptions(unittest.TestCase):
def test_exception(self):
@ -270,6 +274,47 @@ class Test_ErrSetAndRestore(unittest.TestCase):
(ENOENT, 'No such file or directory', 'file'))
# CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error')
def test_err_writeunraisable(self):
# Test PyErr_WriteUnraisable()
writeunraisable = _testcapi.err_writeunraisable
firstline = self.test_err_writeunraisable.__code__.co_firstlineno
with support.catch_unraisable_exception() as cm:
writeunraisable(CustomError('oops!'), hex)
self.assertEqual(cm.unraisable.exc_type, CustomError)
self.assertEqual(str(cm.unraisable.exc_value), 'oops!')
self.assertEqual(cm.unraisable.exc_traceback.tb_lineno,
firstline + 6)
self.assertIsNone(cm.unraisable.err_msg)
self.assertEqual(cm.unraisable.object, hex)
with support.catch_unraisable_exception() as cm:
writeunraisable(CustomError('oops!'), NULL)
self.assertEqual(cm.unraisable.exc_type, CustomError)
self.assertEqual(str(cm.unraisable.exc_value), 'oops!')
self.assertEqual(cm.unraisable.exc_traceback.tb_lineno,
firstline + 15)
self.assertIsNone(cm.unraisable.err_msg)
self.assertIsNone(cm.unraisable.object)
with (support.swap_attr(sys, 'unraisablehook', None),
support.captured_stderr() as stderr):
writeunraisable(CustomError('oops!'), hex)
lines = stderr.getvalue().splitlines()
self.assertEqual(lines[0], f'Exception ignored in: {hex!r}')
self.assertEqual(lines[1], 'Traceback (most recent call last):')
self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!')
with (support.swap_attr(sys, 'unraisablehook', None),
support.captured_stderr() as stderr):
writeunraisable(CustomError('oops!'), NULL)
lines = stderr.getvalue().splitlines()
self.assertEqual(lines[0], 'Traceback (most recent call last):')
self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!')
# CRASHES writeunraisable(NULL, hex)
# CRASHES writeunraisable(NULL, NULL)
class Test_PyUnstable_Exc_PrepReraiseStar(ExceptionIsLikeMixin, unittest.TestCase):