9#define PY_SSIZE_T_CLEAN
37 PyModuleDef_HEAD_INIT,
"_comin",
56 module.m_methods = pyCominMethods.data();
57 PyObject* pSelf = PyModule_Create(&
module);
62 PyErr_NewException(
"comin.ComInError", PyExc_RuntimeError, NULL);
70 PyObject* pShlex = PyImport_ImportModule(
"shlex");
71 PyObject* pDict = PyModule_GetDict(pShlex);
72 PyObject* pSplit = PyDict_GetItemString(
73 pDict, (
char*)
"split");
74 PyObject* pList = PyObject_CallFunction(pSplit,
"s", str);
76 PyList_GetItem(pList, 0);
77 char* filename = strdup(PyUnicode_AsUTF8(pFilename));
83static std::string
exec(std::string cmd) {
84 std::array<char, 128>
buffer;
86 std::unique_ptr<FILE, void (*)(FILE*)> pipe(
87 popen(cmd.c_str(),
"r"),
88 [](FILE* f) ->
void { std::ignore = pclose(f); });
91 "Cannot execute given python executable: %s",
94 while (fgets(
buffer.data(),
static_cast<int>(
buffer.size()), pipe.get()) !=
102 std::string py_version_str =
exec(python_exe +
" --version");
105 py_version_str.substr(py_version_str.find(
" ") + 1);
107 std::atoi(py_version_str.substr(0, py_version_str.find(
".")).c_str());
109 py_version_str.substr(py_version_str.find(
".") + 1);
111 std::atoi(py_version_str.substr(0, py_version_str.find(
".") + 1).c_str());
112 if (major != PY_MAJOR_VERSION || minor != PY_MINOR_VERSION) {
114 "Versions of the embedded interpreter (%d.%d)"
115 " and the python executable (%d.%d)"
116 " are not compatible.",
117 PY_MAJOR_VERSION, PY_MINOR_VERSION, major, minor);
124 PyConfig_InitPythonConfig(&config);
125 std::string python3_exe = Python3_EXECUTABLE;
126 if (
const char* python3_exe_env = std::getenv(
"COMIN_PYTHON_EXECUTABLE"))
127 python3_exe = python3_exe_env;
132 PyConfig_SetBytesString(&config, &config.executable, python3_exe.c_str());
133 if (PyStatus_Exception(status)) {
135 "python_adapter::comin_main",
136 "Cannot set config.executable for python initialization. %s",
141 status = Py_InitializeFromConfig(&config);
142 if (PyStatus_Exception(status)) {
144 "Python initialization failed. (%s)", status.err_msg);
147 PyConfig_Clear(&config);
155 using namespace std::string_literals;
157 int mpi_rank = comin_parallel_get_host_mpi_rank();
159 std::cerr <<
"setup_python_adapter" << std::endl;
161 if (!Py_IsInitialized()) {
169 sprintf(libname,
"libpython3.%d.so", PY_MINOR_VERSION);
170 void* handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL);
171 if (handle ==
nullptr) {
174 __func__,
"Plugin cannot be loaded.\nLibrary: %s\ndlerror: %d",
187 std::string comin_py_c((
char*)comin_py, comin_py_len);
188 PyObject* compiled_comin =
189 Py_CompileString(comin_py_c.c_str(),
"comin.py", Py_file_input);
190 if (PyErr_Occurred()) {
194 PyImport_ExecCodeModule(
"comin", compiled_comin);
195 if (PyErr_Occurred()) {
211 PyObject* globals = PyDict_New();
216 std::filesystem::path fpath = filename;
217 auto parent_path = std::filesystem::canonical(fpath.parent_path());
219 (
"import sys; sys.path.insert(0,\""s + parent_path.c_str() +
"\")"s)
226 std::cerr <<
"Running python script " << filename << std::endl;
227 FILE* file = fopen(filename,
"r");
229 throw std::runtime_error(
"Cannot read "s + std::string(filename));
232 PyRun_File(file, filename, Py_file_input, globals, globals);
233 Py_XDECREF(pyResult);
235 if (PyErr_Occurred()) {
237 throw std::runtime_error(
"Error while executing "s +
238 std::string(filename));
241 (
"sys.path.remove(\""s + parent_path.c_str() +
"\")"s).c_str());
243 }
catch (std::exception& err) {
245 "Error while executing script:\n%s", err.what());
C interface for the ICON Community Interface.
void comin_print_debug_f(const char *fmt,...)
void comin_plugin_finish_f(const char *routine, const char *fmt,...)
void comin_plugin_finish(const char *routine, const char *text)
void comin_error_set_errors_return(bool errors_return)
const char * comin_current_get_plugin_options()
void comin_callback_register(t_comin_entry_point entry_point, t_comin_callback_function fct_ptr)
static void initialize_python()
static char * extract_filename(const char *str)
PyMODINIT_FUNC PyInit_comin(void)
static struct PyModuleDef module
PyObject * PyExc_ComInError
static int instance_counter
const std::vector< PyMethodDef > descrdata_methods()
std::vector< PyMethodDef > variables_methods()
static void python_version_check(std::string python_exe)
static std::vector< PyMethodDef > pyCominMethods
std::vector< PyMethodDef > callbacks_methods()
static std::string exec(std::string cmd)