summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_sys.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_sys.py')
-rw-r--r--Lib/test/test_sys.py97
1 files changed, 54 insertions, 43 deletions
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index b16e1e7..b111962 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1215,38 +1215,38 @@ class SysModuleTest(unittest.TestCase):
@test.support.cpython_only
class UnraisableHookTest(unittest.TestCase):
- def write_unraisable_exc(self, exc, err_msg, obj):
- import _testinternalcapi
- import types
- err_msg2 = f"Exception ignored {err_msg}"
- try:
- _testinternalcapi.write_unraisable_exc(exc, err_msg, obj)
- return types.SimpleNamespace(exc_type=type(exc),
- exc_value=exc,
- exc_traceback=exc.__traceback__,
- err_msg=err_msg2,
- object=obj)
- finally:
- # Explicitly break any reference cycle
- exc = None
-
def test_original_unraisablehook(self):
- for err_msg in (None, "original hook"):
- with self.subTest(err_msg=err_msg):
- obj = "an object"
-
- with test.support.captured_output("stderr") as stderr:
- with test.support.swap_attr(sys, 'unraisablehook',
- sys.__unraisablehook__):
- self.write_unraisable_exc(ValueError(42), err_msg, obj)
-
- err = stderr.getvalue()
- if err_msg is not None:
- self.assertIn(f'Exception ignored {err_msg}: {obj!r}\n', err)
- else:
- self.assertIn(f'Exception ignored in: {obj!r}\n', err)
- self.assertIn('Traceback (most recent call last):\n', err)
- self.assertIn('ValueError: 42\n', err)
+ _testcapi = import_helper.import_module('_testcapi')
+ from _testcapi import err_writeunraisable, err_formatunraisable
+ obj = hex
+
+ with support.swap_attr(sys, 'unraisablehook',
+ sys.__unraisablehook__):
+ with support.captured_stderr() as stderr:
+ err_writeunraisable(ValueError(42), obj)
+ lines = stderr.getvalue().splitlines()
+ self.assertEqual(lines[0], f'Exception ignored in: {obj!r}')
+ self.assertEqual(lines[1], 'Traceback (most recent call last):')
+ self.assertEqual(lines[-1], 'ValueError: 42')
+
+ with support.captured_stderr() as stderr:
+ err_writeunraisable(ValueError(42), None)
+ lines = stderr.getvalue().splitlines()
+ self.assertEqual(lines[0], 'Traceback (most recent call last):')
+ self.assertEqual(lines[-1], 'ValueError: 42')
+
+ with support.captured_stderr() as stderr:
+ err_formatunraisable(ValueError(42), 'Error in %R', obj)
+ lines = stderr.getvalue().splitlines()
+ self.assertEqual(lines[0], f'Error in {obj!r}:')
+ self.assertEqual(lines[1], 'Traceback (most recent call last):')
+ self.assertEqual(lines[-1], 'ValueError: 42')
+
+ with support.captured_stderr() as stderr:
+ err_formatunraisable(ValueError(42), None)
+ lines = stderr.getvalue().splitlines()
+ self.assertEqual(lines[0], 'Traceback (most recent call last):')
+ self.assertEqual(lines[-1], 'ValueError: 42')
def test_original_unraisablehook_err(self):
# bpo-22836: PyErr_WriteUnraisable() should give sensible reports
@@ -1293,6 +1293,8 @@ class UnraisableHookTest(unittest.TestCase):
# Check that the exception is printed with its qualified name
# rather than just classname, and the module names appears
# unless it is one of the hard-coded exclusions.
+ _testcapi = import_helper.import_module('_testcapi')
+ from _testcapi import err_writeunraisable
class A:
class B:
class X(Exception):
@@ -1304,9 +1306,7 @@ class UnraisableHookTest(unittest.TestCase):
with test.support.captured_stderr() as stderr, test.support.swap_attr(
sys, 'unraisablehook', sys.__unraisablehook__
):
- expected = self.write_unraisable_exc(
- A.B.X(), "msg", "obj"
- )
+ err_writeunraisable(A.B.X(), "obj")
report = stderr.getvalue()
self.assertIn(A.B.X.__qualname__, report)
if moduleName in ['builtins', '__main__']:
@@ -1322,34 +1322,45 @@ class UnraisableHookTest(unittest.TestCase):
sys.unraisablehook(exc)
def test_custom_unraisablehook(self):
+ _testcapi = import_helper.import_module('_testcapi')
+ from _testcapi import err_writeunraisable, err_formatunraisable
hook_args = None
def hook_func(args):
nonlocal hook_args
hook_args = args
- obj = object()
+ obj = hex
try:
with test.support.swap_attr(sys, 'unraisablehook', hook_func):
- expected = self.write_unraisable_exc(ValueError(42),
- "custom hook", obj)
- for attr in "exc_type exc_value exc_traceback err_msg object".split():
- self.assertEqual(getattr(hook_args, attr),
- getattr(expected, attr),
- (hook_args, expected))
+ exc = ValueError(42)
+ err_writeunraisable(exc, obj)
+ self.assertIs(hook_args.exc_type, type(exc))
+ self.assertIs(hook_args.exc_value, exc)
+ self.assertIs(hook_args.exc_traceback, exc.__traceback__)
+ self.assertIsNone(hook_args.err_msg)
+ self.assertEqual(hook_args.object, obj)
+
+ err_formatunraisable(exc, "custom hook %R", obj)
+ self.assertIs(hook_args.exc_type, type(exc))
+ self.assertIs(hook_args.exc_value, exc)
+ self.assertIs(hook_args.exc_traceback, exc.__traceback__)
+ self.assertEqual(hook_args.err_msg, f'custom hook {obj!r}')
+ self.assertIsNone(hook_args.object)
finally:
# expected and hook_args contain an exception: break reference cycle
expected = None
hook_args = None
def test_custom_unraisablehook_fail(self):
+ _testcapi = import_helper.import_module('_testcapi')
+ from _testcapi import err_writeunraisable
def hook_func(*args):
raise Exception("hook_func failed")
with test.support.captured_output("stderr") as stderr:
with test.support.swap_attr(sys, 'unraisablehook', hook_func):
- self.write_unraisable_exc(ValueError(42),
- "custom hook fail", None)
+ err_writeunraisable(ValueError(42), "custom hook fail")
err = stderr.getvalue()
self.assertIn(f'Exception ignored in sys.unraisablehook: '