6 import pybind11_cross_module_tests
as cm
7 from pybind11_tests
import exceptions
as m
11 with pytest.raises(RuntimeError)
as excinfo:
12 m.throw_std_exception()
13 assert msg(excinfo.value) ==
"This exception was intentionally thrown." 17 with pytest.raises(RuntimeError)
as excinfo:
18 m.throw_already_set(
False)
21 ==
"Internal error: pybind11::error_already_set called while Python error indicator not set." 24 with pytest.raises(ValueError)
as excinfo:
25 m.throw_already_set(
True)
26 assert msg(excinfo.value) ==
"foo" 30 with pytest.raises(ValueError)
as excinfo:
32 assert msg(excinfo.value) ==
"outer" 33 assert msg(excinfo.value.__cause__) ==
"inner" 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(f
"ignore::pytest.{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":
117 default_hook(unraisable_hook_args)
121 monkeypatch.setattr(sys,
"unraisablehook", hook)
123 assert m.python_alreadyset_in_destructor(
"already_set demo")
is True 125 assert triggered
is True 127 _, captured_stderr = capsys.readouterr()
128 assert captured_stderr.startswith(
"Exception ignored in: 'already_set demo'")
129 assert captured_stderr.rstrip().endswith(
"KeyError: 'bar'")
133 assert m.exception_matches()
134 assert m.exception_matches_base()
135 assert m.modulenotfound_exception_matches_base()
140 with pytest.raises(m.MyException)
as excinfo:
142 assert msg(excinfo.value) ==
"this error should go to a custom type" 145 with pytest.raises(RuntimeError)
as excinfo:
147 assert msg(excinfo.value) ==
"this error should go to a standard Python exception" 150 with pytest.raises(RuntimeError)
as excinfo:
152 assert msg(excinfo.value) ==
"Caught an unknown exception!" 155 with pytest.raises(m.MyException)
as excinfo:
157 assert msg(excinfo.value) ==
"this error is rethrown" 160 with pytest.raises(RuntimeError)
as excinfo:
161 m.throws_logic_error()
163 msg(excinfo.value) ==
"this error should fall through to the standard handler" 167 with pytest.raises(OverflowError)
as excinfo:
168 m.throws_overflow_error()
171 with pytest.raises(m.MyException5)
as excinfo:
173 assert msg(excinfo.value) ==
"this is a helper-defined translated exception" 176 with pytest.raises(m.MyException5)
as excinfo:
178 assert msg(excinfo.value) ==
"MyException5 subclass" 179 assert isinstance(excinfo.value, m.MyException5_1)
181 with pytest.raises(m.MyException5_1)
as excinfo:
183 assert msg(excinfo.value) ==
"MyException5 subclass" 185 with pytest.raises(m.MyException5)
as excinfo:
188 except m.MyException5_1:
189 raise RuntimeError(
"Exception error: caught child from parent")
190 assert msg(excinfo.value) ==
"this is a helper-defined translated exception" 194 """Tests nested (e.g. C++ -> Python -> C++) exception handling""" 197 raise m.MyException(
"nested error")
200 raise m.MyException5(
"nested error 5")
206 m.try_catch(m.MyException5, throw_myex5)
207 assert str(capture).startswith(
"MyException5: nested error 5")
210 with pytest.raises(m.MyException)
as excinfo:
211 m.try_catch(m.MyException5, throw_myex)
212 assert str(excinfo.value) ==
"nested error" 214 def pycatch(exctype, f, *args):
217 except m.MyException
as e:
230 assert str(capture).startswith(
"MyException5: nested error 5")
234 m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)
235 assert capture ==
"this error is rethrown" 238 with pytest.raises(m.MyException5)
as excinfo:
239 m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)
240 assert str(excinfo.value) ==
"this is a helper-defined translated exception" 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" 280 if failure_point ==
"failure_point_init":
281 raise ValueError(
"triggered_failure_point_init")
286 raise ValueError(
"triggered_failure_point_str")
287 return "FlakyException.__str__" 290 @pytest.mark.parametrize(
291 "exc_type, exc_value, expected_what",
293 (ValueError,
"plain_str",
"ValueError: plain_str"),
294 (ValueError, (
"tuple_elem",),
"ValueError: tuple_elem"),
295 (FlakyException, (
"happy",),
"FlakyException: FlakyException.__str__"),
299 exc_type, exc_value, expected_what
301 what, py_err_set_after_what = m.error_already_set_what(exc_type, exc_value)
302 assert not py_err_set_after_what
303 assert what == expected_what
306 @pytest.mark.skipif(
"env.PYPY", reason=
"PyErr_NormalizeException Segmentation fault")
308 with pytest.raises(RuntimeError)
as excinfo:
309 m.error_already_set_what(FlakyException, (
"failure_point_init",))
310 lines =
str(excinfo.value).splitlines()
312 assert lines[:3] == [
313 "pybind11::error_already_set: MISMATCH of original and normalized active exception types:" 314 " ORIGINAL FlakyException REPLACED BY ValueError: triggered_failure_point_init",
319 assert "test_exceptions.py(" in lines[3]
320 assert lines[3].endswith(
"): __init__")
321 assert lines[4].endswith(
"): test_flaky_exception_failure_point_init")
325 what, py_err_set_after_what = m.error_already_set_what(
326 FlakyException, (
"failure_point_str",)
328 assert not py_err_set_after_what
329 lines = what.splitlines()
330 if env.PYPY
and len(lines) == 3:
337 "FlakyException: <MESSAGE UNAVAILABLE DUE TO ANOTHER EXCEPTION>",
339 "MESSAGE UNAVAILABLE DUE TO EXCEPTION: ValueError: triggered_failure_point_str",
347 with pytest.raises(RuntimeError)
as excinfo:
348 m.test_cross_module_interleaved_error_already_set()
349 assert str(excinfo.value)
in (
351 "RuntimeError: 2nd error.",
356 m.test_error_already_set_double_restore(
True)
357 with pytest.raises(RuntimeError)
as excinfo:
358 m.test_error_already_set_double_restore(
False)
359 assert str(excinfo.value) == (
360 "Internal error: pybind11::detail::error_fetch_and_normalize::restore()" 361 " called a second time. ORIGINAL ERROR: ValueError: Random error." def test_flaky_exception_failure_point_init()
def test_cross_module_exceptions(msg)
def test_error_already_set_double_restore()
def test_std_exception(msg)
def test_flaky_exception_failure_point_str()
bool hasattr(handle obj, handle name)
def test_cross_module_exception_translator()
def test_exception_matches()
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
def ignore_pytest_unraisable_warning(f)
def test_error_already_set(msg)
def __init__(self, failure_point)
bool isinstance(handle obj)
def test_python_alreadyset_in_destructor(monkeypatch, capsys)
def test_local_translator(msg)
def test_throw_nested_exception()
def test_cross_module_interleaved_error_already_set()
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
def test_python_call_in_catch()
def test_raise_from_already_set(msg)
def test_error_already_set_what_with_happy_exceptions(exc_type, exc_value, expected_what)
def test_nested_throws(capture)
size_t len(handle h)
Get the length of a Python object.