diff --git a/cmake b/cmake index 60ef4f68ea6ceb2a7fc8c854d0e66f59d1f51dee..33e7189de7eb7bcd9fd5d8409aac413d0c8fa6f4 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 60ef4f68ea6ceb2a7fc8c854d0e66f59d1f51dee +Subproject commit 33e7189de7eb7bcd9fd5d8409aac413d0c8fa6f4 diff --git a/include/dynamic-graph/python/interpreter.hh b/include/dynamic-graph/python/interpreter.hh index dddc9acc805aca427adf25e8122fb5530ea2bf6a..5addec4c128ac4f95f2b1137fbdd2613c4e4c1ae 100644 --- a/include/dynamic-graph/python/interpreter.hh +++ b/include/dynamic-graph/python/interpreter.hh @@ -19,6 +19,7 @@ #include <Python.h> #include <string> #include "dynamic-graph/python/api.hh" +#include "dynamic-graph/python/deprecated.hh" #ifndef DYNAMIC_GRAPH_PYTHON_INTERPRETER_H # define DYNAMIC_GRAPH_PYTHON_INTERPRETER_H @@ -39,7 +40,8 @@ namespace dynamicgraph { ~Interpreter(); /// \brief Method to start python interperter. /// \param command string to execute - std::string python( const std::string& command ); + /// Method deprecated, you *SHOULD* handle error messages. + std::string python( const std::string& command ) DYNAMIC_GRAPH_PYTHON_DEPRECATED; /// \brief Method to start python interperter. /// \param command string to execute, result, stdout, stderr strings diff --git a/src/convert-dg-to-py.cc b/src/convert-dg-to-py.cc index 6a6fe8e8fbcf092ab3d49c017b05d0aa18a5cf3b..542b67084e4bc20a4b9892fc0f09edd9980aedaa 100644 --- a/src/convert-dg-to-py.cc +++ b/src/convert-dg-to-py.cc @@ -62,10 +62,10 @@ namespace dynamicgraph { std::string svalue; Vector v; Matrix m; - unsigned int nCols; - unsigned int size; + Py_ssize_t nCols; + Py_ssize_t size; PyObject* row; - unsigned int nRows; + Py_ssize_t nRows; switch (valueType) { case (Value::BOOL) : @@ -81,7 +81,7 @@ namespace dynamicgraph { throw ExceptionPython(ExceptionPython::VALUE_PARSING, "unsigned int"); } - uvalue = PyInt_AsUnsignedLongMask(pyObject); + uvalue = (unsigned int)PyInt_AsUnsignedLongMask(pyObject); return Value(uvalue); break; case (Value::INT) : @@ -109,7 +109,7 @@ namespace dynamicgraph { dvalue = PyFloat_AsDouble(pyObject); return Value(dvalue); } else if (PyInt_Check(pyObject)) { - dvalue = 0.0+PyInt_AS_LONG(pyObject); + dvalue = (double)PyInt_AS_LONG(pyObject); return Value(dvalue); } else { throw ExceptionPython(ExceptionPython::VALUE_PARSING, @@ -132,7 +132,7 @@ namespace dynamicgraph { } size = PyTuple_Size(pyObject); v.resize(size); - for (unsigned int i=0; i<size; i++) { + for (Py_ssize_t i=0; i<size; i++) { PyObject* pyDouble = PyTuple_GetItem(pyObject, i); if (PyFloat_Check(pyDouble)) v(i) = PyFloat_AsDouble(pyDouble); @@ -162,10 +162,10 @@ namespace dynamicgraph { } nCols = PyTuple_Size(row); - m.resize(nRows, nCols); + m.resize((unsigned int)nRows, (unsigned int)nCols); fillMatrixRow(m, 0, row); - for (unsigned int iRow=1; iRow<nRows; iRow++) { + for (Py_ssize_t iRow=1; iRow<nRows; iRow++) { row = PyTuple_GetItem(pyObject, iRow); if (!PyTuple_Check(row)) { throw ExceptionPython(ExceptionPython::MATRIX_PARSING, diff --git a/src/entity-py.cc b/src/entity-py.cc index d114e30c0ca37feac4fd8f01fce3e88440dd133c..9e25e707a45eca3d0d366edb582ff6f70a8c176c 100644 --- a/src/entity-py.cc +++ b/src/entity-py.cc @@ -193,7 +193,7 @@ namespace dynamicgraph { PyErr_SetString(PyExc_TypeError, "third argument is not a tuple"); return NULL; } - unsigned int size = PyTuple_Size(argTuple); + Py_ssize_t size = PyTuple_Size(argTuple); std::map<const std::string, Command*> commandMap = entity->getNewStyleCommandMap(); @@ -208,16 +208,17 @@ namespace dynamicgraph { Command* command = commandMap[std::string(commandName)]; // Check that tuple size is equal to command number of arguments const std::vector<Value::Type> typeVector = command->valueTypes(); - if (size != typeVector.size()) { - std::stringstream ss; - ss << "command takes " << typeVector.size() - << " parameters, " << size << " given."; - PyErr_SetString(dgpyError, ss.str().c_str()); - return NULL; - } + if ((unsigned)size != typeVector.size()) + { + std::stringstream ss; + ss << "command takes " << typeVector.size() + << " parameters, " << size << " given."; + PyErr_SetString(dgpyError, ss.str().c_str()); + return NULL; + } std::vector<Value> valueVector; - for (unsigned int iParam=0; iParam<size; iParam++) { + for (Py_ssize_t iParam=0; iParam<size; iParam++) { PyObject* PyValue = PyTuple_GetItem(argTuple, iParam); Value::Type valueType = typeVector[iParam]; try { @@ -257,9 +258,10 @@ namespace dynamicgraph { } void* pointer = PyCObject_AsVoidPtr(object); Entity* entity = (Entity*)pointer; - typedef std::map<const std::string, command::Command*> CommandMap; + typedef std::map<const std::string, command::Command*> + CommandMap; CommandMap map = entity->getNewStyleCommandMap(); - unsigned int nbCommands = map.size(); + Py_ssize_t nbCommands = (Py_ssize_t)map.size(); // Create a tuple of same size as the command map PyObject* result = PyTuple_New(nbCommands); unsigned int count = 0; diff --git a/src/factory-py.cc b/src/factory-py.cc index 65b8463e21291cde428f77e1d96b70687d452ccf..76c0f2f7a78d2b4f19b21988e2c3117b8ebf2d01 100644 --- a/src/factory-py.cc +++ b/src/factory-py.cc @@ -34,15 +34,20 @@ namespace dynamicgraph { return NULL; std::vector <std::string> classNames; - dynamicgraph::FactoryStorage::getInstance()->listEntities(classNames); - unsigned int classNumber = classNames.size(); + dynamicgraph::FactoryStorage::getInstance() + ->listEntities(classNames); + + Py_ssize_t classNumber = classNames.size(); // Build a tuple object PyObject* classTuple = PyTuple_New(classNumber); - for (unsigned int iEntity = 0; iEntity < classNames.size(); iEntity++) { - PyObject* className = Py_BuildValue("s", classNames[iEntity].c_str()); - PyTuple_SetItem(classTuple, iEntity, className); - } + for (Py_ssize_t iEntity = 0; + iEntity < (Py_ssize_t)classNames.size(); ++iEntity) + { + PyObject* className = + Py_BuildValue("s", classNames[iEntity].c_str()); + PyTuple_SetItem(classTuple, iEntity, className); + } return Py_BuildValue("O", classTuple); } diff --git a/src/interpreter.cc b/src/interpreter.cc index 4e095b584311ee6ddbe77ec63b94b18497b277d2..2133b5046b12063c612f07fff1186163704e2f10 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -19,6 +19,8 @@ #include "dynamic-graph/python/interpreter.hh" #include "link-to-python.hh" +std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std::ios::out ); + // Python initialization commands namespace dynamicgraph { namespace python { @@ -41,8 +43,8 @@ namespace dynamicgraph { } } -using dynamicgraph::python::Interpreter; -using dynamicgraph::python::libpython; +namespace dynamicgraph { + namespace python { bool HandleErr(std::string & err, PyObject * traceback_format_exception, @@ -66,11 +68,12 @@ bool HandleErr(std::string & err, PyTuple_SET_ITEM(args, 2, ptraceback); pyerr = PyObject_CallObject(traceback_format_exception, args); assert(PyList_Check(pyerr)); - unsigned int size = PyList_GET_SIZE(pyerr); + Py_ssize_t 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))); - } + for (Py_ssize_t 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); dgDEBUG(15) << "err: " << err << std::endl; @@ -106,139 +109,143 @@ bool HandleErr(std::string & err, return lres; } -Interpreter::Interpreter() -{ - // load python dynamic library - // this is silly, but required to be able to import dl module. + + Interpreter::Interpreter() + { + // load python dynamic library + // this is silly, but required to be able to import dl module. #ifndef WIN32 - dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); + dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); #endif - Py_Initialize(); - mainmod_ = PyImport_AddModule("__main__"); - Py_INCREF(mainmod_); - globals_ = PyModule_GetDict(mainmod_); - assert(globals_); - Py_INCREF(globals_); - PyRun_SimpleString(pythonPrefix[0].c_str()); - PyRun_SimpleString(pythonPrefix[1].c_str()); - PyRun_SimpleString(pythonPrefix[2].c_str()); - PyRun_SimpleString(pythonPrefix[3].c_str()); - PyRun_SimpleString(pythonPrefix[4].c_str()); - traceback_format_exception_ = PyDict_GetItemString - (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); - assert(PyCallable_Check(traceback_format_exception_)); - Py_INCREF(traceback_format_exception_); -} + Py_Initialize(); + mainmod_ = PyImport_AddModule("__main__"); + Py_INCREF(mainmod_); + globals_ = PyModule_GetDict(mainmod_); + assert(globals_); + Py_INCREF(globals_); + PyRun_SimpleString(pythonPrefix[0].c_str()); + PyRun_SimpleString(pythonPrefix[1].c_str()); + PyRun_SimpleString(pythonPrefix[2].c_str()); + PyRun_SimpleString(pythonPrefix[3].c_str()); + PyRun_SimpleString(pythonPrefix[4].c_str()); + traceback_format_exception_ = PyDict_GetItemString + (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); + assert(PyCallable_Check(traceback_format_exception_)); + Py_INCREF(traceback_format_exception_); + } -Interpreter::~Interpreter() -{ - //Py_DECREF(mainmod_); - //Py_DECREF(globals_); - //Py_DECREF(traceback_format_exception_); - Py_Finalize(); -} + Interpreter::~Interpreter() + { + //Py_DECREF(mainmod_); + //Py_DECREF(globals_); + //Py_DECREF(traceback_format_exception_); + Py_Finalize(); + } -std::string Interpreter::python( const std::string& command ) -{ - std::string lerr(""),lout(""),lres(""); - python(command,lres,lout,lerr); - return lres; -} + std::string Interpreter::python( const std::string& command ) + { + std::string lerr(""),lout(""),lres(""); + python(command,lres,lout,lerr); + return lres; + } -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_); - // Check if the result is null. - if (!result) { - - // Test if this is a syntax error (due to the evaluation of an expression) - // else just output the problem. - if (!HandleErr(err, - traceback_format_exception_, globals_, - Py_eval_input)) - { - // If this is a statement, re-parse the command. - result = PyRun_String(command.c_str(), Py_single_input, globals_, globals_); - - // If there is still an error build the appropriate err string. - if (result == NULL) - HandleErr(err, - traceback_format_exception_, globals_, - Py_single_input); + void Interpreter::python( const std::string& command, std::string& res, + std::string& out, std::string& err) + { + res = ""; + out = ""; + err = ""; + + std::cout << command.c_str() << std::endl; + PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, + globals_); + // Check if the result is null. + if (!result) { + + // Test if this is a syntax error (due to the evaluation of an expression) + // else just output the problem. + if (!HandleErr(err, + traceback_format_exception_, globals_, + Py_eval_input)) + { + // If this is a statement, re-parse the command. + result = PyRun_String(command.c_str(), Py_single_input, globals_, globals_); + + // If there is still an error build the appropriate err string. + if (result == NULL) + HandleErr(err, + traceback_format_exception_, globals_, + Py_single_input); + else + // If there is no error, make sure that the previous error message is erased. + err=""; + } else - // If there is no error, make sure that the previous error message is erased. - err=""; + { dgDEBUG(15) << "Do not try a second time." << std::endl; } } - else - { dgDEBUG(15) << "Do not try a second time." << std::endl; } - } - PyObject* stdout_obj = PyRun_String("stdout_catcher.fetch()", - Py_eval_input, globals_, - globals_); - out = PyString_AsString(stdout_obj); - // Local display for the robot (in debug mode or for the logs) - std::cout << out; - result = PyObject_Repr(result); - // If python cannot build a string representation of result - // then results is equal to NULL. This will trigger a SEGV - if (result!=NULL) - { - dgDEBUG(15) << "For command :" << command << std::endl; - res = PyString_AsString(result); - dgDEBUG(15) << "Result is: " << res <<std::endl; - dgDEBUG(15) << "Out is: " << out <<std::endl; - dgDEBUG(15) << "Err is :" << err << std::endl; + PyObject* stdout_obj = PyRun_String("stdout_catcher.fetch()", + Py_eval_input, globals_, + globals_); + out = PyString_AsString(stdout_obj); + // Local display for the robot (in debug mode or for the logs) + std::cout << out; + result = PyObject_Repr(result); + // If python cannot build a string representation of result + // then results is equal to NULL. This will trigger a SEGV + if (result!=NULL) + { + dgDEBUG(15) << "For command :" << command << std::endl; + res = PyString_AsString(result); + dgDEBUG(15) << "Result is: " << res <<std::endl; + dgDEBUG(15) << "Out is: " << out <<std::endl; + dgDEBUG(15) << "Err is :" << err << std::endl; + } + else + { dgDEBUG(15) << "Result is empty" << std::endl; } + return; } - else - { dgDEBUG(15) << "Result is empty" << std::endl; } - return; -} -PyObject* Interpreter::globals() -{ - return globals_; -} + PyObject* Interpreter::globals() + { + return globals_; + } -void Interpreter::runPythonFile( std::string filename ) -{ - PyObject* pymainContext = globals_; - PyRun_File(fopen( filename.c_str(),"r" ), filename.c_str(), - Py_file_input, pymainContext,pymainContext); - if (PyErr_Occurred()) + void Interpreter::runPythonFile( std::string filename ) { - std::cout << "Error occures..." << std::endl; - PyErr_Print(); + PyObject* pymainContext = globals_; + PyRun_File(fopen( filename.c_str(),"r" ), filename.c_str(), + Py_file_input, pymainContext,pymainContext); + if (PyErr_Occurred()) + { + std::cout << "Error occures..." << std::endl; + PyErr_Print(); + } } -} -void Interpreter::runMain( void ) -{ - const char * argv [] = { "dg-embedded-pysh" }; - Py_Main(1,const_cast<char**>(argv)); -} + void Interpreter::runMain( void ) + { + const char * argv [] = { "dg-embedded-pysh" }; + Py_Main(1,const_cast<char**>(argv)); + } -std::string Interpreter::processStream(std::istream& stream, std::ostream& os) -{ - char line[10000]; sprintf(line, "%s", "\n"); - std::string command; - std::streamsize maxSize = 10000; + std::string Interpreter::processStream(std::istream& stream, std::ostream& os) + { + char line[10000]; sprintf(line, "%s", "\n"); + std::string command; + std::streamsize maxSize = 10000; #if 0 - while (line != std::string("")) { - stream.getline(line, maxSize, '\n'); - command += std::string(line) + std::string("\n"); - }; + while (line != std::string("")) { + stream.getline(line, maxSize, '\n'); + command += std::string(line) + std::string("\n"); + }; #else - os << "dg> "; - stream.getline(line, maxSize, ';'); - command += std::string(line); + os << "dg> "; + stream.getline(line, maxSize, ';'); + command += std::string(line); #endif - return command; -} + return command; + } + } //namespace python +} // namespace dynamicgraph diff --git a/src/signal-caster-py.cc b/src/signal-caster-py.cc index fdc70de66847a4d9fd00ec428484f0f3664700e7..6631d5c2ceb64b3b7866c27e509dd46c4343c8eb 100644 --- a/src/signal-caster-py.cc +++ b/src/signal-caster-py.cc @@ -29,13 +29,15 @@ namespace dynamicgraph { return NULL; std::vector<std::string> typeList = dynamicgraph::SignalCaster::getInstance()->listTypenames(); - unsigned int typeNumber = typeList.size(); + Py_ssize_t typeNumber = typeList.size(); // Build a tuple object PyObject* typeTuple = PyTuple_New(typeNumber); - for (unsigned int iType = 0; iType < typeNumber; iType++) { - PyObject* className = Py_BuildValue("s", typeList[iType].c_str()); - PyTuple_SetItem(typeTuple, iType, className); + for (Py_ssize_t iType = 0; iType < typeNumber; ++iType) + { + PyObject* className = + Py_BuildValue("s", typeList[iType].c_str()); + PyTuple_SetItem(typeTuple, iType, className); } return Py_BuildValue("O", typeTuple);