[Python] C `FILE` stream from Python BufferedIO object

Discussão em 'Python' iniciado por Stack, Fevereiro 24, 2025.

  1. Stack

    Stack Membro Participativo

    I am writing a Python binding for a C library function that requires a FILE * handle as an input.

    I want the Python caller to pass an open io.BufferedReader object to the function, so as to retain control of the handle, e.g.:

    with open(fname, 'rb') as fh:
    my_c_function(fh)


    Therefore, I don't want to pass a file name and open the handle inside the C function.

    My C wrapper would roughly look like this:

    PyObject *my_c_function (PyObject *self, PyObject *args)
    {
    FILE *fh;
    if (! PyArgs_ParseTuple (args, "?", &fh)) return NULL;
    my_c_lib_function (fh);
    // [...]
    }


    Obviosuly I can't figure out what symbol I should use for "?", or whether I should use a different method than PyArgs_ParseTuple. The Python C API documentation does not seem to provide any example on how to deal with buffered IO objects (from what I understand, the Buffer protocol applies to bytes objects and co.... right?)

    It seems like I could look into the file descriptor of the Python handle object within my C wrapper (as if calling fileno()) and create a C file handle from that using fdopen().

    A couple of questions:

    1. Is this the most convenient way? Or is there a built-in method in the Python C API that I did not see?
    2. The fileno() documentation mentions: "Return the underlying file descriptor (an integer) of the stream if it exists. An OSError is raised if the IO object does not use a file descriptor." In which case would that happen? What if I pass a file handle created in Python by other than open()?
    3. It seems pretty safe to open a read-only C handle on a read-only fd opened by Python, which should be guaranteed to close the handle after the C function; however, can anybody think of any pitfalls to this approach?

    Continue reading...

Compartilhe esta Página