diff --git a/docs/changelog.rst b/docs/changelog.rst index 606be413aa..fb7fe4546f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -50,6 +50,10 @@ v2.3.0 (Not yet released) * ``pybind11/stl.h`` does not convert strings to ``vector`` anymore. `#1258 `_. +* Add a ``PYBIND11_NOEXCEPTIONS`` identifier that allows for compilation + without exceptions enabled. Importing a python module with this identifier + that throws an exception will call ``std::terminate()``. + v2.2.4 (September 11, 2018) ----------------------------------------------------- diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 5ff74856b1..8d65cfece3 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -252,6 +252,16 @@ extern "C" { return m.ptr(); } \endrst */ +#if defined(PYBIND11_NOEXCEPTIONS) +#define PYBIND11_PLUGIN(name) \ + PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \ + static PyObject *pybind11_init(); \ + PYBIND11_PLUGIN_IMPL(name) { \ + PYBIND11_CHECK_PYTHON_VERSION \ + return pybind11_init(); \ + } \ + PyObject *pybind11_init() +#else #define PYBIND11_PLUGIN(name) \ PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \ static PyObject *pybind11_init(); \ @@ -262,6 +272,7 @@ extern "C" { } PYBIND11_CATCH_INIT_EXCEPTIONS \ } \ PyObject *pybind11_init() +#endif /** \rst This macro creates the entry point that will be invoked when the Python interpreter @@ -280,6 +291,17 @@ extern "C" { }); } \endrst */ +#if defined(PYBIND11_NOEXCEPTIONS) +#define PYBIND11_MODULE(name, variable) \ + static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ + PYBIND11_PLUGIN_IMPL(name) { \ + PYBIND11_CHECK_PYTHON_VERSION \ + auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ + PYBIND11_CONCAT(pybind11_init_, name)(m); \ + return m.ptr(); \ + } \ + void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) +#else #define PYBIND11_MODULE(name, variable) \ static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ PYBIND11_PLUGIN_IMPL(name) { \ @@ -291,6 +313,7 @@ extern "C" { } PYBIND11_CATCH_INIT_EXCEPTIONS \ } \ void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) +#endif NAMESPACE_BEGIN(PYBIND11_NAMESPACE) diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 6d7dc5cfe9..a1b753f36d 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -215,6 +215,7 @@ PYBIND11_NOINLINE inline internals &get_internals() { builtins[id] = capsule(internals_pp); internals_ptr->registered_exception_translators.push_front( [](std::exception_ptr p) -> void { +#if !defined(PYBIND11_NOEXCEPTIONS) try { if (p) std::rethrow_exception(p); } catch (error_already_set &e) { e.restore(); return; @@ -230,6 +231,7 @@ PYBIND11_NOINLINE inline internals &get_internals() { PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!"); return; } +#endif } ); internals_ptr->static_property_type = make_static_property_type(); diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 785c1c0067..19ed8f8c81 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -661,7 +661,9 @@ class cpp_function : public function { } } } catch (error_already_set &e) { +#if !defined(PYBIND11_NOEXCEPTIONS) e.restore(); +#endif return nullptr; } catch (...) { /* When an exception is caught, give each registered exception @@ -1784,6 +1786,7 @@ NAMESPACE_END(detail) * This is intended for simple exception translations; for more complex translation, register the * exception object and translator directly. */ +#if !defined(PYBIND11_NOEXCEPTIONS) template exception ®ister_exception(handle scope, const char *name, @@ -1801,6 +1804,7 @@ exception ®ister_exception(handle scope, }); return ex; } +#endif NAMESPACE_BEGIN(detail) PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) {