forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pythongh-93649: Split exception tests from _testcapimodule.c (pythonG…
…H-102173) Automerge-Triggered-By: GH:erlend-aasland
- Loading branch information
1 parent
19b5e22
commit 2131bed
Showing
8 changed files
with
434 additions
and
416 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import re | ||
import sys | ||
import unittest | ||
|
||
from test import support | ||
from test.support import import_helper | ||
from test.support.script_helper import assert_python_failure | ||
|
||
from .test_misc import decode_stderr | ||
|
||
# Skip this test if the _testcapi module isn't available. | ||
_testcapi = import_helper.import_module('_testcapi') | ||
|
||
class Test_Exceptions(unittest.TestCase): | ||
|
||
def test_exception(self): | ||
raised_exception = ValueError("5") | ||
new_exc = TypeError("TEST") | ||
try: | ||
raise raised_exception | ||
except ValueError as e: | ||
orig_sys_exception = sys.exception() | ||
orig_exception = _testcapi.set_exception(new_exc) | ||
new_sys_exception = sys.exception() | ||
new_exception = _testcapi.set_exception(orig_exception) | ||
reset_sys_exception = sys.exception() | ||
|
||
self.assertEqual(orig_exception, e) | ||
|
||
self.assertEqual(orig_exception, raised_exception) | ||
self.assertEqual(orig_sys_exception, orig_exception) | ||
self.assertEqual(reset_sys_exception, orig_exception) | ||
self.assertEqual(new_exception, new_exc) | ||
self.assertEqual(new_sys_exception, new_exception) | ||
else: | ||
self.fail("Exception not raised") | ||
|
||
def test_exc_info(self): | ||
raised_exception = ValueError("5") | ||
new_exc = TypeError("TEST") | ||
try: | ||
raise raised_exception | ||
except ValueError as e: | ||
tb = e.__traceback__ | ||
orig_sys_exc_info = sys.exc_info() | ||
orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None) | ||
new_sys_exc_info = sys.exc_info() | ||
new_exc_info = _testcapi.set_exc_info(*orig_exc_info) | ||
reset_sys_exc_info = sys.exc_info() | ||
|
||
self.assertEqual(orig_exc_info[1], e) | ||
|
||
self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb)) | ||
self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info) | ||
self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info) | ||
self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None)) | ||
self.assertSequenceEqual(new_sys_exc_info, new_exc_info) | ||
else: | ||
self.assertTrue(False) | ||
|
||
|
||
class Test_FatalError(unittest.TestCase): | ||
|
||
def check_fatal_error(self, code, expected, not_expected=()): | ||
with support.SuppressCrashReport(): | ||
rc, out, err = assert_python_failure('-sSI', '-c', code) | ||
|
||
err = decode_stderr(err) | ||
self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n', | ||
err) | ||
|
||
match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$', | ||
err, re.MULTILINE) | ||
if not match: | ||
self.fail(f"Cannot find 'Extension modules:' in {err!r}") | ||
modules = set(match.group(1).strip().split(', ')) | ||
total = int(match.group(2)) | ||
|
||
for name in expected: | ||
self.assertIn(name, modules) | ||
for name in not_expected: | ||
self.assertNotIn(name, modules) | ||
self.assertEqual(len(modules), total) | ||
|
||
@support.requires_subprocess() | ||
def test_fatal_error(self): | ||
# By default, stdlib extension modules are ignored, | ||
# but not test modules. | ||
expected = ('_testcapi',) | ||
not_expected = ('sys',) | ||
code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")' | ||
self.check_fatal_error(code, expected, not_expected) | ||
|
||
# Mark _testcapi as stdlib module, but not sys | ||
expected = ('sys',) | ||
not_expected = ('_testcapi',) | ||
code = """if True: | ||
import _testcapi, sys | ||
sys.stdlib_module_names = frozenset({"_testcapi"}) | ||
_testcapi.fatal_error(b"MESSAGE") | ||
""" | ||
self.check_fatal_error(code, expected) | ||
|
||
|
||
class Test_ErrSetAndRestore(unittest.TestCase): | ||
|
||
def test_err_set_raised(self): | ||
with self.assertRaises(ValueError): | ||
_testcapi.err_set_raised(ValueError()) | ||
v = ValueError() | ||
try: | ||
_testcapi.err_set_raised(v) | ||
except ValueError as ex: | ||
self.assertIs(v, ex) | ||
|
||
def test_err_restore(self): | ||
with self.assertRaises(ValueError): | ||
_testcapi.err_restore(ValueError) | ||
with self.assertRaises(ValueError): | ||
_testcapi.err_restore(ValueError, 1) | ||
with self.assertRaises(ValueError): | ||
_testcapi.err_restore(ValueError, 1, None) | ||
with self.assertRaises(ValueError): | ||
_testcapi.err_restore(ValueError, ValueError()) | ||
try: | ||
_testcapi.err_restore(KeyError, "hi") | ||
except KeyError as k: | ||
self.assertEqual("hi", k.args[0]) | ||
try: | ||
1/0 | ||
except Exception as e: | ||
tb = e.__traceback__ | ||
with self.assertRaises(ValueError): | ||
_testcapi.err_restore(ValueError, 1, tb) | ||
with self.assertRaises(TypeError): | ||
_testcapi.err_restore(ValueError, 1, 0) | ||
try: | ||
_testcapi.err_restore(ValueError, 1, tb) | ||
except ValueError as v: | ||
self.assertEqual(1, v.args[0]) | ||
self.assertIs(tb, v.__traceback__.tb_next) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.