This is a combination of my two recent questions:
[1] Python instance method in C
[2] How to redirect stderr in Python?
I would like to log the output of both stdout and stderr from a python script.
The thing I want to ask is, to create a new type according to [1] seems fairly complicated. Does it simplifies the things if there was no need to expose the new type to Python, i.e. it would only exist in C?
I mean, when Python prints something it goes to "Objects/fileobject.c" and there in "PyFile_WriteObject" it check whether it is possible to write to its argument:
writer = PyObject_GetAttrString(f, "write");
if (writer == NULL)
...
Also, it is possible to get stdout and stderr like this:
PyObject* out = PySys_GetObject("stdout");
PyObject* err = PySys_GetObject("stderr");
My question is then, is it somehow possible to construct necessary PyObject which satisfies the above 'PyObject_GetAttrString(f, "write")' and is callable so I can write:
PySys_SetObject("stdout", <my writer object / class / type / ?>);
http://docs.python.org/c-api/sys.html?highlight=pysys_setobject#PySys_SetObject
This way, there would be no need to expose the new "writer type" to the rest of Python script so I thought it might be a bit simpler to write the code...?
Just make a module object (you're doing that anyway, if you're using the C API!-) and make it have a suitable
write
function -- that module object will be suitable as the second argument toPySys_SetObject
.In my answer to your other question I pointed you to
xxmodule.c
, an example file in Python's C sources, which is a module with a lot of examples including types and functions of various kinds -- you can work from there even if (mysteriously to me) you consider the "make a new type" part too difficult;-).Edit: here's a trivial working example (
aview.py
):Once this
aview
module is properly installed:...any string emitted to standard output is written with
==
signs around it (and thisprint
calls.write
twice: with'ciao'
, and then again with a newline).Based on Alex's answer, here is fully working C code, without the Python "import aview", in Python 3 (so no Py_InitModule), and with stderr redirection :
Note, though, that if you plan to have several distinct interpreters, this won't be enough, because
aview_write
won't be able to know which buffer to append into. You'll need something like that.Here is an awesome reference on how to add new modules and types, btw.