20 #ifdef FLOW123D_HAVE_PYTHON 33 void PythonLoader::initialize(
const std::string &python_home)
35 static internal::PythonRunning _running(python_home);
39 PyObject * PythonLoader::load_module_from_file(
const std::string& fname) {
43 std::ifstream file_stream;
46 file_stream.exceptions ( ifstream::failbit | ifstream::badbit );
48 std::stringstream buffer;
49 buffer << file_stream.rdbuf();
52 unsigned int pos = fname.rfind(
"/");
53 if (pos != string::npos)
54 module_name = fname.substr(pos+1);
61 return load_module_from_string(module_name, buffer.str() );
66 PyObject * PythonLoader::load_module_from_string(
const std::string& module_name,
const std::string& source_string) {
70 char * tmp_name =
new char[ module_name.size() + 2 ];
71 strcpy( tmp_name, module_name.c_str() );
73 PyObject * compiled_string = Py_CompileString( source_string.c_str(), module_name.c_str(), Py_file_input );
74 if (PyErr_Occurred()) {
75 PyObject *ptype, *pvalue, *ptraceback, *pystr;
76 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
78 if ( !PyString_Check(pvalue) ) {
80 PyObject* err_type = PySequence_GetItem(pvalue, 0);
81 pystr = PyObject_Str(err_type);
82 ss << PyString_AsString(pystr) << endl;
83 PyObject* descr = PySequence_GetItem(pvalue, 1);
84 PyObject* file = PySequence_GetItem(descr, 0);
85 pystr = PyObject_Str(file);
86 ss <<
" File \"" << PyString_AsString(pystr) <<
"\"";
87 PyObject* row = PySequence_GetItem(descr, 1);
88 pystr = PyObject_Str(row);
89 ss <<
", line " << PyString_AsString(pystr) << endl;
90 PyObject*
line = PySequence_GetItem(descr, 3);
91 pystr = PyObject_Str(line);
92 ss << PyString_AsString(pystr);
93 PyObject* col = PySequence_GetItem(descr, 2);
94 pystr = PyObject_Str(col);
95 int pos = atoi( PyString_AsString(pystr) );
96 ss << setw(pos) <<
"^" << endl;
97 THROW(ExcPythonError() << EI_PythonMessage( ss.str() ));
99 THROW(ExcPythonError() << EI_PythonMessage( PyString_AsString(pvalue) ));
103 PyObject * result = PyImport_ExecCodeModule(tmp_name, compiled_string);
104 PythonLoader::check_error();
110 PyObject * PythonLoader::load_module_by_name(
const std::string& module_name) {
114 PyObject * module_object = PyImport_ImportModule (module_name.c_str());
115 PythonLoader::check_error();
117 return module_object;
121 void PythonLoader::check_error() {
122 if (PyErr_Occurred()) {
123 PyObject *ptype, *pvalue, *ptraceback;
125 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
126 string error_description = string(PyString_AsString(PyObject_Str(pvalue)));
129 PyObject *module_name = PyString_FromString(
"traceback");
130 PyObject *pyth_module = PyImport_Import(module_name);
131 Py_DECREF(module_name);
133 string str_traceback;
135 PyObject *pyth_func = PyObject_GetAttrString(pyth_module,
"format_exception");
136 if (pyth_func && PyCallable_Check(pyth_func)) {
137 PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL);
139 str_traceback = string(PyString_AsString(PyObject_Str(pyth_val)));
146 "\nType: " + string(PyString_AsString(PyObject_Str(ptype))) +
"\n" 147 +
"Message: " + string(PyString_AsString(PyObject_Str(pvalue))) +
"\n" 148 +
"Traceback: " + str_traceback;
150 THROW(ExcPythonError() << EI_PythonMessage( py_message ));
156 PyObject * PythonLoader::get_callable(PyObject *module,
const std::string &func_name) {
157 char func_char[func_name.size()+2];
158 strcpy(func_char, func_name.c_str());
159 PyObject * func = PyObject_GetAttrString(module, func_char );
160 PythonLoader::check_error();
162 if (! PyCallable_Check(func)) {
164 ss <<
"Field '" << func_name <<
"' from the python module: " << PyModule_GetName(module) <<
" is not callable." << endl;
165 THROW(ExcPythonError() << EI_PythonMessage( ss.str() ));
173 wstring to_py_string(
const string &str) {
174 wchar_t wbuff[ str.size() ];
175 size_t wstr_size = mbstowcs( wbuff, str.c_str(), str.size() );
176 return wstring( wbuff, wstr_size );
179 string from_py_string(
const wstring &wstr) {
180 char buff[ wstr.size() ];
181 size_t str_size = wcstombs( buff, wstr.c_str(), wstr.size() );
182 return string( buff, str_size );
187 #if FLOW123D_PYTHONLIBS_VERSION_MAJOR<3 188 #define to_py_string string 189 #define from_py_string string 190 #define PY_STRING string 192 #define PY_STRING wstring 195 #define STR_EXPAND(tok) #tok 196 #define STR(tok) string(STR_EXPAND(tok)) 200 PythonRunning::PythonRunning(
const std::string& program_name)
202 #ifdef FLOW123D_PYTHON_PREFIX 203 static PY_STRING _python_program_name = to_py_string(program_name);
204 Py_SetProgramName( &(_python_program_name[0]) );
205 PY_STRING full_program_name = Py_GetProgramFullPath();
211 size_t pos = full_program_name.rfind( to_py_string(
"flow123d") );
212 PY_STRING full_flow_prefix =
".";
213 if (pos != PY_STRING::npos) {
214 full_flow_prefix = full_program_name.substr(0,pos-
string(
"/bin/").size() );
217 PY_STRING default_py_prefix(to_py_string(STR(FLOW123D_PYTHON_PREFIX)));
220 static PY_STRING our_py_home(full_flow_prefix +
":" +default_py_prefix);
221 Py_SetPythonHome( &(our_py_home[0]) );
289 #endif //FLOW123D_PYTHON_PREFIX 294 #ifdef FLOW123D_PYTHON_EXTRA_MODULES_PATH 297 std::string path = Py_GetPath();
298 path = path +
":" + std::string(FLOW123D_PYTHON_EXTRA_MODULES_PATH);
300 char * path_char =
const_cast<char *
>(path.c_str());
301 PySys_SetPath (path_char);
302 #endif //FLOW123D_PYTHON_EXTRA_MODULES_PATH 307 PythonRunning::~PythonRunning() {
313 #endif // FLOW123D_HAVE_PYTHON
void open_stream(Stream &stream) const
Global macros to enhance readability and debugging, general constants.
Dedicated class for storing path to input and output files.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.