Reading from an External Buffer

Alex Martelli aleax at aleax.it
Sun Mar 23 11:31:59 CET 2003


Bill Orcutt wrote:

> Hi-
> 
> I working on a Macintosh C program that embeds some python code. I'm
> using "PyMac_SetConsoleHandler" to suppress the SIOUX console, and
> I've created my own write handler that captures Python's stdout &
> stderr and redirects them into my C code. So far no problem.
> 
> Now I'd like to do the same for stdin, reading lines from a buffer in
> my C code and passing them to sys.stdin in my Python code.
> Unfortunately, the only thing I've found that works so far is to write
> the data to temp file in C and then read it out from Python. But
> that's a not much of solution, is it?

The only small problem I see is that the ways to read from a file-like
object, such as sys.stdin, are many more than the ways to write to it.

I.e., to simulate a file open for writing, you need only provide
methods write and writelines, and the latter can be trivially
implemented by a loop over the former except for performance issues.

To simulate a file open for reading, you may need to provide
read([n]), readline([n]), readlines([n]), xreadlines([n]), AND
__iter__ -- and ideally try to make them work with each other.

However, this IS, after all, a SMOP; there is no deep conceptual
issue involved.  You may study the sources of StringIO.py to see
how to do this in Python, and cStringIO.c to see how to do it in
C, when the "buffer" is a Python string object.  When the "buffer"
you're reading from is something else, you should still be able
to reuse (by copying) most of the code in cStringIO.c anyway, and
this is the course of action I would suggest: copy cStringIO.c,
remove the parts related to writable file-objects (for simplicity)
if you don't need those, and modify the reading functions to get
their data from whatever your "external buffer" actually is.

This way, you'll have a type whose instances can "read" data the
way you need them to.  Then you just set a properly initialized
instance of that type as sys.stdin, and off you go...


Alex





More information about the Python-list mailing list