My Project
Python.hpp
1 /*
2  Copyright 2019 Equinor ASA.
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef OPM_PYTHON_HPP
21 #define OPM_PYTHON_HPP
22 
23 #include <memory>
24 #include <string>
25 
26 namespace Opm {
27 class PythonInterp;
28 class Parser;
29 class Deck;
30 class SummaryState;
31 class Schedule;
32 class EclipseState;
33 
34 namespace Action {
35  class PyAction;
36 }
37 /*
38  This class is a thin wrapper around the PythonInterp class. The Python class
39  can always be safely instantiated, but the actual PythonInterp implementation
40  depends on whether Python support was enabled when this library instance was
41  compiled.
42 
43  If one the methods actually invoking the Python interpreter is invoked without
44  proper Python support a dummy PythinInterp instance will be used; and that
45  will just throw std::logic_error. The operator bool can be used to check if
46  this Python manager indeed has a valid Python runtime:
47 
48 
49  auto python = std::make_shared<Python>();
50 
51  if (python)
52  python.exec("print('Hello world')")
53  else
54  OpmLog::Error("This version of opmcommon has been built with support for embedded Python");
55 
56 
57  The default constructor will enable the Python interpreter if the current
58  version of opm-common has been built support for embedded Python, by using the
59  alternative Python(Enable enable) constructor you can explicitly say if you
60  want Python support or not; if that request can not be satisfied you will get
61  std::logic_error().
62 
63  Observe that the real underlying Python interpreter is essentially a singleton
64  - i.e. only a one interpreter can be active at any time. If a Python
65  interpreter has already been instantiated you can still create an additional
66  Opm::Python instance, but that will be empty and not capable of actually
67  running Python code - so although it is technically possible to have more than
68  simultaneous Opm::Python instance it is highly recommended to create only one.
69 
70  The details of the interaction between build configuration, constructor arg
71  and multiple instances is summarized in the table below. The columns should be
72  interpreted as follows:
73 
74  Build: This is whether opm has been built with support for embedding Python,
75  i.e. whether the flag OPM_ENABLE_EMBEDDED_PYTHON was set to True at
76  configure time.
77 
78  Constructor arg: This the enum argument passed to the constructor. The
79  default value is Enable::TRY which means that we will try to instantiate
80  a Python interpreter. If that fails - either because a Python interpreter
81  is already running or because opm-common has been built without Python
82  support - you will get a empty but valid Opm::Python object back.
83 
84  Existing instance: Is there already Python interpreter running? The value *
85  implies that the end result will be the same irrespective of whether we
86  have a Python instance running.
87 
88  Result: What kind of Opm::Python instance will we get - here { } implies an
89  empty Opm::Python instance. This does *not* hold on to an actual
90  interpreter and can not be used to run code - for this type of
91  Opm::Python instance the enabled() method will return false. { Python }
92  means that we will get a Opm::Python instance which manages a true Python
93  interpreter.
94 
95  std::logic_error means that you have asked for something which can not be
96  satisfied and std::logic_error exception will be raised.
97 
98 
99  Build: | Constructor arg | Existing instance | Result
100  ---------|--------------------|---------------------|-------
101  True | OFF | * | { }
102  True | ON | True | std::logic_error
103  True | ON | False | { Python }
104  True | TRY | True | { }
105  True | TRY | False | { Python }
106  False | OFF | * | { }
107  False | ON | * | std::logic_error
108  False | TRY | * | { }
109  ---------|--------------------|---------------------|-------
110 
111 
112 */
113 
114 
115 class Python {
116 public:
117 
118  enum class Enable {
119  ON, /* Enable the Python extensions - throw std::logic_error() if it fails. */
120  TRY, /* Try to enable Python extensions*/
121  OFF /* Do not enable Python */
122  };
123 
124  explicit Python(Enable enable = Enable::TRY);
125  bool exec(const std::string& python_code) const;
126  bool exec(const std::string& python_code, const Parser& parser, Deck& deck) const;
127  bool exec(const Action::PyAction& py_action, EclipseState& ecl_state, Schedule& schedule, std::size_t report_step, SummaryState& st) const;
128 
129  /*
130  The enabled function returns true if this particular Python instance
131  manages a true Python interpreter.
132  */
133  bool enabled() const;
134 
135  /*
136  The supported function return true if this instance of opm-common has been
137  compiled with support for Python.
138  */
139  static bool supported();
140  bool run_module(const std::string& path);
141 private:
142  std::shared_ptr<PythonInterp> interp;
143 };
144 
145 }
146 
147 
148 
149 #endif
150 
Definition: PyAction.hpp:41
Definition: Deck.hpp:63
Definition: EclipseState.hpp:55
The hub of the parsing process.
Definition: Parser.hpp:59
Definition: Python.hpp:115
Definition: Schedule.hpp:145
Definition: SummaryState.hpp:69
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29