gh-108082: C API: Add tests for PyErr_WriteUnraisable() (GH-111455) · python/cpython@bca3305 · GitHub
Skip to content

Commit bca3305

Browse files
gh-108082: C API: Add tests for PyErr_WriteUnraisable() (GH-111455)
Also document the behavior when called with NULL.
1 parent 8eaa206 commit bca3305

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

Doc/c-api/exceptions.rst

Lines changed: 8 additions & 0 deletions

Lib/test/test_capi/test_exceptions.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
NULL = None
1919

20+
class CustomError(Exception):
21+
pass
22+
23+
2024
class Test_Exceptions(unittest.TestCase):
2125

2226
def test_exception(self):
@@ -270,6 +274,47 @@ def test_setfromerrnowithfilename(self):
270274
(ENOENT, 'No such file or directory', 'file'))
271275
# CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error')
272276

277+
def test_err_writeunraisable(self):
278+
# Test PyErr_WriteUnraisable()
279+
writeunraisable = _testcapi.err_writeunraisable
280+
firstline = self.test_err_writeunraisable.__code__.co_firstlineno
281+
282+
with support.catch_unraisable_exception() as cm:
283+
writeunraisable(CustomError('oops!'), hex)
284+
self.assertEqual(cm.unraisable.exc_type, CustomError)
285+
self.assertEqual(str(cm.unraisable.exc_value), 'oops!')
286+
self.assertEqual(cm.unraisable.exc_traceback.tb_lineno,
287+
firstline + 6)
288+
self.assertIsNone(cm.unraisable.err_msg)
289+
self.assertEqual(cm.unraisable.object, hex)
290+
291+
with support.catch_unraisable_exception() as cm:
292+
writeunraisable(CustomError('oops!'), NULL)
293+
self.assertEqual(cm.unraisable.exc_type, CustomError)
294+
self.assertEqual(str(cm.unraisable.exc_value), 'oops!')
295+
self.assertEqual(cm.unraisable.exc_traceback.tb_lineno,
296+
firstline + 15)
297+
self.assertIsNone(cm.unraisable.err_msg)
298+
self.assertIsNone(cm.unraisable.object)
299+
300+
with (support.swap_attr(sys, 'unraisablehook', None),
301+
support.captured_stderr() as stderr):
302+
writeunraisable(CustomError('oops!'), hex)
303+
lines = stderr.getvalue().splitlines()
304+
self.assertEqual(lines[0], f'Exception ignored in: {hex!r}')
305+
self.assertEqual(lines[1], 'Traceback (most recent call last):')
306+
self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!')
307+
308+
with (support.swap_attr(sys, 'unraisablehook', None),
309+
support.captured_stderr() as stderr):
310+
writeunraisable(CustomError('oops!'), NULL)
311+
lines = stderr.getvalue().splitlines()
312+
self.assertEqual(lines[0], 'Traceback (most recent call last):')
313+
self.assertEqual(lines[-1], f'{__name__}.CustomError: oops!')
314+
315+
# CRASHES writeunraisable(NULL, hex)
316+
# CRASHES writeunraisable(NULL, NULL)
317+
273318

274319
class Test_PyUnstable_Exc_PrepReraiseStar(ExceptionIsLikeMixin, unittest.TestCase):
275320

Modules/_testcapi/exceptions.c

Lines changed: 17 additions & 0 deletions

0 commit comments

Comments
 (0)