OGS
ApplicationsLib Namespace Reference

Detailed Description

The LinearSolverLibrarySetup takes care of proper initialization and shutting down of an external linear solver library. The concrete implementation is chosen by the build system. An object of this class must be created at the beginning of the scope where it is used. When the scope closes (or the object is destroyed explicitly) library shutting down functions are automatically called. The default implementation is empty providing polymorphic behaviour when using this class.

Namespaces

namespace  anonymous_namespace{ogs_embedded_python.cpp}

Classes

struct  LinearSolverLibrarySetup
class  TestDefinition

Functions

pybind11::scoped_interpreter setupEmbeddedPython ()
void setupEmbeddedPythonVenvPaths ()

Function Documentation

◆ setupEmbeddedPython()

OGS_EXPORT_SYMBOL pybind11::scoped_interpreter ApplicationsLib::setupEmbeddedPython ( )

Sets up an embedded Python interpreter and makes sure that the OpenGeoSys Python module is not removed by the linker.

Definition at line 32 of file ogs_embedded_python.cpp.

33{
34 // Allows ogs to be interrupted by SIGINT, which otherwise is handled by
35 // python. See
36 // https://docs.python.org/3/c-api/exceptions.html#c.PyErr_CheckSignals and
37 // https://pybind11.readthedocs.io/en/stable/faq.html#how-can-i-properly-handle-ctrl-c-in-long-running-functions
38 constexpr bool init_signal_handlers = false;
39 return pybind11::scoped_interpreter{init_signal_handlers};
40}

◆ setupEmbeddedPythonVenvPaths()

OGS_EXPORT_SYMBOL void ApplicationsLib::setupEmbeddedPythonVenvPaths ( )

Checks for activated and matching virtual environment and adds it to sys.path.

Definition at line 172 of file ogs_embedded_python.cpp.

173{
174 namespace py = pybind11;
175 namespace fs = std::filesystem;
176
177 // Get embedded Python version
178 py::object const version_info =
179 py::module_::import("sys").attr("version_info");
180 int const emb_major = version_info.attr("major").cast<int>();
181 int const emb_minor = version_info.attr("minor").cast<int>();
182
183 // Check for virtual environment
184 char const* const venv = std::getenv("VIRTUAL_ENV");
185 if (venv == nullptr)
186 {
187 DBUG("No virtual environment detected (VIRTUAL_ENV not set).");
188 return;
189 }
190
191 fs::path const venv_path(venv);
192 DBUG("Virtual environment detected at: {}", venv_path.string());
193
194 auto const venv_version = getPythonVersionFromVenv(venv_path);
195 if (!venv_version.has_value())
196 {
197 OGS_FATAL(
198 "Failed to determine Python version from virtual environment at "
199 "'{}'. "
200 "Please ensure the virtual environment is valid.",
201 venv_path.string());
202 }
203
204 int const venv_major = venv_version->first;
205 int const venv_minor = venv_version->second;
206
207 // Validate version match
208 if (venv_major != emb_major || venv_minor != emb_minor)
209 {
210 OGS_FATAL(
211 "Python version mismatch:\n"
212 " Embedded interpreter: {}.{}\n"
213 " Virtual environment: {}.{}\n"
214 "The virtual environment must use the same Python version as the "
215 "embedded interpreter.",
216 emb_major, emb_minor, venv_major, venv_minor);
217 }
218
219 // Find and validate site-packages path
220 fs::path const site_packages = findSitePackagesPath(venv_path);
221 INFO("Using virtual environment site-packages: {}", site_packages.string());
222
223 // Add to sys.path (insert at beginning for highest priority)
224 py::list sys_path = py::module_::import("sys").attr("path");
225 sys_path.insert(0, py::str(site_packages.string()));
226}
#define OGS_FATAL(...)
Definition Error.h:19
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
std::filesystem::path findSitePackagesPath(std::filesystem::path const &venv_path)
Finds site-packages path in the virtual environment.

References DBUG(), INFO(), and OGS_FATAL.