/*! * Use the environment variable PYTHON_CMD if it is set. If not, return * the string 'python'. * * Note, there are hidden problems here that really direct us to use a full * pathname for the location of python. Basically the system call will use the * shell /bin/sh, in order to launch python. This default shell may not be the * shell that the user is employing. Therefore, the default path to python may * be different during a system call than during the default user shell * environment. This is quite a headache. The answer is to always set the * PYTHON_CMD environmental variable in the user environment to an absolute path * to locate the python executable. Then this issue goes away. */ static string pypath() { string s = "python"; const char* py = getenv("PYTHON_CMD"); if (py) { string sp = trimCopy(string(py)); if (sp.size() > 0) { s = sp; } } return s; }
void Python::load() { PyObject *modName; std::ostringstream comm; PyRun_SimpleString("curdir = os.getcwd()"); std::string path = trimCopy(getFolderFromFilePath(_script)); std::string filename = trimCopy(getFileNameFromFilePath(_script)); if(path.at(0) == '.') // "./" prefix has been set comm << "modulePath = curdir + \"" << path.substr(1) << "\""; else comm << "modulePath = \"" << path << "\""; PyRun_SimpleString(comm.str().c_str()); PyRun_SimpleString("sys.path.append(modulePath)"); modName = PyUnicode_FromString(filename.c_str()); _module = PyImport_Import(modName); Py_DECREF(modName); modName=0; if(!_module){ std::ostringstream msg; msg << "Python module \"" << filename << "\" cannot be imported." << std::endl; LOG(L_ERROR, msg.str()); printf("\n--- Python report --------------------------\n\n"); PyErr_Print(); printf("\n-------------------------- Python report ---\n"); throw std::runtime_error("Python execution error"); } _func = PyObject_GetAttrString(_module, "main"); if(!_func || !PyCallable_Check(_func)) { LOG(L_ERROR, "main() function cannot be found.\n"); printf("\n--- Python report --------------------------\n\n"); PyErr_Print(); printf("\n-------------------------- Python report ---\n"); throw std::runtime_error("Python execution error"); } }
std::string Utils::getCppVarName(const std::string& varName) { std::string cppVarName(varName); if(!varName.empty()) { if('@' == varName[0]) { cppVarName = varName.substr(1); m_cppVarNameAccessedElementNames.insert(cppVarName); } else if(Elements::findElement("@" + varName)) //KLUDGE?: need to decide if '@' should be removed before setting in cppTypeInfo { m_cppVarNameAccessedElementNames.insert(cppVarName); } if('$' == varName[0]) cppVarName = "s_" + varName.substr(1); } return trimCopy(cppVarName); }
static std::string call_ctml_writer(const std::string& text, bool isfile) { std::string file, arg; if (isfile) { file = text; arg = "r'" + text + "'"; } else { file = "<string>"; arg = "text=r'''" + text + "'''"; } string python_output, error_output; int python_exit_code; try { exec_stream_t python; python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes stringstream output_stream, error_stream; python.start(pypath(), ""); ostream& pyin = python.in(); pyin << "from __future__ import print_function\n" "if True:\n" " import sys\n" " try:\n" " from cantera import ctml_writer\n" " except ImportError:\n" " print('sys.path: ' + repr(sys.path) + '\\n', file=sys.stderr)\n" " raise\n" " ctml_writer.convert("; pyin << arg << ", outName='STDOUT')\n"; pyin << " sys.exit(0)\n\n"; pyin << "sys.exit(7)\n"; python.close_in(); std::string line; while (python.out().good()) { std::getline(python.out(), line); output_stream << line << std::endl; } #ifdef _WIN32 // Sleeping for 1 ms prevents a (somewhat inexplicable) deadlock while // reading from the stream. Sleep(1); #endif while (python.err().good()) { std::getline(python.err(), line); error_stream << line << std::endl; } python.close(); python_exit_code = python.exit_code(); error_output = trimCopy(error_stream.str()); python_output = output_stream.str(); } catch (std::exception& err) { // Report failure to execute Python stringstream message; message << "Error executing python while converting input file:\n"; message << "Python command was: '" << pypath() << "'\n"; message << err.what() << std::endl; throw CanteraError("ct2ctml_string", message.str()); } if (python_exit_code != 0) { // Report a failure in the conversion process stringstream message; message << "Error converting input file \"" << file << "\" to CTML.\n"; message << "Python command was: '" << pypath() << "'\n"; message << "The exit code was: " << python_exit_code << "\n"; if (error_output.size() > 0) { message << "-------------- start of converter log --------------\n"; message << error_output << std::endl; message << "--------------- end of converter log ---------------"; } else { message << "The command did not produce any output." << endl; } throw CanteraError("ct2ctml_string", message.str()); } if (error_output.size() > 0) { // Warn if there was any output from the conversion process stringstream message; message << "Warning: Unexpected output from CTI converter\n"; message << "-------------- start of converter log --------------\n"; message << error_output << std::endl; message << "--------------- end of converter log ---------------\n"; writelog(message.str()); } return python_output; }
void ck2cti(const std::string& in_file, const std::string& thermo_file, const std::string& transport_file, const std::string& id_tag) { string python_output; int python_exit_code; try { exec_stream_t python; python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes python.start(pypath(), "-i"); stringstream output_stream; ostream& pyin = python.in(); pyin << "if True:\n" << // Use this so that the rest is a single block " import sys\n" << " sys.stderr = sys.stdout\n" << " try:\n" << " from cantera import ck2cti\n" << " except ImportError:\n" << " print('sys.path: ' + repr(sys.path))\n" << " raise\n" " ck2cti.Parser().convertMech(r'" << in_file << "',"; if (thermo_file != "" && thermo_file != "-") { pyin << " thermoFile=r'" << thermo_file << "',"; } if (transport_file != "" && transport_file != "-") { pyin << " transportFile=r'" << transport_file << "',"; } pyin << " phaseName='" << id_tag << "',"; pyin << " permissive=True,"; pyin << " quiet=True)\n"; pyin << " sys.exit(0)\n\n"; pyin << "sys.exit(7)\n"; python.close_in(); std::string line; while (python.out().good()) { std::getline(python.out(), line); output_stream << line << std::endl;; } python.close(); python_exit_code = python.exit_code(); python_output = trimCopy(output_stream.str()); } catch (std::exception& err) { // Report failure to execute Python stringstream message; message << "Error executing python while converting input file:\n"; message << "Python command was: '" << pypath() << "'\n"; message << err.what() << std::endl; throw CanteraError("ct2ctml", message.str()); } if (python_exit_code != 0) { // Report a failure in the conversion process stringstream message; message << "Error converting input file \"" << in_file << "\" to CTI.\n"; message << "Python command was: '" << pypath() << "'\n"; message << "The exit code was: " << python_exit_code << "\n"; if (python_output.size() > 0) { message << "-------------- start of converter log --------------\n"; message << python_output << std::endl; message << "--------------- end of converter log ---------------"; } else { message << "The command did not produce any output." << endl; } throw CanteraError("ck2cti", message.str()); } if (python_output.size() > 0) { // Warn if there was any output from the conversion process stringstream message; message << "Warning: Unexpected output from CTI converter\n"; message << "-------------- start of converter log --------------\n"; message << python_output << std::endl; message << "--------------- end of converter log ---------------\n"; writelog(message.str()); } }