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: Is this the most convenient way? Or is there a built-in method in the Python C API that I did not see? 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()? 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...