##// END OF EJS Templates
add tests, fix exceptiongroup dependency, add doc requirement in another place
jakkdl -
Show More
@@ -0,0 +1,109 b''
1 import unittest
2 import re
3 from IPython.utils.capture import capture_output
4 import sys
5 import pytest
6 from tempfile import TemporaryDirectory
7 from IPython.testing import tools as tt
8
9 def _exceptiongroup_common(
10 outer_chain: str,
11 inner_chain: str,
12 native: bool,
13 ) -> None:
14 pre_raise = "exceptiongroup." if not native else ""
15 pre_catch = pre_raise if sys.version_info < (3, 11) else ""
16 filestr = f"""
17 {"import exceptiongroup" if not native else ""}
18 import pytest
19
20 def f(): raise ValueError("From f()")
21 def g(): raise BaseException("From g()")
22
23 def inner(inner_chain):
24 excs = []
25 for callback in [f, g]:
26 try:
27 callback()
28 except BaseException as err:
29 excs.append(err)
30 if excs:
31 if inner_chain == "none":
32 raise {pre_raise}BaseExceptionGroup("Oops", excs)
33 try:
34 raise SyntaxError()
35 except SyntaxError as e:
36 if inner_chain == "from":
37 raise {pre_raise}BaseExceptionGroup("Oops", excs) from e
38 else:
39 raise {pre_raise}BaseExceptionGroup("Oops", excs)
40
41 def outer(outer_chain, inner_chain):
42 try:
43 inner(inner_chain)
44 except {pre_catch}BaseExceptionGroup as e:
45 if outer_chain == "none":
46 raise
47 if outer_chain == "from":
48 raise IndexError() from e
49 else:
50 raise IndexError
51
52
53 outer("{outer_chain}", "{inner_chain}")
54 """
55 with capture_output() as cap:
56 ip.run_cell(filestr)
57
58 match_lines = []
59 if inner_chain == "another":
60 match_lines += [
61 "During handling of the above exception, another exception occurred:",
62 ]
63 elif inner_chain == 'from':
64 match_lines += [
65 "The above exception was the direct cause of the following exception:",
66 ]
67
68 match_lines += [
69 " + Exception Group Traceback (most recent call last):",
70 f" | {pre_catch}BaseExceptionGroup: Oops (2 sub-exceptions)",
71 " | ValueError: From f()",
72 " | BaseException: From g()",
73 ]
74
75 if outer_chain == "another":
76 match_lines += [
77 "During handling of the above exception, another exception occurred:",
78 "IndexError",
79 ]
80 elif outer_chain == "from":
81 match_lines += [
82 "The above exception was the direct cause of the following exception:",
83 "IndexError",
84 ]
85
86 error_lines = cap.stderr.split("\n")
87
88 err_index = match_index = 0
89 for expected in match_lines:
90 for i,actual in enumerate(error_lines):
91 if actual == expected:
92 error_lines = error_lines[i+1:]
93 break
94 else:
95 assert False, f'{expected} not found in cap.stderr'
96
97 @pytest.mark.skipif(
98 sys.version_info < (3, 11), reason="Native ExceptionGroup not implemented"
99 )
100 @pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
101 @pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
102 def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
103 _exceptiongroup_common(outer_chain, inner_chain, native=True)
104
105 @pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
106 @pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
107 def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
108 pytest.importorskip("exceptiongroup")
109 _exceptiongroup_common(outer_chain, inner_chain, native=False)
@@ -8,6 +8,7 b' dependencies:'
8 - sphinx>=4.2
8 - sphinx>=4.2
9 - sphinx_rtd_theme
9 - sphinx_rtd_theme
10 - numpy
10 - numpy
11 - exceptiongroup
11 - testpath
12 - testpath
12 - matplotlib
13 - matplotlib
13 - pip
14 - pip
@@ -33,7 +33,7 b' install_requires ='
33 backcall
33 backcall
34 colorama; sys_platform == "win32"
34 colorama; sys_platform == "win32"
35 decorator
35 decorator
36 exceptiongroup; python_version<'3.10'
36 exceptiongroup; python_version<'3.11'
37 jedi>=0.16
37 jedi>=0.16
38 matplotlib-inline
38 matplotlib-inline
39 pexpect>4.3; sys_platform != "win32"
39 pexpect>4.3; sys_platform != "win32"
General Comments 0
You need to be logged in to leave comments. Login now