[Discuss] Compiling/running user-supplied Python code

noel at natnix.com noel at natnix.com
Thu Aug 10 11:23:20 PDT 2006


Looks like python's eval() doesn't like "def foo():" statements.  I got
it to work with eval(compile()) though:

defstr = "def foo(): print('foo!')"
eval(compile(defstr, '<defstr>', 'exec'))

evalstr = "foo()"
eval(evalstr)

--Noel

On Thu, Aug 10, 2006 at 10:43:44AM -0700, Adam Parkin wrote:
> 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
> _______________________________________________
> Discuss mailing list
> Discuss at vlug.org
> http://ladybug.vlug.org/cgi-bin/mailman/listinfo/discuss


More information about the Discuss mailing list