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