Unverified Commit 0b7862d6 authored by Joseph Mirabel's avatar Joseph Mirabel Committed by GitHub
Browse files

Merge pull request #40 from nim65s/devel

fix #39
parents 63d0a6ef 9a27fc49
Pipeline #7538 failed with stage
in 26 minutes and 21 seconds
......@@ -178,12 +178,12 @@ __attribute__((unused)) static struct PyModuleDef dynamicGraphModuleDef = {
NULL,
NULL};
#define GETSTATE(m) ((struct dynamicgraph::python::module_state*)PyModule_GetState(m))
#define DGPYERROR GETSTATE(PyState_FindModule(&dynamicGraphModuleDef))->dgpyError
#define DGPYERROR(m) GETSTATE(m)->dgpyError
#define INITERROR return NULL
#else
__attribute__((unused)) static struct module_state _state;
#define GETSTATE(m) (&dynamicgraph::python::_state)
#define DGPYERROR dynamicgraph::python::_state.dgpyError
#define DGPYERROR(m) dynamicgraph::python::dgpyError
#define INITERROR return
#endif
......
......@@ -7,19 +7,19 @@
/// \brief Catch all exceptions which may be sent when C++ code is
/// called.
#define CATCH_ALL_EXCEPTIONS() \
catch (const std::exception& exc) { \
PyErr_SetString(DGPYERROR, exc.what()); \
return NULL; \
} \
catch (const char* s) { \
PyErr_SetString(DGPYERROR, s); \
return NULL; \
} \
catch (...) { \
PyErr_SetString(DGPYERROR, "Unknown exception"); \
return NULL; \
} \
#define CATCH_ALL_EXCEPTIONS(m) \
catch (const std::exception& exc) { \
PyErr_SetString(DGPYERROR(m), exc.what()); \
return NULL; \
} \
catch (const char* s) { \
PyErr_SetString(DGPYERROR(m), s); \
return NULL; \
} \
catch (...) { \
PyErr_SetString(DGPYERROR(m), "Unknown exception"); \
return NULL; \
} \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION
......@@ -21,11 +21,21 @@ typedef boost::shared_ptr<std::ofstream> ofstreamShrPtr;
namespace dynamicgraph {
namespace python {
#if PY_MAJOR_VERSION == 2
extern PyObject* dgpyError;
# endif
namespace debug {
std::map<std::string, ofstreamShrPtr> mapOfFiles_;
PyObject* addLoggerFileOutputStream(PyObject* /*self*/, PyObject* args) {
PyObject* addLoggerFileOutputStream(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* filename;
if (!PyArg_ParseTuple(args, "s", &filename)) return NULL;
std::string sfilename(filename);
......@@ -38,49 +48,79 @@ PyObject* addLoggerFileOutputStream(PyObject* /*self*/, PyObject* args) {
dgRTLOG() << "Added " << filename << " as an output stream \n";
mapOfFiles_[sfilename] = ofs_shrptr;
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* closeLoggerFileOutputStream(PyObject* /*self*/, PyObject* /*args */) {
PyObject* closeLoggerFileOutputStream(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try {
for (std::map<std::string, ofstreamShrPtr>::iterator it = mapOfFiles_.begin(); it != mapOfFiles_.end(); ++it) {
it->second->close();
}
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* addLoggerCoutOutputStream(PyObject* /*self*/, PyObject* /*args*/) {
PyObject* addLoggerCoutOutputStream(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try {
dgADD_OSTREAM_TO_RTLOG(std::cout);
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* realTimeLoggerDestroy(PyObject* /*self*/, PyObject* /*args*/) {
PyObject* realTimeLoggerDestroy(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try {
RealTimeLogger::destroy();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* realTimeLoggerSpinOnce(PyObject* /*self*/, PyObject* /*args*/) {
PyObject* realTimeLoggerSpinOnce(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try {
RealTimeLogger::instance().spinOnce();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* realTimeLoggerInstance(PyObject* /*self*/, PyObject* /*args*/) {
PyObject* realTimeLoggerInstance(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try {
RealTimeLogger::instance();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
......
......@@ -14,10 +14,20 @@
namespace dynamicgraph {
namespace python {
#if PY_MAJOR_VERSION == 2
PyObject* dgpyError;
# endif
/**
\brief plug a signal into another one.
*/
PyObject* plug(PyObject* /*self*/, PyObject* args) {
PyObject* plug(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* objOut = NULL;
PyObject* objIn = NULL;
void* pObjOut;
......@@ -61,11 +71,17 @@ PyObject* plug(PyObject* /*self*/, PyObject* args) {
try {
signalIn->plug(signalOut);
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("");
}
PyObject* enableTrace(PyObject* /*self*/, PyObject* args) {
PyObject* enableTrace(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* boolean;
char* filename = NULL;
......@@ -82,12 +98,12 @@ PyObject* enableTrace(PyObject* /*self*/, PyObject* args) {
try {
DebugTrace::openFile(filename);
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
} else {
try {
DebugTrace::closeFile(filename);
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
}
} else {
return NULL;
......@@ -102,8 +118,7 @@ PyObject* error_out(
PyObject*, PyObject*
#endif
) {
struct module_state* st = GETSTATE(m);
PyErr_SetString(st->dgpyError, "something bad happened");
PyErr_SetString(DGPYERROR(m), "something bad happened");
return NULL;
}
......@@ -121,30 +136,29 @@ void initwrap(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
PyObject* module = PyModule_Create(&dynamicgraph::python::dynamicGraphModuleDef);
PyObject* m = PyModule_Create(&dynamicgraph::python::dynamicGraphModuleDef);
#else
PyObject* module = Py_InitModule("wrap", dynamicgraph::python::dynamicGraphMethods);
PyObject* m = Py_InitModule("wrap", dynamicgraph::python::dynamicGraphMethods);
#endif
if (module == NULL) INITERROR;
struct dynamicgraph::python::module_state* st = GETSTATE(module);
if (m == NULL) INITERROR;
st->dgpyError = PyErr_NewException(const_cast<char*>("dynamic_graph.dgpyError"), NULL, NULL);
if (st->dgpyError == NULL) {
Py_DECREF(module);
DGPYERROR(m) = PyErr_NewException(const_cast<char*>("dynamic_graph.dgpyError"), NULL, NULL);
if (DGPYERROR(m) == NULL) {
Py_DECREF(m);
INITERROR;
}
Py_XINCREF(st->dgpyError);
if (PyModule_AddObject(module, "dgpyError", st->dgpyError) < 0) {
Py_XDECREF(st->dgpyError);
Py_CLEAR(st->dgpyError);
Py_DECREF(module);
return NULL;
Py_XINCREF(DGPYERROR(m));
if (PyModule_AddObject(m, "dgpyError", DGPYERROR(m)) < 0) {
Py_XDECREF(DGPYERROR(m));
Py_CLEAR(DGPYERROR(m));
Py_DECREF(m);
INITERROR;
}
#if PY_MAJOR_VERSION >= 3
return module;
return m;
#endif
}
......
......@@ -32,12 +32,22 @@ namespace python {
using namespace convert;
#if PY_MAJOR_VERSION == 2
extern PyObject* dgpyError;
# endif
namespace entity {
/**
\brief Create an instance of Entity
*/
PyObject* create(PyObject* /*self*/, PyObject* args) {
PyObject* create(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* className = NULL;
char* instanceName = NULL;
......@@ -51,7 +61,7 @@ PyObject* create(PyObject* /*self*/, PyObject* args) {
",\n"
"but this object is of type " +
std::string(obj->getClassName()) + " and not " + std::string(className));
PyErr_SetString(DGPYERROR, msg.c_str());
PyErr_SetString(DGPYERROR(m), msg.c_str());
return NULL;
}
} else /* If not, create a new object. */
......@@ -59,7 +69,7 @@ PyObject* create(PyObject* /*self*/, PyObject* args) {
try {
obj = dynamicgraph::FactoryStorage::getInstance()->newEntity(std::string(className), std::string(instanceName));
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
}
// Return the pointer as a PyCapsule
......@@ -69,7 +79,13 @@ PyObject* create(PyObject* /*self*/, PyObject* args) {
/**
\brief Get name of entity
*/
PyObject* getName(PyObject* /*self*/, PyObject* args) {
PyObject* getName(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
void* pointer = NULL;
std::string name;
......@@ -86,14 +102,20 @@ PyObject* getName(PyObject* /*self*/, PyObject* args) {
try {
name = entity->getName();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", name.c_str());
}
/**
\brief Get class name of entity
*/
PyObject* getClassName(PyObject* /*self*/, PyObject* args) {
PyObject* getClassName(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
void* pointer = NULL;
std::string name;
......@@ -110,14 +132,20 @@ PyObject* getClassName(PyObject* /*self*/, PyObject* args) {
try {
name = entity->getClassName();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", name.c_str());
}
/**
\brief Check if the entity has a signal with the given name
*/
PyObject* hasSignal(PyObject* /*self*/, PyObject* args) {
PyObject* hasSignal(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* name = NULL;
PyObject* object = NULL;
void* pointer = NULL;
......@@ -136,7 +164,7 @@ PyObject* hasSignal(PyObject* /*self*/, PyObject* args) {
try {
hasSignal = entity->hasSignal(std::string(name));
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
if (hasSignal)
Py_RETURN_TRUE;
......@@ -147,7 +175,13 @@ PyObject* hasSignal(PyObject* /*self*/, PyObject* args) {
/**
\brief Get a signal by name
*/
PyObject* getSignal(PyObject* /*self*/, PyObject* args) {
PyObject* getSignal(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* name = NULL;
PyObject* object = NULL;
void* pointer = NULL;
......@@ -166,14 +200,20 @@ PyObject* getSignal(PyObject* /*self*/, PyObject* args) {
try {
signal = &(entity->getSignal(std::string(name)));
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
// Return the pointer to the signal without destructor since the signal
// is not owned by the calling object but by the Entity.
return PyCapsule_New((void*)signal, "dynamic_graph.Signal", NULL);
}
PyObject* listSignals(PyObject* /*self*/, PyObject* args) {
PyObject* listSignals(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL;
PyObject* object = NULL;
......@@ -198,11 +238,17 @@ PyObject* listSignals(PyObject* /*self*/, PyObject* args) {
}
return result;
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return NULL;
}
PyObject* executeCommand(PyObject* /*self*/, PyObject* args) {
PyObject* executeCommand(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject* , PyObject* args
#endif
) {
PyObject* object = NULL;
PyObject* argTuple = NULL;
char* commandName = NULL;
......@@ -236,7 +282,7 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) {
if ((unsigned)size != typeVector.size()) {
std::stringstream ss;
ss << "command takes " << typeVector.size() << " parameters, " << size << " given.";
PyErr_SetString(DGPYERROR, ss.str().c_str());
PyErr_SetString(DGPYERROR(m), ss.str().c_str());
return NULL;
}
std::vector<Value> valueVector;
......@@ -249,10 +295,10 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) {
} catch (const std::exception& exc) {
std::stringstream ss;
ss << "while parsing argument " << iParam + 1 << ": expecting " << exc.what() << ".";
PyErr_SetString(DGPYERROR, ss.str().c_str());
PyErr_SetString(DGPYERROR(m), ss.str().c_str());
return NULL;
} catch (...) {
PyErr_SetString(DGPYERROR, "Unknown exception");
PyErr_SetString(DGPYERROR(m), "Unknown exception");
return NULL;
}
}
......@@ -261,7 +307,7 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) {
Value result = command->execute();
return valueToPython(result);
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return NULL;
}
......@@ -292,7 +338,13 @@ PyObject* listCommands(PyObject* /*self*/, PyObject* args) {
}
return result;
}
PyObject* getCommandDocstring(PyObject* /*self*/, PyObject* args) {
PyObject* getCommandDocstring(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
char* commandName;
if (!PyArg_ParseTuple(args, "Os", &object, &commandName)) {
......@@ -301,7 +353,7 @@ PyObject* getCommandDocstring(PyObject* /*self*/, PyObject* args) {
// Retrieve the entity instance
if (!PyCapsule_CheckExact(object)) {
PyErr_SetString(DGPYERROR, "first argument is not an object");
PyErr_SetString(DGPYERROR(m), "first argument is not an object");
return NULL;
}
void* pointer = PyCapsule_GetPointer(object, "dynamic_graph.Entity");
......@@ -322,7 +374,13 @@ PyObject* getCommandDocstring(PyObject* /*self*/, PyObject* args) {
return Py_BuildValue("s", docstring.c_str());
}
PyObject* getDocString(PyObject* /*self*/, PyObject* args) {
PyObject* getDocString(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) {
return NULL;
......@@ -330,7 +388,7 @@ PyObject* getDocString(PyObject* /*self*/, PyObject* args) {
// Retrieve the entity instance
if (!PyCapsule_CheckExact(object)) {
PyErr_SetString(DGPYERROR, "first argument is not an object");
PyErr_SetString(DGPYERROR(m), "first argument is not an object");
return NULL;
}
void* pointer = PyCapsule_GetPointer(object, "dynamic_graph.Entity");
......@@ -338,20 +396,26 @@ PyObject* getDocString(PyObject* /*self*/, PyObject* args) {
try {
return Py_BuildValue("s", entity->getDocString().c_str());
} catch (const std::exception& exc) {
PyErr_SetString(DGPYERROR, exc.what());
PyErr_SetString(DGPYERROR(m), exc.what());
return NULL;
} catch (...) {
PyErr_SetString(DGPYERROR, "Unknown exception");
PyErr_SetString(DGPYERROR(m), "Unknown exception");
return NULL;
}
return NULL;
}
PyObject* display(PyObject* /*self*/, PyObject* args) {
PyObject* display(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
/* Retrieve the entity instance. */
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object) || (!PyCapsule_CheckExact(object))) {
PyErr_SetString(DGPYERROR, "first argument is not an object");
PyErr_SetString(DGPYERROR(m), "first argument is not an object");
return NULL;
}
void* pointer = PyCapsule_GetPointer(object, "dynamic_graph.Entity");
......@@ -368,7 +432,13 @@ PyObject* display(PyObject* /*self*/, PyObject* args) {
/**
\brief Set verbosity Level
*/
PyObject* setLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args) {
PyObject* setLoggerVerbosityLevel(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
PyObject* objectVerbosityLevel = NULL;
if (!PyArg_ParseTuple(args, "OO", &object, &objectVerbosityLevel)) return NULL;
......@@ -408,13 +478,13 @@ PyObject* setLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args) {
break;
}
} catch (const std::exception& exc) {
PyErr_SetString(DGPYERROR, exc.what());
PyErr_SetString(DGPYERROR(m), exc.what());
return NULL;
} catch (const char* s) {
PyErr_SetString(DGPYERROR, s);
PyErr_SetString(DGPYERROR(m), s);
return NULL;
} catch (...) {
PyErr_SetString(DGPYERROR, "Unknown exception");
PyErr_SetString(DGPYERROR(m), "Unknown exception");
return NULL;
}
......@@ -424,7 +494,13 @@ PyObject* setLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args) {
/**
\brief Get verbosity Level
*/
PyObject* getLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args) {
PyObject* getLoggerVerbosityLevel(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
......@@ -441,7 +517,7 @@ PyObject* getLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args) {
try {
alv = entity->getLoggerVerbosityLevel();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
int ares = (int)alv;
return Py_BuildValue("i", ares);
......@@ -450,7 +526,13 @@ PyObject* getLoggerVerbosityLevel(PyObject* /*self*/, PyObject* args) {
/**
\brief Get stream print period
*/
PyObject* getStreamPrintPeriod(PyObject* /*self*/, PyObject* args) {
PyObject* getStreamPrintPeriod(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL;
if (!PyArg_ParseTuple(args, "O", &object)) return NULL;
......@@ -467,7 +549,7 @@ PyObject* getStreamPrintPeriod(PyObject* /*self*/, PyObject* args) {
try {
r = entity->getStreamPrintPeriod();
}
CATCH_ALL_EXCEPTIONS();
CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("d", r);
}