1

We can extract a PyObject pointing to a python method using

PyObject *method = PyDict_GetItemString(methodsDictionary,methodName.c_str());

I want to know how many arguments the method takes. So if the function is

def f(x,y):
    return x+y

how do I find out it needs 2 arguments?

jkcl
  • 2,141
  • 3
  • 16
  • 19
  • Potentially relevant: http://stackoverflow.com/questions/6616398/finding-python-function-parameters-from-c – Jon Clements Nov 21 '12 at 11:50
  • 1
    Also, just noticed the `.c_str()` in there - so I'm guessing you're using C++. Have you looked at the Boost.Python or other wrapper libraries? - using the native Python C-API is not the most pleasant experience – Jon Clements Nov 21 '12 at 12:22

1 Answers1

0

Followed through the link provided by Jon. Assuming you don't want to (or can't) use Boost in your application, the following should get you the number (easily adapted from How to find the number of parameters to a Python function from C?):

PyObject *key, *value;
int pos = 0;
while(PyDict_Next(methodsDictionary, &pos, &key, &value)) {
    if(PyCallable_Check(value)) {
        PyObject* fc = PyObject_GetAttrString(value, "func_code");
        if(fc) {
            PyObject* ac = PyObject_GetAttrString(fc, "co_argcount");
            if(ac) {
               const int count = PyInt_AsLong(ac);
               // we now have the argument count, do something with this function
               Py_DECREF(ac);
            }
            Py_DECREF(fc);
        }
    }
}

If you're in Python 2.x the above definitely works. In Python 3.0+, you seem to need to use "__code__" instead of "func_code" in the snippet above.

I appreciate the inability to use Boost (my company won't allow it for the projects I've been working on lately), but in general, I would try to knuckle down and use that if you can, as I've found that the Python C API can in general get a bit fiddly as you try to do complicated stuff like this.

Community
  • 1
  • 1
Fritz
  • 274
  • 3
  • 16