From d348f170f2cdbee98241acf4cb99c2a78632e883 Mon Sep 17 00:00:00 2001 From: Steinar Foss Date: Wed, 13 Nov 2019 15:03:47 +0100 Subject: [PATCH] PYBIND11_EMBEDDED_MODULE replaced by OPM_EMBEDDED_MODULE. python.cpp: PythonInterp created within contr. brackets. PYBIND11_EMBEDDED_MODULE commented out. opm_python: added file Embed.hpp. introduced macro OPM_EMBEDDED_MODULE. added opm_embedded_module. using opm_embedded_module. opm_embedded_module: commented out PyInstance check. added namespace Opm::embed. Embed.hpp -> EmbedModule.hpp. Python.cpp: added exception if PyIsinstance. parserstate: python is a unique_ptr. Parser.cpp: exception if no Opm::python obj. --- opm/parser/eclipse/Python/Python.hpp | 4 ++ src/opm/parser/eclipse/Parser/Parser.cpp | 12 +++- src/opm/parser/eclipse/Python/EmbedModule.hpp | 58 +++++++++++++++++++ src/opm/parser/eclipse/Python/Python.cpp | 12 +++- .../parser/eclipse/Python/PythonInterp.cpp | 3 +- .../parser/eclipse/Python/PythonInterp.hpp | 4 +- 6 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 src/opm/parser/eclipse/Python/EmbedModule.hpp diff --git a/opm/parser/eclipse/Python/Python.hpp b/opm/parser/eclipse/Python/Python.hpp index f33890e02..13c023f71 100644 --- a/opm/parser/eclipse/Python/Python.hpp +++ b/opm/parser/eclipse/Python/Python.hpp @@ -60,8 +60,12 @@ public: private: std::shared_ptr interp; }; + +std::unique_ptr PythonInstance(); + } + #endif diff --git a/src/opm/parser/eclipse/Parser/Parser.cpp b/src/opm/parser/eclipse/Parser/Parser.cpp index ea051399a..52c55bee1 100644 --- a/src/opm/parser/eclipse/Parser/Parser.cpp +++ b/src/opm/parser/eclipse/Parser/Parser.cpp @@ -356,7 +356,7 @@ class ParserState { std::string lastKeyWord; Deck deck; - Python python; + std::unique_ptr python; const ParseContext& parseContext; ErrorGuard& errors; bool unknown_keyword = false; @@ -411,6 +411,7 @@ ParserState::ParserState(const std::vector>& ErrorGuard& errors_arg) : code_keywords(code_keywords_arg), parseContext( __parseContext ), + python( PythonInstance() ), errors( errors_arg ) {} @@ -421,6 +422,7 @@ ParserState::ParserState( const std::vector> code_keywords(code_keywords_arg), rootPath( boost::filesystem::canonical( p ).parent_path() ), parseContext( context ), + python( PythonInstance() ), errors( errors_arg ) { openRootFile( p ); @@ -840,8 +842,12 @@ bool parseState( ParserState& parserState, const Parser& parser ) { } try { if (rawKeyword->getKeywordName() == Opm::RawConsts::pyinput) { - std::string python_string = rawKeyword->getFirstRecord().getRecordString(); - parserState.python.exec(python_string, parser, parserState.deck); + if (parserState.python) { + std::string python_string = rawKeyword->getFirstRecord().getRecordString(); + parserState.python->exec(python_string, parser, parserState.deck); + } + else + throw std::logic_error("Cannot yet embed Python while still running Python."); } else parserState.deck.addKeyword( parserKeyword.parse( parserState.parseContext, diff --git a/src/opm/parser/eclipse/Python/EmbedModule.hpp b/src/opm/parser/eclipse/Python/EmbedModule.hpp new file mode 100644 index 000000000..35c915b06 --- /dev/null +++ b/src/opm/parser/eclipse/Python/EmbedModule.hpp @@ -0,0 +1,58 @@ +/* +This Code is a copy paste of part of the contents of pybind11/embed.h +It allows for slightly changing the python embedding without changing the pybind11 sourcecode. +*/ + +#ifndef OPM_EMBED_MODULE +#define OPM_EMBED_MODULE + +#ifdef EMBEDDED_PYTHON +#include + +#define OPM_EMBEDDED_MODULE(name, variable) \ + static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ + static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \ + auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ + try { \ + PYBIND11_CONCAT(pybind11_init_, name)(m); \ + return m.ptr(); \ + } catch (pybind11::error_already_set &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } catch (const std::exception &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } \ + } \ + PYBIND11_EMBEDDED_MODULE_IMPL(name) \ + Opm::embed::python_module name(PYBIND11_TOSTRING(name), \ + PYBIND11_CONCAT(pybind11_init_impl_, name)); \ + void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) + +namespace Opm { +namespace embed { + +/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks. +struct python_module { +#if PY_MAJOR_VERSION >= 3 + using init_t = PyObject *(*)(); +#else + using init_t = void (*)(); +#endif + python_module(const char *name, init_t init) { + + auto result = PyImport_AppendInittab(name, init); + if (result == -1) + pybind11::pybind11_fail("Insufficient memory to add a new module"); + } +}; + +} +} + + + + +#endif + +#endif diff --git a/src/opm/parser/eclipse/Python/Python.cpp b/src/opm/parser/eclipse/Python/Python.cpp index 5d7e75c67..d6481b97f 100644 --- a/src/opm/parser/eclipse/Python/Python.cpp +++ b/src/opm/parser/eclipse/Python/Python.cpp @@ -23,12 +23,11 @@ namespace Opm { -Python::Python(): - interp(std::make_shared()) +Python::Python() : + interp(std::make_shared()) { } - bool Python::exec(const std::string& python_code) const { this->interp->exec(python_code); return true; @@ -50,5 +49,12 @@ Python::operator bool() const { return false; } +std::unique_ptr PythonInstance() { + if (Py_IsInitialized()) + return NULL; + + return std::make_unique(); +} + } diff --git a/src/opm/parser/eclipse/Python/PythonInterp.cpp b/src/opm/parser/eclipse/Python/PythonInterp.cpp index 7366ea256..6a511d795 100644 --- a/src/opm/parser/eclipse/Python/PythonInterp.cpp +++ b/src/opm/parser/eclipse/Python/PythonInterp.cpp @@ -27,11 +27,12 @@ #include "python/cxx/export.hpp" #include "PythonInterp.hpp" +#include "EmbedModule.hpp" namespace py = pybind11; namespace Opm { -PYBIND11_EMBEDDED_MODULE(context, module) { +OPM_EMBEDDED_MODULE(context, module) { python::common::export_all(module); } diff --git a/src/opm/parser/eclipse/Python/PythonInterp.hpp b/src/opm/parser/eclipse/Python/PythonInterp.hpp index 9388d932f..ca28ddc74 100644 --- a/src/opm/parser/eclipse/Python/PythonInterp.hpp +++ b/src/opm/parser/eclipse/Python/PythonInterp.hpp @@ -18,8 +18,8 @@ */ -#ifndef EMBEDDED_PYTHON_INTERP -#define EMBEDDED_PYTHON_INTERP +#ifndef PYTHON_INTERP +#define PYTHON_INTERP #include #include