##// END OF EJS Templates
whatsnew 8.31
whatsnew 8.31

File last commit:

r29028:5fbc6d29
r29036:5fc548f6
Show More
test_exceptiongroup_tb.py
103 lines | 3.2 KiB | text/x-python | PythonLexer
/ IPython / core / tests / test_exceptiongroup_tb.py
from IPython.utils.capture import capture_output
import pytest
def _exceptiongroup_common(
outer_chain: str,
inner_chain: str,
native: bool,
) -> None:
pre_raise = "exceptiongroup." if not native else ""
filestr = f"""
{"import exceptiongroup" if not native else ""}
import pytest
def f(): raise ValueError("From f()")
def g(): raise BaseException("From g()")
def inner(inner_chain):
excs = []
for callback in [f, g]:
try:
callback()
except BaseException as err:
excs.append(err)
if excs:
if inner_chain == "none":
raise {pre_raise}BaseExceptionGroup("Oops", excs)
try:
raise SyntaxError()
except SyntaxError as e:
if inner_chain == "from":
raise {pre_raise}BaseExceptionGroup("Oops", excs) from e
else:
raise {pre_raise}BaseExceptionGroup("Oops", excs)
def outer(outer_chain, inner_chain):
try:
inner(inner_chain)
except BaseExceptionGroup as e:
if outer_chain == "none":
raise
if outer_chain == "from":
raise IndexError() from e
else:
raise IndexError
outer("{outer_chain}", "{inner_chain}")
"""
with capture_output() as cap:
ip.run_cell(filestr)
match_lines = []
if inner_chain == "another":
match_lines += [
"During handling of the above exception, another exception occurred:",
]
elif inner_chain == "from":
match_lines += [
"The above exception was the direct cause of the following exception:",
]
match_lines += [
" + Exception Group Traceback (most recent call last):",
" | BaseExceptionGroup: Oops (2 sub-exceptions)",
" | ValueError: From f()",
" | BaseException: From g()",
]
if outer_chain == "another":
match_lines += [
"During handling of the above exception, another exception occurred:",
"IndexError",
]
elif outer_chain == "from":
match_lines += [
"The above exception was the direct cause of the following exception:",
"IndexError",
]
error_lines = cap.stderr.split("\n")
err_index = match_index = 0
for expected in match_lines:
for i, actual in enumerate(error_lines):
if actual == expected:
error_lines = error_lines[i + 1 :]
break
else:
assert False, f"{expected} not found in cap.stderr"
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
_exceptiongroup_common(outer_chain, inner_chain, native=True)
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
pytest.importorskip("exceptiongroup")
_exceptiongroup_common(outer_chain, inner_chain, native=False)