maxbachmann
maxbachmann

Reputation: 3265

Python C Api check if PyObject points to a specific PyCFunction

I have a module written using the Python C API:

static PyObject* my_func1(PyObject* /*self*/, PyObject* args)
{
  Py_RETURN_NONE;
}

static PyObject* my_func2(PyObject* /*self*/, PyObject* args)
{
  Py_RETURN_NONE;
}


static PyMethodDef methods[] = {
    {"my_func1", (PyCFunction)my_func1, METH_VARARGS, ""}, 
    {"my_func2", (PyCFunction)my_func2, METH_VARARGS, ""},
    {NULL, NULL, 0, NULL} /* sentinel */
};

static struct PyModuleDef moduledef = {                                                          
      PyModuleDef_HEAD_INIT, my_module, NULL, -1, methods, NULL, NULL, NULL, NULL
};                     
 
PyMODINIT_FUNC PyInit_my_module(void){                                                                                                
    return PyModule_Create(&moduledef);                                                            
}

as one of the arguments a user can pass a function e.g.:

my_func1(my_func2)

How can I detect inside my_func1, that the argument the user passed is a function, that points to my_func2 using the Python C API?

Upvotes: 2

Views: 352

Answers (1)

DavidW
DavidW

Reputation: 30889

You can use PyCFunction_Check to test if an object is a C function and PyCFunction_GetFunction to get the C function pointer. You can then just compare the C function pointers. Relevant header is at https://github.com/python/cpython/blob/4c9ea093cd752a6687864674d34250653653f743/Include/methodobject.h if you want to look at the signatures.

This looks to date back to at least Python 3.6 (probably further) although it's slightly hard to track because they've moved what headers these are defined in a bit.

Note that this is all looks fairly undocumented so you shouldn't rely completely on it not changing.

Upvotes: 3

Related Questions