3 from pybind11_tests
import exceptions
as m
4 import pybind11_cross_module_tests
as cm
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."
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"
18 with pytest
.raises(ValueError) as excinfo
:
19 m
.throw_already_set(True)
20 assert msg(excinfo
.value
) == "foo"
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"
28 with pytest
.raises(ValueError) as excinfo
:
29 cm
.raise_value_error()
30 assert str(excinfo
.value
) == "My value error"
32 with pytest
.raises(ValueError) as excinfo
:
33 cm
.throw_pybind_value_error()
34 assert str(excinfo
.value
) == "pybind11 value error"
36 with pytest
.raises(TypeError) as excinfo
:
37 cm
.throw_pybind_type_error()
38 assert str(excinfo
.value
) == "pybind11 type error"
40 with pytest
.raises(StopIteration) as excinfo
:
41 cm
.throw_stop_iteration()
44 def test_python_call_in_catch():
46 assert m
.python_call_in_destructor(d
) is True
47 assert d
["good"] is True
50 def test_exception_matches():
51 assert m
.exception_matches()
52 assert m
.exception_matches_base()
53 assert m
.modulenotfound_exception_matches_base()
57 # Can we catch a MyException?
58 with pytest
.raises(m
.MyException
) as excinfo
:
60 assert msg(excinfo
.value
) == "this error should go to a custom type"
62 # Can we translate to standard Python exceptions?
63 with pytest
.raises(RuntimeError) as excinfo
:
65 assert msg(excinfo
.value
) == "this error should go to a standard Python exception"
67 # Can we handle unknown exceptions?
68 with pytest
.raises(RuntimeError) as excinfo
:
70 assert msg(excinfo
.value
) == "Caught an unknown exception!"
72 # Can we delegate to another handler by rethrowing?
73 with pytest
.raises(m
.MyException
) as excinfo
:
75 assert msg(excinfo
.value
) == "this error is rethrown"
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"
82 # Can we handle a helper-declared exception?
83 with pytest
.raises(m
.MyException5
) as excinfo
:
85 assert msg(excinfo
.value
) == "this is a helper-defined translated exception"
87 # Exception subclassing:
88 with pytest
.raises(m
.MyException5
) as excinfo
:
90 assert msg(excinfo
.value
) == "MyException5 subclass"
91 assert isinstance(excinfo
.value
, m
.MyException5_1
)
93 with pytest
.raises(m
.MyException5_1
) as excinfo
:
95 assert msg(excinfo
.value
) == "MyException5 subclass"
97 with pytest
.raises(m
.MyException5
) as excinfo
:
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"
105 def test_nested_throws(capture
):
106 """Tests nested (e.g. C++ -> Python -> C++) exception handling"""
109 raise m
.MyException("nested error")
112 raise m
.MyException5("nested error 5")
114 # In the comments below, the exception is caught in the first step, thrown in the last step
118 m
.try_catch(m
.MyException5
, throw_myex5
)
119 assert str(capture
).startswith("MyException5: nested error 5")
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"
126 def pycatch(exctype
, f
, *args
):
129 except m
.MyException
as e
:
132 # C++ -> Python -> C++ -> Python
135 m
.MyException5
, pycatch
, m
.MyException
, m
.try_catch
, m
.MyException
, throw_myex5
)
136 assert str(capture
).startswith("MyException5: nested error 5")
138 # C++ -> Python -> C++
140 m
.try_catch(m
.MyException
, pycatch
, m
.MyException5
, m
.throws4
)
141 assert capture
== "this error is rethrown"
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"