Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exposing a file-like object from Cython

I need to expose a file-like object from a C library that i'm wrapping with a Cython module. I want to reuse python's generic io code for stuff like buffering, readline(), etc.

The new IO module seems to be just what i need, but actually using it from Cython seems to be non-trivial, I've tried several aproaches:

  • My code in a cdef class that inherits from IO.RawIOBase - This fails because cdef classes can inherit only from other cython cdef classes, while IO is "raw" C.

  • My code in a cdef class, another (non-cdef) class that inherits both my cdef class and RawIOBase - Fails with "TypeError: multiple bases have instance lay-out conflict"

  • My code in a (non-cdef) class that inherits from RawIOBase - This works, but i loose the ability to store my c-level (that i need to talk to the underlying library) stuff inside the class, so i need a make a cdef wrapper around it and store that as a member... this looks like a mess.

  • My code in cdef class that doesn't inherit (Raw)IOBase rather reimplements it's functionality, Python code gets my object wrapped in BufferedReader/BufferedWriter - This one seems to work and less messy than the previous option.

My questions(s):

1) Am I missing something and reinventing the wheel here?

2) What is the exact stuff from IOBase that I need to implement to keep BufferedReader/Writer happy with my object in current and future versions of python? Is this documented anywhere?

3) How will that work in python 2.6 where IO is pure python? I guess that performance will suffer but it will work, right?

like image 295
bdew Avatar asked Nov 25 '10 15:11

bdew


1 Answers

Would it be too inefficient to call os.fdopen() on the file descriptor number returned by the underlying library, and then to dispatch normal Python method calls to the resulting file object in order to do your input and output? With most I/O, I would be surprised if you could see a difference with whether you called a C routine directly or let the Python method dispatch logic call it for you — but, of course, you might be in an unusual situation and I could be wrong!

like image 99
Brandon Rhodes Avatar answered Nov 09 '22 11:11

Brandon Rhodes