[Discuss] Compiling/running user-supplied Python code

Adam Parkin pzelnip at telus.net
Thu Aug 10 10:43:44 PDT 2006


Okay, I've been banging my head against the wall for awhile now and I'm 
giving up and turning (once again) to the Python gurus.

For the application I'm working on, I read two strings from a user.  One 
which will contain Python code for declaring functions, and a second 
which will contain Python code for actually executing a function.  I'll 
use the name "code" for the first, and "trigger" for the second.  So for 
example, the "code" string might look something like:

def foo(n):
	x = 3 * n
	return x

(that is some identifier "code" will contain the string: "def 
foo(n):\n\tx = 3 * n\n\treturn x\n").  It can be arbitrarily long (ie - 
contain arbitrarily many function definitions).  The corresponding 
"trigger" might look something like:

foo(5)

That is an identifier "trigger" will contain the string "foo(5)".  This 
string should only contain one single expression which should evaluate 
to some return value (as per what the eval() function in Python would 
expect).

Now I've read up on the compile(), code.compile_command(), eval(), 
exec(), and I've lost count of how many other statements that all in 
some way seem to be what I'm looking for, but don't work for one reason 
or another.  What I'd like to do is something like this:

- Compile the "code" block so that the definitions contained are visible 
for later use
- do some other stuff
- at a particular time, evaluate the "trigger" expression which should 
be able to call on the functions declared in the code block

So in semi-Python code:

code = "def foo(n):\n\tx = 3 * n\n\treturn x\n"
trigger = "foo(5)"
compile (code)	# not valid, but intent is to make foo() visible

# do some other stuff

print "Trigger evaluates to: " + eval(trigger)

# do some other stuff

print "Trigger the second time evaluates to: " + eval(trigger)

What I want is the "trigger" to be able to be evaluated many times 
throughout the life of my program, but the "code" to be "compiled" only 
once (the "code" block is to contain only function declarations).  The 
sticking point so far for me is getting the declarations in "code" to be 
visible in the call to eval(trigger).

Any suggestions?

And of course, yes, I know that executing user-supplied code is 
extremely dangerous as you can import all sorts of nasty modules and do 
all sorts of terrible things, so you don't need to warn me about this. =8-p

Thanks in advance for any (helpful, hehe) replies,
--
Adam Parkin
E-mail: pzelnip at telus.net
----------------------
Reputation is what men and women think of us; character is what God and 
angels know of us
	-- Thomas Paine, Quotedb.com


More information about the Discuss mailing list