Retrieving result from embedded execution

Stefan Behnel stefan_ml at behnel.de
Fri May 11 00:45:21 EDT 2012


F L, 08.05.2012 21:07:
> We are trying to implement our own interactive interpreter in our
> applicationusing an embedded Python interpreter. I was wondering what
> would be the best way to retreive as text the result of  executing
> Python code. The text must be exactly the same as it would be in
> thestandalone interpreter. We used to do this by changing the embedded
> interpreter's sys.stdout and sys.stderrwith a FILE created in C++. We
> could then execute code using the PyRun_InteractiveOnefunction and
> easily retrieve the result from the FILE. The problem is, our
> applicationshouldn't create any files if possible. We also tried
> replacing sys.stdout and sys.stderr with a custom made Python
> objectwhich could be more easily read from C++. We then used the
> function PyRun_Stringto execute the code. The problem here is that using
> the Py_file_input start tokendoesn't write everything we need to
> sys.stdout. (i.e. executing 2+2 does not write 4).It also doesn't print
> a traceback to sys.stderr when there is an exception. Using theother two
> start tokens is impossible since we need to be able to execute more than
> one instruction at once. We also tried using the function
> PyRun_SimpleString but weencounter the same problems.

As was already suggested, the PyRun_*() functions are a better choice for
executing code from C code, but they will not automatically divert
sys.stdout and sys.stderr for you, which are global settings of the
interpreter, not local to an execution. So you will get the result of the
evaluation back, but not any output that may have been printed during the
execution. You have to change those yourself, as you apparently already did.

However, have you tried using a pipe for them instead of a real file? That
would allow you to retrieve the output without needing to pass through a
file in the file system. You can also replace sys.stdout/err with arbitrary
objects in Python space, which could then forward the output in any way you
want.

But, if you control the code that is being executed, it would really be
best to *not* print anything out directly, but to use the logging module
for output, where you can control much better what exactly gets propagated
and to what target.

And when the code fails and raises an exception, you can get at the stack
trace (that the normal interpreter would just print out) using the
traceback module.


> Also, I'm new to mailling lists, what is the proper way to reply to
> someone? Should Ireply directly to someone's email adress or is there a
> way to answer trough the server.

A couple of more hints in addition to what Chris Angelico said: reply below
the text your are responding to (i.e. not above the text) or split it into
sections and reply inline (as I did). Cut down the original text to what is
needed for readers to understand the context of your answer. Write plain
text mails instead of HTML mails.

Your problem description was very good, BTW. It included the perfect amount
of information about what you tried and what didn't work for you about it.

Stefan




More information about the Python-list mailing list