ext: Updated Pybind11 to version 2.4.1.
[gem5.git] / ext / pybind11 / tests / test_exceptions.py
1 import pytest
2
3 from pybind11_tests import exceptions as m
4 import pybind11_cross_module_tests as cm
5
6
7 def test_std_exception(msg):
8 with pytest.raises(RuntimeError) as excinfo:
9 m.throw_std_exception()
10 assert msg(excinfo.value) == "This exception was intentionally thrown."
11
12
13 def test_error_already_set(msg):
14 with pytest.raises(RuntimeError) as excinfo:
15 m.throw_already_set(False)
16 assert msg(excinfo.value) == "Unknown internal error occurred"
17
18 with pytest.raises(ValueError) as excinfo:
19 m.throw_already_set(True)
20 assert msg(excinfo.value) == "foo"
21
22
23 def test_cross_module_exceptions():
24 with pytest.raises(RuntimeError) as excinfo:
25 cm.raise_runtime_error()
26 assert str(excinfo.value) == "My runtime error"
27
28 with pytest.raises(ValueError) as excinfo:
29 cm.raise_value_error()
30 assert str(excinfo.value) == "My value error"
31
32 with pytest.raises(ValueError) as excinfo:
33 cm.throw_pybind_value_error()
34 assert str(excinfo.value) == "pybind11 value error"
35
36 with pytest.raises(TypeError) as excinfo:
37 cm.throw_pybind_type_error()
38 assert str(excinfo.value) == "pybind11 type error"
39
40 with pytest.raises(StopIteration) as excinfo:
41 cm.throw_stop_iteration()
42
43
44 def test_python_call_in_catch():
45 d = {}
46 assert m.python_call_in_destructor(d) is True
47 assert d["good"] is True
48
49
50 def test_exception_matches():
51 assert m.exception_matches()
52 assert m.exception_matches_base()
53 assert m.modulenotfound_exception_matches_base()
54
55
56 def test_custom(msg):
57 # Can we catch a MyException?
58 with pytest.raises(m.MyException) as excinfo:
59 m.throws1()
60 assert msg(excinfo.value) == "this error should go to a custom type"
61
62 # Can we translate to standard Python exceptions?
63 with pytest.raises(RuntimeError) as excinfo:
64 m.throws2()
65 assert msg(excinfo.value) == "this error should go to a standard Python exception"
66
67 # Can we handle unknown exceptions?
68 with pytest.raises(RuntimeError) as excinfo:
69 m.throws3()
70 assert msg(excinfo.value) == "Caught an unknown exception!"
71
72 # Can we delegate to another handler by rethrowing?
73 with pytest.raises(m.MyException) as excinfo:
74 m.throws4()
75 assert msg(excinfo.value) == "this error is rethrown"
76
77 # Can we fall-through to the default handler?
78 with pytest.raises(RuntimeError) as excinfo:
79 m.throws_logic_error()
80 assert msg(excinfo.value) == "this error should fall through to the standard handler"
81
82 # Can we handle a helper-declared exception?
83 with pytest.raises(m.MyException5) as excinfo:
84 m.throws5()
85 assert msg(excinfo.value) == "this is a helper-defined translated exception"
86
87 # Exception subclassing:
88 with pytest.raises(m.MyException5) as excinfo:
89 m.throws5_1()
90 assert msg(excinfo.value) == "MyException5 subclass"
91 assert isinstance(excinfo.value, m.MyException5_1)
92
93 with pytest.raises(m.MyException5_1) as excinfo:
94 m.throws5_1()
95 assert msg(excinfo.value) == "MyException5 subclass"
96
97 with pytest.raises(m.MyException5) as excinfo:
98 try:
99 m.throws5()
100 except m.MyException5_1:
101 raise RuntimeError("Exception error: caught child from parent")
102 assert msg(excinfo.value) == "this is a helper-defined translated exception"
103
104
105 def test_nested_throws(capture):
106 """Tests nested (e.g. C++ -> Python -> C++) exception handling"""
107
108 def throw_myex():
109 raise m.MyException("nested error")
110
111 def throw_myex5():
112 raise m.MyException5("nested error 5")
113
114 # In the comments below, the exception is caught in the first step, thrown in the last step
115
116 # C++ -> Python
117 with capture:
118 m.try_catch(m.MyException5, throw_myex5)
119 assert str(capture).startswith("MyException5: nested error 5")
120
121 # Python -> C++ -> Python
122 with pytest.raises(m.MyException) as excinfo:
123 m.try_catch(m.MyException5, throw_myex)
124 assert str(excinfo.value) == "nested error"
125
126 def pycatch(exctype, f, *args):
127 try:
128 f(*args)
129 except m.MyException as e:
130 print(e)
131
132 # C++ -> Python -> C++ -> Python
133 with capture:
134 m.try_catch(
135 m.MyException5, pycatch, m.MyException, m.try_catch, m.MyException, throw_myex5)
136 assert str(capture).startswith("MyException5: nested error 5")
137
138 # C++ -> Python -> C++
139 with capture:
140 m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)
141 assert capture == "this error is rethrown"
142
143 # Python -> C++ -> Python -> C++
144 with pytest.raises(m.MyException5) as excinfo:
145 m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)
146 assert str(excinfo.value) == "this is a helper-defined translated exception"