There is an eval() function in Python I stumbled upon while playing around. I cannot think of a case when this function is needed, except maybe as syntactic sugar. Can anyone give an example?
eval and exec are handy quick-and-dirty way to get some source code dynamically, maybe munge it a bit, and then execute it -- but they're hardly ever the best way, especially in production code as opposed to "quick-and-dirty" prototypes &c.
For example, if I had to deal with such dynamic Python sources, I'd reach for the ast module -- ast.literal_eval is MUCH safer than eval (you can call it directly on a string form of the expression, if it's a one-off and relies on simple constants only, or do node = ast.parse(source) first, then keep the node around, perhaps munge it with suitable visitors e.g. for variable lookup, then literal_eval the node) -- or, once having put the node in proper shape and vetted it for security issues, I could compile it (yielding a code object) and build a new function object out of that. Far less simple (except that ast.literal_eval is just as simple as eval for the simplest cases!) but safer and preferable in production-quality code.
For many tasks I've seen people (ab-)use exec and eval for, Python's powerful built-ins, such as getattr and setattr, indexing into globals(), &c, provide preferable and in fact often simpler solutions. For specific uses such as parsing JSON, library modules such as json are better (e.g. see SilentGhost's comment on tinnitus' answer to this very question). Etc, etc...
The Wikipedia article on eval is pretty informative, and details various uses.
Some of the uses it suggests are:
Evaluating mathematical expressions
Compiler bootstrapping
Scripting (dynamic languages in general are very suitable to this)
Language tutors
You may want to use it to allow users to enter their own "scriptlets": small expressions (or even small functions), that can be used to customize the behavior of a complex system.
In that context, and if you do not have to care too much for the security implications (e.g. you have an educated userbase), then eval() may be a good choice.
In the past I have used eval() to add a debugging interface to my application. I created a telnet service which dropped you into the environment of the running application. Inputs were run through eval() so you can interactively run Python commands in the application.
In a program I once wrote, you had an input file where you could specify geometric parameters both as values and as python expressions of the previous values, eg:
a=10.0
b=5.0
c=math.log10(a/b)
A python parser read this input file and obtained the final data evaluating the values and the expressions using eval().
I don't claim it to be good programming, but I did not have to drive a nuclear reactor.
I use it as a quick JSON parser ...
r='''
{
"glossary": {
"title": "example glossary"
}
}
'''
print eval(r)['glossary']['title']
You can use eval in a decorator:
#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
#eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
print("The number is %i", i)
#call
printNumber()
while you cannot use complex expressions like
#lambda fun: lambda: fun(10)
def ...
nor
#(lambda fun: lambda: fun(10))
def ...
You cannot use a lambda-expression there, because the decorator should either be an identifier:
#myModule.functionWithOneArg
or a function call:
#functionReturningFunctionWithOneArg(any, "args")
You see that the call of the function eval with a string has valid syntax here, but the lambda-expression not. (-> https://docs.python.org/3/reference/compound_stmts.html#function-definitions)
eval() is not normally very useful. One of the few things I have used it for (well, it was exec() actually, but it's pretty similar) was allowing the user to script an application that I wrote in Python. If it were written in something like C++, I would have to embed a Python interpreter in the application.
Eval is a way to interact with the Python interpreter from within a program. You can pass literals to eval and it evaluates them as python expressions.
For example -
print eval("__import__('os').getcwd()")
would return the current working directory.
cheers
eval() is for single sentence, while exec() is for multiple ones.
usually we use them to add or visit some scripts just like bash shell.
because of they can run some byte scripts in the memory, if you have some important data or script you can decode and unzip your 'secret' then do everything you wanna.
I just came across a good use of eval. I was writing a test suite for some code, and created a Test class, where every method was a test to be run. I wanted a way so that I could run all the test methods without having to call each method individually. So, I wrote something rather dirty.
class Test:
def __init__(self, *args):
#bs
def test1(self):
#bs
def test2(self):
#bs
if __name__ == "__main__":
import argparse
#argparse bs
test = Test(*bs_args)
for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
print(eval('test.{func}()'.format(func = func)))
Dynamic evaluation of arbitrary test cases is pretty cool. I just have to write the method, and after saving I can include the method in my test suite. As for the code, I basically just inspect the methods defined in the test object, and make sure they aren't default python "magic" methods or attributes to the Test object. After that I can assume they are methods and can be evaluated.
I used it to input variable values to the main program:
test.py var1=2 var2=True
...
var1=0
var2=False
for arg in sys.argv[1:]:
exec(arg)
A crude way to allow keyword args in the main program. If there's a better way let me know!
I had a case where I used eval in combination with an informix database. For some reason the query returned a string formed like this
query_result = "['1', '2', '3']"
I just used eval on the query result so python interpreted it as a list of strings.
[int(i) for i in eval(query_result)]
> [1,2,3]
I could not change the db so this was a quick (and dirty) way to get the integers.
I use exec to create a system of plugins in Python.
try:
exec ("from " + plugin_name + " import Plugin")
myplugin = Plugin(module_options, config=config)
except ImportError, message:
fatal ("No such module " + plugin_name + \
" (or no Plugin constructor) in my Python path: " + str(message))
except Exception:
fatal ("Module " + plugin_name + " cannot be loaded: " + \
str(sys.exc_type) + ": " + str(sys.exc_value) + \
".\n May be a missing or erroneous option?")
With a plugin like:
class Plugin:
def __init__ (self):
pass
def query(self, arg):
...
You will be able to call it like:
result = myplugin.query("something")
I do not think you can have plugins in Python without exec/eval.
Related
When I pass the options in the program (a computational biology experiment) I usually pass them through a .py file.
So I have this .py file that reads like:
starting_length=9
starting_cell_size=1000
LengthofExperiments=5000000
Then I execute the file and get the data. Since the program is all on my machine and no one else has access to it, it is secure in a trivial way.
I can also write a similar file very easily:
def writeoptions(directory):
options=""
options+="starting_length=%s%s"%(starting_length,os.linesep)
options+="starting_cell_size=%s%s"%(starting_cell_size,os.linesep)
options+="LengthofExperiments=%s%s"%(LengthofExperiments,os.linesep)
...
open("%s%soptions.py"%(directory,os.sep),'w').write(options)
I want to pass a function as one of the parameters:
starting_length=9
starting_cell_size=1000
LengthofExperiments=5000000
def pippo(a,b):
return a+b
functionoperator=pippo
And of course in the real experiment the function pippo will be much more complex. And different from experiment to experiment.
But what I am unable to do is to write the function automatically. In short I don't know how to generalise the writeoptions function to keep on writing the options, if one of the options is a function. I could of course copy the original file, but this is inelegant, inefficient (because it contains a lot of extra options that are not being used), and generally does not solve the question.
How do you get python to write down the code of a function, as it writes down the value of a variable?
vinko#mithril$ more a.py
def foo(a):
print a
vinko#mithril$ more b.py
import a
import inspect
a.foo(89)
print inspect.getsource(a.foo)
vinko#mithril$ python b.py
89
def foo(a):
print a
You might also consider some other means of data persistence. In my own (astronomy) research, I've been experimenting with two different means of storing scripts for reproducibility. The first is to have them exclusively inside a subversion repository, and then have the job submission script automatically commit them. For instance, if you just wanted to do this in bash:
alias run_py='svn ci -m "Commit before running"; python2.5 $*'
and inside the script, have the output prefixed by the current subversion revision number for that file, you'd have a record of each script that was run and what the input was. You could pull this back out of subversion as need be.
Another, substantially less full-featured, means of tracking the input to a function could be via something like LodgeIt, a pastebin that accepts XML-RPC input and comes with Python bindings. (It can be installed locally, and has support for replying to and updating existing pastes.)
But, if you are looking for a relatively small amount of code to be included, Vinko's solution using inspect should work quite well. Doug Hellman covered the inspect module in his Python Module of the Week series. You could create a decorator that examines each option and argument and then prints it out as appropriate (I'll use inspect.getargspec to get the names of the arguments.)
import inspect
from functools import wraps
def option_printer(func):
#wraps(func)
def run_func(*args, **kwargs):
for name, arg in zip(inspect.getargspec(func)[0], args) \
+ sorted(kwargs.items()):
if isinstance(arg, types.FunctionType):
print "Function argument '%s' named '%s':\n" % (name, func.func_name)
print inspect.getsource(func)
else:
print "%s: %s" % (name, arg)
return func(*args, **kwargs)
return run_func
This could probably be made a bit more elegant, but in my tests it works for simple sets of arguments and variables. Additionally, it might have some trouble with lambdas.
Are you asking about this?
def writeoptions(directory):
options=""
options+="starting_length=%s%s"%(starting_length,os.linesep)
options+="starting_cell_size=%s%s"%(starting_cell_size,os.linesep)
options+="LengthofExperiments=%s%s"%(LengthofExperiments,os.linesep)
options+="def pippo(a,b):%s" % ( os.linesep, )
options+=" '''Some version of pippo'''%s" % ( os.linesep, )
options+=" return 2*a+b%s" % ( os.linesep, )
open("%s%soptions.py"%(directory,os.sep),'w').write(options)
Or something else?
While it is possible to do what you ask (as Vinko has shown), I'd say it is cleaner to share code. Put pippo and his buddies in a submodule that both programs can access.
Instead of diving into the subject of disassemblers and bytecodes (e.g inspect), why don't you just save the generated Python source in a module (file.py), and later, import it?
I would suggest looking into a more standard way of handling what you call options. For example, you can use the JSON module and save or restore your data. Or look into the marshal and pickle modules.
I wrote a simple command-line tool in Python. To simplify the logic, I use a dict for storing the commands and handlers, something like this:
#!/usr/bin/env python
# some code here
DISPACHERS = {
"run": func_run
"list": func_list
}
# other code
The problem is, I have to put this piece of code after the function declarations, which is not the standard practice I have seen in other languages (i.e. constants in one block, variables after, and then the functions).
I could use strings for storing the function, and retrieve it using something like getattr(__main__, "func_run"), so I can stick with my preference, but I wonder if that's a "proper" way.
Any idea?
=== Update ===
Since it's a simple python script that handles some automation tasks of another project, so it would be better to keep it in a single file (no other module) if possible.
Use a decorator to enumerate the functions.
dispatchmap = {}
def dispatcher(name):
def add_dispatcher(func):
dispatchmap[name] = func
return func
return add_dispatcher
...
#dispatcher('run')
def func_run(...):
...
I have router that is deciding which function to call based upon user input (uses ConfigParser) and then tries to decide which function to call.
def SomethingElse():
print 'hello'
def UploadDirectory():
print 'hi'
def router(config):
if config.has_option('job', 'Some_Task'):
taskName = config.get('job', 'Some_Task')
# taskName is now 'UploadDirectory'
###execute the UploadDirectory function
###execute something else if something else, etc
So what is the way to write this in python? If I prebuilt a map of functions to strings, can i execute them that way?
How would you write this?
Yep, building a map of strings to function names is perfectly valid:
task_map = {
'upload': UploadDirectory,
'something': SomethingElse,
}
And execute as:
task_map[task_name]()
Aside: try to follow PEP-8, the python style guide; it helps make your code more readable to all other Python programmers. Specifically in this case, prefer underscore_separated function names instead of LeadingCaps.
Another hacky way to do it is to use globals(), if you're not running just by importing the router function:
globals()[taskName]()
def myFunc(arg1, arg2):
print "This is a test with " + arg1 + " and " + arg2
while (input != "quit"):
input = raw_input("> ")
if input != "quit":
eval(input)
This code gives me a prompt, allowing me to invoke myFunc with parameters I want. I know that eval can be dangerous if a dictionary is not supplied, so I added this:
eval(input, {"__builtins__": {} }
Now I can no longer invoke myFunc. How do I fix this without leaving eval open to exploits?
This will allow you to use myFunc:
eval(input, {"__builtins__": {}, "myFunc": myFunc})
However, as others have pointed out, using eval is inherently insecure, and still vulnerabe to exploits.
Your question, "How do I fix this without leaving eval open to exploits?", isn't the right oneāeval is vulnerable to exploits, period. Not introducing __builtins__ into the global namespace of the evaluated code does not make the __builtin__ module impossible to access, and it doesn't close off other points of entry.
If you explained more about the problem you are trying to solve, someone may be able to suggest a secure option to accomplish your goals.
If you need a demonstration of how eval is still dangerous even with the builtins removed, see this: Eval really is dangerous. There are examples there of segfaulting the CPython interpreter, or of exiting it directly.
How do I execute a string containing Python code in Python?
Do not ever use eval (or exec) on data that could possibly come from outside the program in any form. It is a critical security risk. You allow the author of the data to run arbitrary code on your computer. If you are here because you want to create multiple variables in your Python program following a pattern, you almost certainly have an XY problem. Do not create those variables at all - instead, use a list or dict appropriately.
For statements, use exec(string) (Python 2/3) or exec string (Python 2):
>>> my_code = 'print("hello world")'
>>> exec(my_code)
Hello world
When you need the value of an expression, use eval(string):
>>> x = eval("2+2")
>>> x
4
However, the first step should be to ask yourself if you really need to. Executing code should generally be the position of last resort: It's slow, ugly and dangerous if it can contain user-entered code. You should always look at alternatives first, such as higher order functions, to see if these can better meet your needs.
In the example a string is executed as code using the exec function.
import sys
import StringIO
# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()
code = """
def f(x):
x = x + 1
return x
print 'This is my output.'
"""
# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr
exec code
# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print f(4)
s = codeErr.getvalue()
print "error:\n%s\n" % s
s = codeOut.getvalue()
print "output:\n%s" % s
codeOut.close()
codeErr.close()
eval and exec are the correct solution, and they can be used in a safer manner.
As discussed in Python's reference manual and clearly explained in this tutorial, the eval and exec functions take two extra parameters that allow a user to specify what global and local functions and variables are available.
For example:
public_variable = 10
private_variable = 2
def public_function():
return "public information"
def private_function():
return "super sensitive information"
# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len
>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12
>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined
>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters
>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined
In essence you are defining the namespace in which the code will be executed.
Remember that from version 3 exec is a function!
so always use exec(mystring) instead of exec mystring.
Avoid exec and eval
Using exec and eval in Python is highly frowned upon.
There are better alternatives
From the top answer (emphasis mine):
For statements, use exec.
When you need the value of an expression, use eval.
However, the first step should be to ask yourself if you really need to. Executing code should generally be the position of last resort: It's slow, ugly and dangerous if it can contain user-entered code. You should always look at alternatives first, such as higher order functions, to see if these can better meet your needs.
From Alternatives to exec/eval?
set and get values of variables with the names in strings
[while eval] would work, it is generally not advised to use variable names bearing a meaning to the program itself.
Instead, better use a dict.
It is not idiomatic
From http://lucumr.pocoo.org/2011/2/1/exec-in-python/ (emphasis mine)
Python is not PHP
Don't try to circumvent Python idioms because some other language does it differently. Namespaces are in Python for a reason and just because it gives you the tool exec it does not mean you should use that tool.
It is dangerous
From http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html (emphasis mine)
So eval is not safe, even if you remove all the globals and the builtins!
The problem with all of these attempts to protect eval() is that they are blacklists. They explicitly remove things that could be dangerous. That is a losing battle because if there's just one item left off the list, you can attack the system.
So, can eval be made safe? Hard to say. At this point, my best guess is that you can't do any harm if you can't use any double underscores, so maybe if you exclude any string with double underscores you are safe. Maybe...
It is hard to read and understand
From http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (emphasis mine):
First, exec makes it harder to human beings to read your code. In order to figure out what's happening, I don't just have to read your code, I have to read your code, figure out what string it's going to generate, then read that virtual code. So, if you're working on a team, or publishing open source software, or asking for help somewhere like StackOverflow, you're making it harder for other people to help you. And if there's any chance that you're going to be debugging or expanding on this code 6 months from now, you're making it harder for yourself directly.
eval() is just for expressions, while eval('x+1') works, eval('x=1') won't work for example. In that case, it's better to use exec, or even better: try to find a better solution :)
It's worth mentioning that exec's brother exists as well, called execfile, if you want to call a Python file. That is sometimes good if you are working in a third party package which have terrible IDE's included and you want to code outside of their package.
Example:
execfile('/path/to/source.py')
or:
exec(open("/path/to/source.py").read())
You accomplish executing code using exec, as with the following IDLE session:
>>> kw = {}
>>> exec( "ret = 4" ) in kw
>>> kw['ret']
4
As the others mentioned, it's "exec" ..
but, in case your code contains variables, you can use "global" to access it, also to prevent the compiler to raise the following error:
NameError: name 'p_variable' is not defined
exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)
I tried quite a few things, but the only thing that worked was the following:
temp_dict = {}
exec("temp_dict['val'] = 10")
print(temp_dict['val'])
output:
10
Use eval.
Check out eval:
x = 1
print eval('x+1')
->2
The most logical solution would be to use the built-in eval() function .Another solution is to write that string to a temporary python file and execute it.
Ok .. I know this isn't exactly an answer, but possibly a note for people looking at this as I was. I wanted to execute specific code for different users/customers but also wanted to avoid the exec/eval. I initially looked to storing the code in a database for each user and doing the above.
I ended up creating the files on the file system within a 'customer_filters' folder and using the 'imp' module, if no filter applied for that customer, it just carried on
import imp
def get_customer_module(customerName='default', name='filter'):
lm = None
try:
module_name = customerName+"_"+name;
m = imp.find_module(module_name, ['customer_filters'])
lm = imp.load_module(module_name, m[0], m[1], m[2])
except:
''
#ignore, if no module is found,
return lm
m = get_customer_module(customerName, "filter")
if m is not None:
m.apply_address_filter(myobj)
so customerName = "jj"
would execute apply_address_filter from the customer_filters\jj_filter.py file