I’ve been playing around with the Python C API for a while. I like it a lot but today I hit a roadblock. I have a Python extension that has a function which expects one or two dictionaries as argument. I fear I might have misunderstood how PyDict_Check, or PyArg_ParseTuple works. Here’s a dumbed down example:
static PyObject * doStuffToOtherStuff(MyCustomPyObject *self, PyObject *args) {
char const *fmt = "OO";
PyObject dict1, dict2;
if (!PyArg_ParseTuple(args, fmt, &dict1, &dict2))
return NULL;
int hasDict1 = PyDict_Check(&dict1);
int hasDict2 = PyDict_Check(&dict2);
printf("%d %d\n");
Py_INCREF(Py_None);
return Py_None;
}
When built and imported I call it like this for example:
myClass.doStuffToOtherStuff(dict(), None)
I expect this to print 1 0 but it actually prints 1 1 . So does:
myClass.doStuffToOtherStuff(None, None)
myClass.doStuffToOtherStuff(None, dict())
myClass.doStuffToOtherStuff({}, None)
#etc…
If I change PyDict_Check to PyDict_CheckExact it prints 0 0 instead, no matter what I pass as arguments.
Any insight will be much appreciated.
PyArg_ParseTuplewithOarguments expects a pointer to aPyObject *, not a pointer to aPyObject(i.e. the variadic argument should be of typePyObject **).So your code should be: