I've am learning about Python-C extensions and am puzzled as to why methods that use keyword arguments must be cast to PyCFunctions.
My understanding of a PyCFunction is that it takes two pointers to PyObjects and returns a single pointer to a PyObject - e.g.
PyObject* myFunc(PyObject* self, PyObject* args)
If I'm going to use a function that uses keyword arguments, then this function will take three pointers to PyObjects and returns a single pointer to a PyObject - e.g.
PyObject* myFunc(PyObject* self, PyObject* args, PyObject* keywordArgs)
However, when I create the module functions array (for a function called 'adder'):
{ "adder", (PyCFunction)adder, METH_VARARGS | METH_KEYWORDS, "adder method" }
works fine. It feels like I cast a float to an int and still got to use the non-integer parts of the float. If I didn't see this work, I would have thought it wouldn't work. What am I not understanding here?
Also, I saw some references to a PyCFunctionWithKeywords, which seems to have the function signature I thought I needed, but my compiler complained (gave warnings) about 'incompatible pointer types'.
Was PyCFunctionWithKeywords deprecated? If not, is there a time when I should/must use it?
If your function handles keyword arguments, then it must correspond to a PyCFunctionWithKeywords. However, C doesn’t do overloading, and the structure built by PyMethodDef is defined to expect a PyCFunction, rather than, say, a completely unchecked void *. So you must cast your PyCFunctionWithKeywords to a PyCFunction to stop the compiler complaining, that’s all.
Remember that you must also pass METH_KEYWORDS in the flags to tell Python that your function has the signature of a PyCFunctionWithKeywords, not a PyCFunction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With