Understanding PyDict_Check behaviour
Question: 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.


Answer: `PyArg_ParseTuple` with `O` arguments expects a pointer to a `PyObject *`, not
a pointer to a `PyObject` (i.e. 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);
    
      // ...
    

