29 #include <pybind11/embed.h>
32 namespace py = pybind11;
35 void PythonLoader::initialize()
41 py::module_ PythonLoader::load_module_from_file(
const std::string& fname) {
44 std::ifstream file_stream;
46 f_path.open_stream(file_stream);
47 std::string parent_path = f_path.parent_path();
48 PythonLoader::add_sys_path(parent_path);
50 string module_name = f_path.stem();
53 module = py::module_::import(module_name.c_str());
54 }
catch (
const py::error_already_set &ex) {
62 py::module_ PythonLoader::load_module_from_string(
const std::string& module_name,
const std::string& func_name,
const std::string& source_string) {
65 py::module_ user_module;
66 py::dict globals = py::globals();
69 py::exec(source_string.c_str(), globals, globals);
70 user_module = py::module::create_extension_module(module_name.c_str(),
"",
new PyModuleDef());
71 user_module.add_object(func_name.c_str(), globals[func_name.c_str()]);
72 }
catch (
const py::error_already_set &ex) {
78 py::module_ PythonLoader::load_module_by_name(
const std::string& module_name) {
82 py::module_ module_object;
84 module_object = py::module_::import (module_name.c_str());
85 }
catch (
const py::error_already_set &ex) {
94 PyObject *ptype = ex.type().ptr();
95 PyObject *pvalue = ex.value().ptr();
96 PyObject *ptraceback = ex.trace().ptr();
98 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
99 string error_description = string(PyUnicode_AsUTF8(PyObject_Str(pvalue)));
105 PyObject *traceback_module = PyImport_ImportModule(
"traceback");
107 string str_traceback;
108 if (traceback_module && ptraceback) {
109 PyObject *format_tb_method = PyObject_GetAttrString(traceback_module,
"format_tb");
110 if (format_tb_method) {
111 PyObject * traceback_lines = PyObject_CallFunctionObjArgs(format_tb_method, ptraceback, NULL);
112 if (traceback_lines) {
113 PyObject * join_str = PyUnicode_FromString(
"");
114 PyObject * join = PyObject_GetAttrString(join_str,
"join");
115 PyObject * message = PyObject_CallFunctionObjArgs(join, traceback_lines, NULL);
117 str_traceback = string(PyUnicode_AsUTF8(PyObject_Str(message)));
119 Py_DECREF(traceback_lines);
128 auto path_vec = PythonLoader::get_python_path();
130 for (
auto p : path_vec) {
131 python_path += p +
"\n";
136 "\nType: " + string(PyUnicode_AsUTF8(PyObject_Str( ex.type().ptr() ))) +
"\n"
137 +
"Message: " + string(PyUnicode_AsUTF8(PyObject_Str( ex.value().attr(
"args").ptr() ))) +
"\n"
138 +
"Traceback: \n" + str_traceback
139 +
"--------------------------------------------------------\n\n"
140 +
"Python sys.path: " +
"\n" + python_path
141 +
"--------------------------------------------------------\n\n";
143 THROW(ExcPythonError() << EI_PythonMessage( py_message ));
148 void PythonLoader::add_sys_path(
const std::string &path)
150 py::module_ sys = py::module_::import(
"sys");
151 auto sys_paths = sys.attr(
"path");
153 for (
auto sp : sys_paths) {
154 std::string sys_path = sp.cast<std::string>();
155 if (sys_path == path) {
156 WarningOut() <<
"Path '" << sys_path <<
"' already exists in Python sys path and cannot be added repeatedly!";
162 sys_paths.attr(
"append")(path);
167 py::module_ sys = py::module_::import(
"sys");
168 auto sys_paths = sys.attr(
"path");
170 for (
auto sp : sys_paths) {
171 std::string sys_path = sp.cast<std::string>();
172 path_vec.push_back(sys_path);
182 PythonRunning::PythonRunning()
185 py::initialize_interpreter();
186 std::string flowpy_path = std::string(FLOW123D_SOURCE_DIR) +
"/src/python";
187 std::string fieldproxypy_path = std::string(FLOW123D_SOURCE_DIR) +
"/build_tree/src";
188 PythonLoader::add_sys_path(flowpy_path);
189 PythonLoader::add_sys_path(fieldproxypy_path);
191 #ifdef FLOW123D_PYTHON_EXTRA_MODULES_PATH
193 std::stringstream extra_paths(FLOW123D_PYTHON_EXTRA_MODULES_PATH);
194 std::string extra_path;
195 while ( std::getline(extra_paths, extra_path,
':') )
197 PythonLoader::add_sys_path(extra_path);
205 PythonRunning::~PythonRunning() {
206 py::finalize_interpreter();
Dedicated class for storing path to input and output files.
Global macros to enhance readability and debugging, general constants.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
#define WarningOut()
Macro defining 'warning' record of log.
void throw_error(spirit_namespace::position_iterator< Iter_type > i, const std::string &reason)