From 77fafcbc407d043debbf996b9c1194efaea0767d Mon Sep 17 00:00:00 2001 From: Duong Dang <nddang@laas.fr> Date: Fri, 4 Mar 2011 13:41:29 +0100 Subject: [PATCH] Add method intepreter::python with stdout and stderr returned along with result. --- include/dynamic-graph/python/interpreter.hh | 5 ++ src/dg-python.cc | 12 +++- src/interpreter.cc | 71 +++++++++++++++++++-- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/include/dynamic-graph/python/interpreter.hh b/include/dynamic-graph/python/interpreter.hh index e0d8dad..dddc9ac 100644 --- a/include/dynamic-graph/python/interpreter.hh +++ b/include/dynamic-graph/python/interpreter.hh @@ -41,6 +41,11 @@ namespace dynamicgraph { /// \param command string to execute std::string python( const std::string& command ); + /// \brief Method to start python interperter. + /// \param command string to execute, result, stdout, stderr strings + void python( const std::string& command , std::string& result, + std::string& out, std::string& err); + /// \brief Method to exectue a python script. /// \param filename the filename void runPythonFile( std::string filename ); diff --git a/src/dg-python.cc b/src/dg-python.cc index dd41db9..9ffae78 100644 --- a/src/dg-python.cc +++ b/src/dg-python.cc @@ -71,7 +71,7 @@ int main (int argc, char** argv) po::positional_options_description p; p.add("input", -1); - + po::variables_map vm; try @@ -121,7 +121,15 @@ int main (int argc, char** argv) while(1) { command = interpreter.processStream(std::cin, std::cout); if (command != "\n") { - std::string result = interpreter.python(command); + std::string result, out, err; + interpreter.python(command, result, out, err); + + if (out != "") { + std::cout << out << std::endl; + } + if (err != "") { + std::cout << err << std::endl; + } if (result != "None") { std::cout << result << std::endl; } diff --git a/src/interpreter.cc b/src/interpreter.cc index 23ef07f..5cb34ba 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -23,7 +23,19 @@ namespace dynamicgraph { namespace python { static const std::string pythonPrefix[5] = { "import traceback\n", - "def display(s): return str(s) if not s is None else None" + "def display(s): return str(s) if not s is None else None", + "class StdoutCatcher:\n" + " def __init__(self):\n" + " self.data = ''\n" + " def write(self, stuff):\n" + " self.data = self.data + stuff\n" + " def fetch(self):\n" + " s = self.data[:]\n" + " self.data = ''\n" + " return s\n" + "stdout_catcher = StdoutCatcher()\n" + "import sys\n" + "sys.stdout = stdout_catcher" }; } } @@ -64,18 +76,18 @@ Interpreter::~Interpreter() std::string Interpreter::python( const std::string& command ) { PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, - globals_); + globals_); if (!result) { PyErr_Clear(); result = PyRun_String(command.c_str(), Py_single_input, globals_, - globals_); + globals_); } if (result == NULL) { if (PyErr_Occurred()) { PyObject *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); if (ptraceback == NULL) { - ptraceback = Py_None; + ptraceback = Py_None; } PyObject* args = PyTuple_New(3); PyTuple_SET_ITEM(args, 0, ptype); @@ -86,7 +98,7 @@ std::string Interpreter::python( const std::string& command ) unsigned int size = PyList_GET_SIZE(result); std::string stringRes; for (unsigned int i=0; i<size; i++) { - stringRes += std::string(PyString_AsString(PyList_GET_ITEM(result, i))); + stringRes += std::string(PyString_AsString(PyList_GET_ITEM(result, i))); } result = PyString_FromString(stringRes.c_str()); PyErr_Clear(); @@ -100,6 +112,55 @@ std::string Interpreter::python( const std::string& command ) return value; } +void Interpreter::python( const std::string& command, std::string& res, + std::string& out, std::string& err) +{ + res = ""; + out = ""; + err = ""; + PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, + globals_); + if (!result) { + PyErr_Clear(); + result = PyRun_String(command.c_str(), Py_single_input, globals_, + globals_); + } + + if (result == NULL) { + if (PyErr_Occurred()) { + PyObject *ptype, *pvalue, *ptraceback, *pyerr; + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (ptraceback == NULL) { + ptraceback = Py_None; + } + PyObject* args = PyTuple_New(3); + PyTuple_SET_ITEM(args, 0, ptype); + PyTuple_SET_ITEM(args, 1, pvalue); + PyTuple_SET_ITEM(args, 2, ptraceback); + pyerr = PyObject_CallObject(traceback_format_exception_, args); + assert(PyList_Check(pyerr)); + unsigned int size = PyList_GET_SIZE(pyerr); + std::string stringRes; + for (unsigned int i=0; i<size; i++) { + stringRes += std::string(PyString_AsString(PyList_GET_ITEM(pyerr, i))); + } + pyerr = PyString_FromString(stringRes.c_str()); + err = PyString_AsString(pyerr); + PyErr_Clear(); + } else { + std::cout << "Result is NULL but no error occurred." << std::endl; + } + } + PyObject* stdout_obj = PyRun_String("stdout_catcher.fetch()", + Py_eval_input, globals_, + globals_); + out = PyString_AsString(stdout_obj); + std::cout << out; + result = PyObject_Repr(result); + res = PyString_AsString(result); + return; +} + PyObject* Interpreter::globals() { return globals_; -- GitLab