7import pybind11_cross_module_tests
as cm
8from pybind11_tests
import exceptions
as m
12 with pytest.raises(RuntimeError)
as excinfo:
13 m.throw_std_exception()
14 assert msg(excinfo.value) ==
"This exception was intentionally thrown."
18 with pytest.raises(RuntimeError)
as excinfo:
19 m.throw_already_set(
False)
20 assert msg(excinfo.value) ==
"Unknown internal error occurred"
22 with pytest.raises(ValueError)
as excinfo:
23 m.throw_already_set(
True)
24 assert msg(excinfo.value) ==
"foo"
27@pytest.mark.skipif("env.PY2")
29 with pytest.raises(ValueError)
as excinfo:
31 assert msg(excinfo.value) ==
"outer"
32 assert msg(excinfo.value.__cause__) ==
"inner"
35@pytest.mark.skipif("env.PY2")
37 with pytest.raises(ValueError)
as excinfo:
38 m.raise_from_already_set()
39 assert msg(excinfo.value) ==
"outer"
40 assert msg(excinfo.value.__cause__) ==
"inner"
44 with pytest.raises(RuntimeError)
as excinfo:
45 cm.raise_runtime_error()
46 assert str(excinfo.value) ==
"My runtime error"
48 with pytest.raises(ValueError)
as excinfo:
49 cm.raise_value_error()
50 assert str(excinfo.value) ==
"My value error"
52 with pytest.raises(ValueError)
as excinfo:
53 cm.throw_pybind_value_error()
54 assert str(excinfo.value) ==
"pybind11 value error"
56 with pytest.raises(TypeError)
as excinfo:
57 cm.throw_pybind_type_error()
58 assert str(excinfo.value) ==
"pybind11 type error"
60 with pytest.raises(StopIteration)
as excinfo:
61 cm.throw_stop_iteration()
63 with pytest.raises(cm.LocalSimpleException)
as excinfo:
64 cm.throw_local_simple_error()
65 assert msg(excinfo.value) ==
"external mod"
67 with pytest.raises(KeyError)
as excinfo:
68 cm.throw_local_error()
70 assert str(excinfo.value) ==
"'just local'"
75 "env.PYPY and env.MACOS",
77 reason=
"Expected failure with PyPy and libc++ (Issue #2847 & PR #2999)",
80 with pytest.raises(KeyError):
82 m.throw_should_be_translated_to_key_error()
87 assert m.python_call_in_destructor(d)
is True
88 assert d[
"good"]
is True
92 unraisable =
"PytestUnraisableExceptionWarning"
94 dec = pytest.mark.filterwarnings(
"ignore::pytest.{}".format(unraisable))
101@pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False)
102@ignore_pytest_unraisable_warning
107 if hasattr(sys,
"unraisablehook"):
110 default_hook = sys.__unraisablehook__
112 def hook(unraisable_hook_args):
113 exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args
114 if obj ==
"already_set demo":
116 default_hook(unraisable_hook_args)
120 monkeypatch.setattr(sys,
"unraisablehook", hook)
122 assert m.python_alreadyset_in_destructor(
"already_set demo")
is True
124 assert triggered[0]
is True
126 _, captured_stderr = capsys.readouterr()
128 assert "ignored" in captured_stderr
and "already_set demo" in captured_stderr
132 assert m.exception_matches()
133 assert m.exception_matches_base()
134 assert m.modulenotfound_exception_matches_base()
139 with pytest.raises(m.MyException)
as excinfo:
141 assert msg(excinfo.value) ==
"this error should go to a custom type"
144 with pytest.raises(RuntimeError)
as excinfo:
146 assert msg(excinfo.value) ==
"this error should go to a standard Python exception"
149 with pytest.raises(RuntimeError)
as excinfo:
151 assert msg(excinfo.value) ==
"Caught an unknown exception!"
154 with pytest.raises(m.MyException)
as excinfo:
156 assert msg(excinfo.value) ==
"this error is rethrown"
159 with pytest.raises(RuntimeError)
as excinfo:
160 m.throws_logic_error()
162 msg(excinfo.value) ==
"this error should fall through to the standard handler"
166 with pytest.raises(OverflowError)
as excinfo:
167 m.throws_overflow_error()
170 with pytest.raises(m.MyException5)
as excinfo:
172 assert msg(excinfo.value) ==
"this is a helper-defined translated exception"
175 with pytest.raises(m.MyException5)
as excinfo:
177 assert msg(excinfo.value) ==
"MyException5 subclass"
178 assert isinstance(excinfo.value, m.MyException5_1)
180 with pytest.raises(m.MyException5_1)
as excinfo:
182 assert msg(excinfo.value) ==
"MyException5 subclass"
184 with pytest.raises(m.MyException5)
as excinfo:
187 except m.MyException5_1:
188 raise RuntimeError(
"Exception error: caught child from parent")
189 assert msg(excinfo.value) ==
"this is a helper-defined translated exception"
193 """Tests nested (e.g. C++ -> Python -> C++) exception handling"""
196 raise m.MyException(
"nested error")
199 raise m.MyException5(
"nested error 5")
205 m.try_catch(m.MyException5, throw_myex5)
206 assert str(capture).startswith(
"MyException5: nested error 5")
209 with pytest.raises(m.MyException)
as excinfo:
210 m.try_catch(m.MyException5, throw_myex)
211 assert str(excinfo.value) ==
"nested error"
213 def pycatch(exctype, f, *args):
216 except m.MyException
as e:
229 assert str(capture).startswith(
"MyException5: nested error 5")
233 m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)
234 assert capture ==
"this error is rethrown"
237 with pytest.raises(m.MyException5)
as excinfo:
238 m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)
239 assert str(excinfo.value) ==
"this is a helper-defined translated exception"
242@pytest.mark.skipif("env.PY2")
244 with pytest.raises(RuntimeError)
as excinfo:
245 m.throw_nested_exception()
246 assert str(excinfo.value) ==
"Outer Exception"
247 assert str(excinfo.value.__cause__) ==
"Inner Exception"
254 raise AttributeError(
"Example error")
256 with pytest.raises(TypeError):
257 m.simple_bool_passthrough(MyRepr())
261 """Tests that a local translator works and that the local translator from
262 the cross module is not applied
"""
263 with pytest.raises(RuntimeError)
as excinfo:
265 assert msg(excinfo.value) ==
"MyException6 only handled in this module"
267 with pytest.raises(RuntimeError)
as excinfo:
268 m.throws_local_error()
269 assert not isinstance(excinfo.value, KeyError)
270 assert msg(excinfo.value) ==
"never caught"
272 with pytest.raises(Exception)
as excinfo:
273 m.throws_local_simple_error()
274 assert not isinstance(excinfo.value, cm.LocalSimpleException)
275 assert msg(excinfo.value) ==
"this mod"
\rst Holds a reference to a Python object (with reference counting)
bool hasattr(handle obj, handle name)
bool isinstance(handle obj)
\rst Return true if obj is an instance of T.
def test_local_translator(msg)
def ignore_pytest_unraisable_warning(f)
def test_exception_matches()
def test_throw_nested_exception()
def test_cross_module_exceptions(msg)
def test_raise_from_already_set(msg)
def test_python_alreadyset_in_destructor(monkeypatch, capsys)
def test_python_call_in_catch()
def test_std_exception(msg)
def test_cross_module_exception_translator()
def test_error_already_set(msg)
def test_nested_throws(capture)