From a8f0ebb1834455f721282a28c43b86a8ad8e50c1 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 26 Mar 2020 12:00:59 +0100 Subject: [PATCH] Enable fine grained control of Python ON | OFF --- opm/parser/eclipse/Python/Python.hpp | 35 ++++++++++++++++++++++++ src/opm/parser/eclipse/Python/Python.cpp | 21 ++++++++++++-- tests/parser/EmbeddedPython.cpp | 31 +++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/opm/parser/eclipse/Python/Python.hpp b/opm/parser/eclipse/Python/Python.hpp index fd50ed2c2..ab488317e 100644 --- a/opm/parser/eclipse/Python/Python.hpp +++ b/opm/parser/eclipse/Python/Python.hpp @@ -52,10 +52,45 @@ class EclipseState; else OpmLog::Error("This version of opmcommon has been built with support for embedded Python"); + + The default constructor will enable the Python interpreter if the current + version of opm-common has been built support for embedded Python, by using the + alternative Python(Enable enable) constructor you can explicitly say if you + want Python support or not; if that request can not be satisfied you will get + std::logic_error(). + + Observe that the real underlying Python interpreter is essentially a singleton + - i.e. only a one interpreter can be active at any time. The details of the + interaction between build configuration, constructor arg and multiple + instances is as follows: + + + Build: | Constructor arg | Existing instance | Result + ---------|--------------------|---------------------|------- + True | OFF | * | { } + True | ON | False | { Python } + True | ON | True | std::logic_error + True | COND | True | { } + True | COND | False | { Python } + False | OFF | * | { } + False | ON | * | std::logic_error + False | COND | * | { } + ---------|--------------------|---------------------|------- + + */ + class Python { public: + + enum class Enable { + ON, /* Enable the Python extensions - throw std::logic_error() if it fails. */ + COND, /* Try to enable Python extensions*/ + OFF /* Do not enable Python */ + }; + + explicit Python(Enable enable); Python(); bool exec(const std::string& python_code) const; bool exec(const std::string& python_code, const Parser& parser, Deck& deck) const; diff --git a/src/opm/parser/eclipse/Python/Python.cpp b/src/opm/parser/eclipse/Python/Python.cpp index 829fe27c7..eed6fecfa 100644 --- a/src/opm/parser/eclipse/Python/Python.cpp +++ b/src/opm/parser/eclipse/Python/Python.cpp @@ -24,8 +24,25 @@ namespace Opm { -Python::Python() : - interp(std::make_shared()) +Python::Python(Enable enable) { + if (enable == Enable::OFF) + return; + +#ifdef EMBEDDED_PYTHON + if (!Py_IsInitialized()) + this->interp = std::make_shared(); + else if (enable == Enable::ON) + throw std::logic_error("An instance of the Python interpreter is already running"); + + return; +#endif + + if (enable == Enable::ON) + throw std::logic_error("The version has been built without Python support"); +} + + +Python::Python() : Python(Enable::COND) { } diff --git a/tests/parser/EmbeddedPython.cpp b/tests/parser/EmbeddedPython.cpp index abf2115bf..dcdb6cdb9 100644 --- a/tests/parser/EmbeddedPython.cpp +++ b/tests/parser/EmbeddedPython.cpp @@ -41,6 +41,14 @@ BOOST_AUTO_TEST_CASE(INSTANTIATE) { BOOST_CHECK(!python); BOOST_CHECK_THROW(python.exec("print('Hello world')"), std::logic_error); BOOST_CHECK(! Python::enabled() ); + + + BOOST_CHECK_THROW( Python(Python::Enable::ON), std::logic_error ); + Python python_cond(Python::Enable::COND); + BOOST_CHECK(!python_cond); + + Python python_off(Python::Enable::OFF); + BOOST_CHECK(!python_off); } #else @@ -129,6 +137,29 @@ BOOST_AUTO_TEST_CASE(PYACTION) { } +BOOST_AUTO_TEST_CASE(Python_Constructor) { + Python python_off(Python::Enable::OFF); + BOOST_CHECK(!python_off); + + Python python_on(Python::Enable::ON); + BOOST_CHECK(python_on); + + // Can only have one Python interpreter active at any time + BOOST_CHECK_THROW(Python(Python::Enable::ON), std::logic_error); +} + +BOOST_AUTO_TEST_CASE(Python_Constructor2) { + Python python_cond1(Python::Enable::COND); + BOOST_CHECK(python_cond1); + + Python python_cond2(Python::Enable::COND); + BOOST_CHECK(!python_cond2); +} + #endif + + + +