I have written a small C program that embeds Python. I'm setting it up correctly using Py_Initialize() and Py_Finalize(), and am able to run scripts either using PyRun_SimpleString or PyRun_SimpleFile. However, I don't know how mimic the behavior of Python's own interpreter when printing variables.
Specifically:
a = (1, 2, 3)
print a
Works fine for me: it prints out (1, 2, 3)
However:
a = (1, 2, 3)
a
Prints out nothing at all. In Python's own interpreter, this would print out (1, 2, 3) as well. How can I make my code do what users would expect and print out the value?
Thanks in advance!
To run the interpreters interactive loop, you should use the function PyRun_InteractiveLoop()
. Otherwise, your code will behave as if it were written in a Python script file, not entered interactively.
Edit: Here's the full code of a simple interactive interpreter:
#include <Python.h>
int main()
{
Py_Initialize();
PyRun_InteractiveLoop(stdin, "<stdin>");
Py_Finalize();
}
Edit2: Implementing a full interactive interpreter in a GUI is a bit of a project. Probably the easiest way to get it right is to write a basic terminal emulator connected to a pseudo-terminal device, and use the above code on that device. This will automatically get all subtleties right.
If your aim isn't a full-blown interactive editor, an option might be to use PyRun_String()
with Py_single_input
as start token. This will allow you to run some Python code as in the interactive interpreter, and if that code happened to be a single expression that doesn't evaluate to None
, a representation of its value is printed -- to stdout of course. Here is some example code (without error checking for simplicity):
#include <Python.h>
int main()
{
PyObject *main, *d;
Py_Initialize();
main = PyImport_AddModule("__main__");
d = PyModule_GetDict(main);
PyRun_String("a = (1, 2, 3)", Py_single_input, d, d);
PyRun_String("a", Py_single_input, d, d);
Py_Finalize();
}
This will print (1, 2, 3)
.
There are still a lot of problems:
- No error handling and traceback printing.
- No "incremental input" for block commands like in the interactive interpreter. The input needs to be complete.
- Output to stdout.
- If multiple lines of input are given, nothing is printed.
To really replicate the behaviour of the interactive interpreter is not easy. That's why my initial recommendation was to write a basic terminal emulator in your GUI, which shouldn't be too hard -- or maybe there's even one available.