|
17 | 17 |
|
18 | 18 | NULL = None
|
19 | 19 |
|
| 20 | +class CustomError(Exception): |
| 21 | + pass |
| 22 | + |
| 23 | + |
20 | 24 | class Test_Exceptions(unittest.TestCase):
|
21 | 25 |
|
22 | 26 | def test_exception(self):
|
@@ -270,6 +274,47 @@ def test_setfromerrnowithfilename(self):
|
270 | 274 | (ENOENT, 'No such file or directory', 'file'))
|
271 | 275 | # CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error')
|
272 | 276 |
|
| 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 | + |
273 | 318 |
|
274 | 319 | class Test_PyUnstable_Exc_PrepReraiseStar(ExceptionIsLikeMixin, unittest.TestCase):
|
275 | 320 |
|
|
0 commit comments