4

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!

1
  • You need to simulate the interpreter then. Just evaluate the input line by line and print the results. Commented Mar 2, 2012 at 22:40

1 Answer 1

8

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Yes, I had tried this, but it seemed to want an interactive input - unless I was doing something wrong. What I tried was: FILE *myfile = fopen("example.py","r+"); PyRun_InteractiveLoop(myfile, "example.py"); fclose(myfile);
@FizzBuzz: So you want to read commands from a file, but want them behave as if they were interactively entered? And you claim this is what your users expect? I'm sure I'm missing something here.
@FizzBuzz: Note that the file you pass to PyRun_InteractiveLoop() must be "associated with an interactive device", as the linked documentation says.
You're right; I'm just not being clear - sorry! My initial test app is on the terminal; it would be trivial to point Python at stdin and let it work. However, I would like to take it into a GUI, which should behave to the user the same way but is not so easily hooked up. I'd like to read user input from somewhere (not stdin; a GUI text box), and have it executed in the same way as the command-line interpreter. Originally I was using PyRun_SimpleString() to send each line, but I also tried writing commands to a file and running from there. I hope this is clearer; thank you for your patience!
@FizzBuzz: Yes, that was really clear! Thanks, I'll update my answer. What platform are you on?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.