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_ParseTuple
with O
arguments expects a pointer to a PyObject *
, not a pointer to a PyObject
(ie the variadic argument should be of type PyObject **
).
So your code should be:
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);
// ...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.