Python C module questions

Thomas Heller theller at python.net
Fri Sep 2 02:17:13 EDT 2005


jeremy.d.brewer at gmail.com writes:

[...]
>     /* convert sequences to tuples if necessary */
>     ra1 = PySequence_Fast(ra1, "ra1 must be iterable");
>     if (ra1 == NULL) {
>         return NULL;
>     }
>
>     dec1 = PySequence_Fast(dec1, "dec1 must be iterable");
>     if (dec1 == NULL) {
>         return NULL;
>     }

You leak a refcount to ra1 here in the case the the second
PySequence_Fast fails.

[...]
>     /* allocate memory for C arrays */
>     r1 = (double *) malloc(len1 * sizeof(double));
>     if (r1 == NULL) {
>         Py_DECREF(ra1);
>         Py_DECREF(dec1);
>         Py_DECREF(ra2);
>         Py_DECREF(dec2);
>         return PyErr_NoMemory();
>     }
>
>     d1 = (double *) malloc(len1 * sizeof(double));
>     if (d1 == NULL) {
>         Py_DECREF(ra1);
>         Py_DECREF(dec1);
>         Py_DECREF(ra2);
>         Py_DECREF(dec2);
>         return PyErr_NoMemory();
>     }
and so on, and so on.

You should probably better start your code initializing all local vars
to NULL, like this:

    PyObject *ra1 = NULL, *dec1 = NULL, ...
    char *r1 = NULL, char *d1 = NULL, ...;

Then in the body of the function

    d1 = (double *) malloc(len1 * sizeof(double));
    if (d1 == NULL) {
        PyErr_NoMemory();
        goto error;
    }

and have a cleanup section at the end:

  error:
    if (d1) free(d1);
    ....
    Py_XDECREF(ra1);
    Py_XDECREF(dec1);
    return NULL;
}

Reading the sources for a few builtin modules of the Python sources
itself should give you also an idea.

> I also find it hard to believe that there's no
> standard Python function for converting sequences of one object to
> arrays in C (a friend mentioned that Ruby's C API has this).

The builtin array module does help with this, you can build the
C-compatible arrays in Python, pass them to your extension, and access
them using the buffer api.

Thomas



More information about the Python-list mailing list