Python extension module with variable number of arguments

后端 未结 1 1645
自闭症患者
自闭症患者 2020-12-10 03:54

I am trying to figure out how in C extension modules to have a variable (and maybe) quite large number of arguments to a function.

Reading about PyArg_ParseTuple it

相关标签:
1条回答
  • 2020-12-10 04:24

    I had used something like this earlier. It could be a bad code as I am not an experienced C coder, but it worked for me. The idea is, *args is just a Python tuple, and you can do anything that you could do with a Python tuple. You can check http://docs.python.org/c-api/tuple.html .

    int
    ParseArguments(unsigned long arr[],Py_ssize_t size, PyObject *args) {
        /* Get arbitrary number of positive numbers from Py_Tuple */
        Py_ssize_t i;
        PyObject *temp_p, *temp_p2;
    
    
        for (i=0;i<size;i++) {
            temp_p = PyTuple_GetItem(args,i);
            if(temp_p == NULL) {return NULL;}
    
            /* Check if temp_p is numeric */
            if (PyNumber_Check(temp_p) != 1) {
                PyErr_SetString(PyExc_TypeError,"Non-numeric argument.");
                return NULL;
            }
    
            /* Convert number to python long and than C unsigned long */
            temp_p2 = PyNumber_Long(temp_p);
            arr[i] = PyLong_AsUnsignedLong(temp_p2);
            Py_DECREF(temp_p2);
            if (arr[i] == 0) {
                PyErr_SetString(PyExc_ValueError,"Zero doesn't allowed as argument.");
                return NULL;
            }
            if (PyErr_Occurred()) {return NULL; }
        }
    
        return 1;
    }
    

    I was calling this function like this:

    static PyObject *
    function_name_was_here(PyObject *self, PyObject *args)
    {
        Py_ssize_t TupleSize = PyTuple_Size(args);
        Py_ssize_t i;
        struct bigcouples *temp = malloc(sizeof(struct bigcouples));
        unsigned long current;
    
        if(!TupleSize) {
            if(!PyErr_Occurred()) 
                PyErr_SetString(PyExc_TypeError,"You must supply at least one argument.");
            free(temp);
            return NULL;
        }
    
        unsigned long *nums = malloc(TupleSize * sizeof(unsigned long));
    
        if(!ParseArguments(nums, TupleSize, args)){
            /* Make a cleanup and than return null*/
            return null;
        }
    
    0 讨论(0)
提交回复
热议问题