diff --git a/tests/test_exceptions.cpp b/tests/test_exceptions.cpp index 01efc700e..7cfc5762b 100644 --- a/tests/test_exceptions.cpp +++ b/tests/test_exceptions.cpp @@ -58,48 +58,6 @@ class MyException5_1 : public MyException5 { using MyException5::MyException5; }; -void throws1() { - throw MyException("this error should go to a custom type"); -} - -void throws2() { - throw MyException2("this error should go to a standard Python exception"); -} - -void throws3() { - throw MyException3("this error cannot be translated"); -} - -void throws4() { - throw MyException4("this error is rethrown"); -} - -void throws5() { - throw MyException5("this is a helper-defined translated exception"); -} - -void throws5_1() { - throw MyException5_1("MyException5 subclass"); -} - -void throws_logic_error() { - throw std::logic_error("this error should fall through to the standard handler"); -} - -// Test error_already_set::matches() method -void exception_matches() { - py::dict foo; - try { - foo["bar"]; - } - catch (py::error_already_set& ex) { - if (ex.matches(PyExc_KeyError)) - ex.clear(); - else - throw; - } -} - struct PythonCallInDestructor { PythonCallInDestructor(const py::dict &d) : d(d) {} ~PythonCallInDestructor() { d["good"] = true; } @@ -107,7 +65,7 @@ struct PythonCallInDestructor { py::dict d; }; -test_initializer custom_exceptions([](py::module &m) { +TEST_SUBMODULE(exceptions, m) { m.def("throw_std_exception", []() { throw std::runtime_error("This exception was intentionally thrown."); }); @@ -151,14 +109,23 @@ test_initializer custom_exceptions([](py::module &m) { // A slightly more complicated one that declares MyException5_1 as a subclass of MyException5 py::register_exception(m, "MyException5_1", ex5.ptr()); - m.def("throws1", &throws1); - m.def("throws2", &throws2); - m.def("throws3", &throws3); - m.def("throws4", &throws4); - m.def("throws5", &throws5); - m.def("throws5_1", &throws5_1); - m.def("throws_logic_error", &throws_logic_error); - m.def("exception_matches", &exception_matches); + m.def("throws1", []() { throw MyException("this error should go to a custom type"); }); + m.def("throws2", []() { throw MyException2("this error should go to a standard Python exception"); }); + m.def("throws3", []() { throw MyException3("this error cannot be translated"); }); + m.def("throws4", []() { throw MyException4("this error is rethrown"); }); + m.def("throws5", []() { throw MyException5("this is a helper-defined translated exception"); }); + m.def("throws5_1", []() { throw MyException5_1("MyException5 subclass"); }); + m.def("throws_logic_error", []() { throw std::logic_error("this error should fall through to the standard handler"); }); + m.def("exception_matches", []() { + py::dict foo; + try { foo["bar"]; } + catch (py::error_already_set& ex) { + if (ex.matches(PyExc_KeyError)) + ex.clear(); + else + throw; + } + }); m.def("throw_already_set", [](bool err) { if (err) @@ -189,4 +156,4 @@ test_initializer custom_exceptions([](py::module &m) { } return false; }); -}); +} diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 15d47876f..cc4baaa09 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -1,87 +1,78 @@ import pytest +from pybind11_tests import exceptions as m + def test_std_exception(msg): - from pybind11_tests import throw_std_exception - with pytest.raises(RuntimeError) as excinfo: - throw_std_exception() + m.throw_std_exception() assert msg(excinfo.value) == "This exception was intentionally thrown." def test_error_already_set(msg): - from pybind11_tests import throw_already_set - with pytest.raises(RuntimeError) as excinfo: - throw_already_set(False) + m.throw_already_set(False) assert msg(excinfo.value) == "Unknown internal error occurred" with pytest.raises(ValueError) as excinfo: - throw_already_set(True) + m.throw_already_set(True) assert msg(excinfo.value) == "foo" def test_python_call_in_catch(): - from pybind11_tests import python_call_in_destructor - d = {} - assert python_call_in_destructor(d) is True + assert m.python_call_in_destructor(d) is True assert d["good"] is True def test_exception_matches(): - from pybind11_tests import exception_matches - exception_matches() + m.exception_matches() def test_custom(msg): - from pybind11_tests import (MyException, MyException5, MyException5_1, - throws1, throws2, throws3, throws4, throws5, throws5_1, - throws_logic_error) - - # Can we catch a MyException?" - with pytest.raises(MyException) as excinfo: - throws1() + # Can we catch a MyException? + with pytest.raises(m.MyException) as excinfo: + m.throws1() assert msg(excinfo.value) == "this error should go to a custom type" # Can we translate to standard Python exceptions? with pytest.raises(RuntimeError) as excinfo: - throws2() + m.throws2() assert msg(excinfo.value) == "this error should go to a standard Python exception" # Can we handle unknown exceptions? with pytest.raises(RuntimeError) as excinfo: - throws3() + m.throws3() assert msg(excinfo.value) == "Caught an unknown exception!" # Can we delegate to another handler by rethrowing? - with pytest.raises(MyException) as excinfo: - throws4() + with pytest.raises(m.MyException) as excinfo: + m.throws4() assert msg(excinfo.value) == "this error is rethrown" - # "Can we fall-through to the default handler?" + # Can we fall-through to the default handler? with pytest.raises(RuntimeError) as excinfo: - throws_logic_error() + m.throws_logic_error() assert msg(excinfo.value) == "this error should fall through to the standard handler" # Can we handle a helper-declared exception? - with pytest.raises(MyException5) as excinfo: - throws5() + with pytest.raises(m.MyException5) as excinfo: + m.throws5() assert msg(excinfo.value) == "this is a helper-defined translated exception" # Exception subclassing: - with pytest.raises(MyException5) as excinfo: - throws5_1() + with pytest.raises(m.MyException5) as excinfo: + m.throws5_1() assert msg(excinfo.value) == "MyException5 subclass" - assert isinstance(excinfo.value, MyException5_1) + assert isinstance(excinfo.value, m.MyException5_1) - with pytest.raises(MyException5_1) as excinfo: - throws5_1() + with pytest.raises(m.MyException5_1) as excinfo: + m.throws5_1() assert msg(excinfo.value) == "MyException5 subclass" - with pytest.raises(MyException5) as excinfo: + with pytest.raises(m.MyException5) as excinfo: try: - throws5() - except MyException5_1: + m.throws5() + except m.MyException5_1: raise RuntimeError("Exception error: caught child from parent") assert msg(excinfo.value) == "this is a helper-defined translated exception"