getting values from an "exec" statement

T

Toby Donaldson

Hi all,

I'm designing an educational application that will run Python code and
check the output against a pre-define answer. I want to use the "exec"
statement to run the code, but I don't know how to get output from it.

For instance, exec works like this:
for i in xrange(1, 5):
print i
"""1
2
3
4

I want to store the values output by the print statement in a list. Is
there anyway to re-direct the output of the exec statement?

Also, it would be nice if exec had a timeout that automatically
haulted code that ran for too long. Is there a standard trick for
this? I expect I would have to run it in its own thread and kill the
thread when it takes too long (which reminds me I don't know anything
about Python threads!).

Toby
 
G

Greg Krohn

Toby Donaldson said:
Hi all,

I'm designing an educational application that will run Python code and
check the output against a pre-define answer. I want to use the "exec"
statement to run the code, but I don't know how to get output from it.

For instance, exec works like this:

for i in xrange(1, 5):
print i
"""
1
2
3
4

I want to store the values output by the print statement in a list. Is
there anyway to re-direct the output of the exec statement?

The code run by exec is run in the same scope as the exec (by default). So
anything done "in" the exec is visible to things "outside" the exec. Like
this:

l = []
code = """for i in xrange(1, 5):
l.append(i)"""
exec code
print l


greg
 
P

Paul Rubin

Python isn't really set up for what you're doing. The exec'd code can
too easily mess around with the calling code, if it's malicious.
You're best off just running the student's program in a separate
process and capturing the output.
 
E

Erik Max Francis

Toby said:
I'm designing an educational application that will run Python code and
check the output against a pre-define answer. I want to use the "exec"
statement to run the code, but I don't know how to get output from it.

Override sys.stdout with a proxy that will capture what's send to stdout
so you can do something with it. Of course, this won't help your second
problem -- trying to set up a useful sandbox -- but it's a start for
non-malicious code.
 
A

Alex Martelli

Toby said:
Hi all,

I'm designing an educational application that will run Python code and
check the output against a pre-define answer. I want to use the "exec"
statement to run the code, but I don't know how to get output from it.

I see you already received answers to this part.
I want to store the values output by the print statement in a list. Is
there anyway to re-direct the output of the exec statement?

I would suggest sys.stdout=cStringIO.StringIO() right before the
exec (and store it somewhere, and restore the previous value, in
a finally clause -- you DO want to have the exec inside a try
clause, of course, since it's so likely that exec will raise
exceptions!).

Also, it would be nice if exec had a timeout that automatically
haulted code that ran for too long. Is there a standard trick for
this? I expect I would have to run it in its own thread and kill the
thread when it takes too long (which reminds me I don't know anything
about Python threads!).

In Python 2.3, you can run the exec in the main thread after
setting up a secondary "watchdog" thread that calls function
thread.interrupt_main() after sleeping for a given length of
time; this will raise a KeyboardInterrupt in the main thread,
just as if somebody at the kbd had banged on Ctrl-C or the like.

Of course, this does NOT protect you against MALICIOUS code in
the exec -- THAT might easily capture and ignore the exception.
Your code will be MUCH more solid if you can arrange to execute
the untrusted code in a separate process (not hard on Linux,
BSD, and the like; possible -- though not quite as trivial -- on
Windows, too). But for "normal mistakes", it's reasonably OK.


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top