Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.

Commit 834ff2f

Browse files
committed
explicit error in case of misuse of dg.plug, fix #36
1 parent d4a210d commit 834ff2f

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

src/dynamic_graph/dynamic-graph-py.cc

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ namespace python {
1717
/**
1818
\brief plug a signal into another one.
1919
*/
20-
PyObject* plug(PyObject* /*self*/, PyObject* args) {
20+
PyObject* plug(
21+
#if PY_MAJOR_VERSION >= 3
22+
PyObject* m, PyObject* args
23+
#else
24+
PyObject*, PyObject* args
25+
#endif
26+
) {
2127
PyObject* objOut = NULL;
2228
PyObject* objIn = NULL;
2329
void* pObjOut;
@@ -40,10 +46,22 @@ PyObject* plug(PyObject* /*self*/, PyObject* args) {
4046

4147
pObjIn = PyCapsule_GetPointer(objIn, "dynamic_graph.Signal");
4248
SignalBase<int>* signalIn = (SignalBase<int>*)pObjIn;
43-
if (signalIn == NULL) return NULL;
49+
if (signalIn == NULL) {
50+
struct module_state* st = GETSTATE(m);
51+
std::ostringstream oss;
52+
oss << "dgpy.plug in argument must be a dynamic_graph.Signal, not a " << PyCapsule_GetName(objIn);
53+
PyErr_SetString(st->dgpyError, oss.str().c_str());
54+
return NULL;
55+
}
4456
pObjOut = PyCapsule_GetPointer(objOut, "dynamic_graph.Signal");
4557
SignalBase<int>* signalOut = (SignalBase<int>*)pObjOut;
46-
if (signalOut == NULL) return NULL;
58+
if (signalOut == NULL) {
59+
struct module_state* st = GETSTATE(m);
60+
std::ostringstream oss;
61+
oss << "dgpy.plug out argument must be a dynamic_graph.Signal, not a " << PyCapsule_GetName(objOut);
62+
PyErr_SetString(st->dgpyError, oss.str().c_str());
63+
return NULL;
64+
}
4765
std::ostringstream os;
4866

4967
try {
@@ -123,6 +141,14 @@ void initwrap(void)
123141
INITERROR;
124142
}
125143

144+
Py_XINCREF(st->dgpyError);
145+
if (PyModule_AddObject(module, "dgpyError", st->dgpyError) < 0) {
146+
Py_XDECREF(st->dgpyError);
147+
Py_CLEAR(st->dgpyError);
148+
Py_DECREF(module);
149+
return NULL;
150+
}
151+
126152
#if PY_MAJOR_VERSION >= 3
127153
return module;
128154
#endif

unitTesting/test_bindings.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22

33
import dynamic_graph as dg
4+
45
from custom_entity import CustomEntity
56

67

@@ -15,10 +16,18 @@ def test_type_check(self):
1516
second = CustomEntity('second_entity')
1617
# Check that we can connect first.out to second.in
1718
dg.plug(first.signal('out_double'), second.signal('in_double'))
19+
1820
# Check that we can't connect first.out to second
19-
with self.assertRaises(ValueError) as cm:
21+
with self.assertRaises(dg.dgpyError) as cm_in:
2022
dg.plug(first.signal('out_double'), second)
21-
self.assertEqual(str(cm.exception), "PyCapsule_GetPointer called with incorrect name")
23+
self.assertEqual(str(cm_in.exception),
24+
"dgpy.plug in argument must be a dynamic_graph.Signal, not a dynamic_graph.Entity")
25+
26+
# Check that we can't connect first to second.in
27+
with self.assertRaises(dg.dgpyError) as cm_out:
28+
dg.plug(first, second.signal('in_double'))
29+
self.assertEqual(str(cm_out.exception),
30+
"dgpy.plug out argument must be a dynamic_graph.Signal, not a dynamic_graph.Entity")
2231

2332

2433
if __name__ == '__main__':

0 commit comments

Comments
 (0)