20 #ifdef FLOW123D_HAVE_PYTHON 32 void PythonLoader::initialize(
const std::string &python_home)
34 static internal::PythonRunning _running(python_home);
38 PyObject * PythonLoader::load_module_from_file(
const std::string& fname) {
42 std::ifstream file_stream( fname.c_str() );
44 INPUT_CHECK(! file_stream.fail(),
"Can not open input file '%s'.\n", fname.c_str() );
45 file_stream.exceptions ( ifstream::failbit | ifstream::badbit );
47 std::stringstream buffer;
48 buffer << file_stream.rdbuf();
51 unsigned int pos = fname.rfind(
"/");
52 if (pos != string::npos)
53 module_name = fname.substr(pos+1);
60 return load_module_from_string(module_name, buffer.str() );
65 PyObject * PythonLoader::load_module_from_string(
const std::string& module_name,
const std::string& source_string) {
69 char * tmp_name =
new char[ module_name.size() + 2 ];
70 strcpy( tmp_name, module_name.c_str() );
72 PyObject * compiled_string = Py_CompileString( source_string.c_str(), module_name.c_str(), Py_file_input );
73 if (PyErr_Occurred()) {
74 PyObject *ptype, *pvalue, *ptraceback, *pystr;
75 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
77 if ( !PyString_Check(pvalue) ) {
79 PyObject* err_type = PySequence_GetItem(pvalue, 0);
80 pystr = PyObject_Str(err_type);
81 ss << PyString_AsString(pystr) << endl;
82 PyObject* descr = PySequence_GetItem(pvalue, 1);
83 PyObject* file = PySequence_GetItem(descr, 0);
84 pystr = PyObject_Str(file);
85 ss <<
" File \"" << PyString_AsString(pystr) <<
"\"";
86 PyObject* row = PySequence_GetItem(descr, 1);
87 pystr = PyObject_Str(row);
88 ss <<
", line " << PyString_AsString(pystr) << endl;
89 PyObject*
line = PySequence_GetItem(descr, 3);
90 pystr = PyObject_Str(line);
91 ss << PyString_AsString(pystr);
92 PyObject* col = PySequence_GetItem(descr, 2);
93 pystr = PyObject_Str(col);
94 int pos = atoi( PyString_AsString(pystr) );
95 ss << setw(pos) <<
"^" << endl;
96 THROW(ExcPythonError() << EI_PythonMessage( ss.str() ));
98 THROW(ExcPythonError() << EI_PythonMessage( PyString_AsString(pvalue) ));
102 PyObject * result = PyImport_ExecCodeModule(tmp_name, compiled_string);
103 PythonLoader::check_error();
109 PyObject * PythonLoader::load_module_by_name(
const std::string& module_name) {
113 PyObject * module_object = PyImport_ImportModule (module_name.c_str());
114 PythonLoader::check_error();
116 return module_object;
120 void PythonLoader::check_error() {
121 if (PyErr_Occurred()) {
122 PyObject *ptype, *pvalue, *ptraceback;
124 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
125 string error_description = string(PyString_AsString(PyObject_Str(pvalue)));
128 PyObject *module_name = PyString_FromString(
"traceback");
129 PyObject *pyth_module = PyImport_Import(module_name);
130 Py_DECREF(module_name);
132 string str_traceback;
134 PyObject *pyth_func = PyObject_GetAttrString(pyth_module,
"format_exception");
135 if (pyth_func && PyCallable_Check(pyth_func)) {
136 PyObject *pyth_val = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL);
138 str_traceback = string(PyString_AsString(PyObject_Str(pyth_val)));
145 "\nType: " + string(PyString_AsString(PyObject_Str(ptype))) +
"\n" 146 +
"Message: " + string(PyString_AsString(PyObject_Str(pvalue))) +
"\n" 147 +
"Traceback: " + str_traceback;
149 THROW(ExcPythonError() << EI_PythonMessage( py_message ));
155 PyObject * PythonLoader::get_callable(PyObject *module,
const std::string &func_name) {
156 char func_char[func_name.size()+2];
157 strcpy(func_char, func_name.c_str());
158 PyObject * func = PyObject_GetAttrString(module, func_char );
159 PythonLoader::check_error();
161 if (! PyCallable_Check(func)) {
163 ss <<
"Field '" << func_name <<
"' from the python module: " << PyModule_GetName(module) <<
" is not callable." << endl;
164 THROW(ExcPythonError() << EI_PythonMessage( ss.str() ));
172 wstring to_py_string(
const string &str) {
173 wchar_t wbuff[ str.size() ];
174 size_t wstr_size = mbstowcs( wbuff, str.c_str(), str.size() );
175 return wstring( wbuff, wstr_size );
178 string from_py_string(
const wstring &wstr) {
179 char buff[ wstr.size() ];
180 size_t str_size = wcstombs( buff, wstr.c_str(), wstr.size() );
181 return string( buff, str_size );
186 #if FLOW123D_PYTHONLIBS_VERSION_MAJOR<3 187 #define to_py_string string 188 #define from_py_string string 189 #define PY_STRING string 191 #define PY_STRING wstring 194 #define STR_EXPAND(tok) #tok 195 #define STR(tok) string(STR_EXPAND(tok)) 199 PythonRunning::PythonRunning(
const std::string& program_name)
201 #ifdef FLOW123D_PYTHON_PREFIX 202 static PY_STRING _python_program_name = to_py_string(program_name);
203 Py_SetProgramName( &(_python_program_name[0]) );
204 PY_STRING full_program_name = Py_GetProgramFullPath();
210 size_t pos = full_program_name.rfind( to_py_string(
"flow123d") );
211 PY_STRING full_flow_prefix =
".";
212 if (pos != PY_STRING::npos) {
213 full_flow_prefix = full_program_name.substr(0,pos-
string(
"/bin/").size() );
216 PY_STRING default_py_prefix(to_py_string(STR(FLOW123D_PYTHON_PREFIX)));
219 static PY_STRING our_py_home(full_flow_prefix +
":" +default_py_prefix);
220 Py_SetPythonHome( &(our_py_home[0]) );
288 #endif //FLOW123D_PYTHON_PREFIX 293 #ifdef FLOW123D_PYTHON_EXTRA_MODULES_PATH 296 std::string path = Py_GetPath();
297 path = path +
":" + std::string(FLOW123D_PYTHON_EXTRA_MODULES_PATH);
299 char * path_char =
const_cast<char *
>(path.c_str());
300 PySys_SetPath (path_char);
301 #endif //FLOW123D_PYTHON_EXTRA_MODULES_PATH 306 PythonRunning::~PythonRunning() {
312 #endif // FLOW123D_HAVE_PYTHON
#define INPUT_CHECK(i,...)
Debugging macros.
Global macros to enhance readability and debugging, general constants.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.