I've seen this multiple times in multiple places, but never have found a satisfying explanation as to why this should be the case.
So, hopefully, one will be presented here. Why should we (at least, generally) not use exec() and eval()?
EDIT: I see that people are assuming that this question pertains to web servers – it doesn't. I can see why an unsanitized string being passed to exec could be bad. Is it bad in non-web-applications?
There are often clearer, more direct ways to get the same effect. If you build a complex string and pass it to exec, the code is difficult to follow, and difficult to test.
Example: I wrote code that read in string keys and values and set corresponding fields in an object. It looked like this:
for key, val in values:
fieldName = valueToFieldName[key]
fieldType = fieldNameToType[fieldName]
if fieldType is int:
s = 'object.%s = int(%s)' % (fieldName, fieldType)
#Many clauses like this...
exec(s)
That code isn't too terrible for simple cases, but as new types cropped up it got more and more complex. When there were bugs they always triggered on the call to exec, so stack traces didn't help me find them. Eventually I switched to a slightly longer, less clever version that set each field explicitly.
The first rule of code clarity is that each line of your code should be easy to understand by looking only at the lines near it. This is why goto and global variables are discouraged. exec and eval make it easy to break this rule badly.
When you need exec and eval, yeah, you really do need them.
But, the majority of the in-the-wild usage of these functions (and the similar constructs in other scripting languages) is totally inappropriate and could be replaced with other simpler constructs that are faster, more secure and have fewer bugs.
You can, with proper escaping and filtering, use exec and eval safely. But the kind of coder who goes straight for exec/eval to solve a problem (because they don't understand the other facilities the language makes available) isn't the kind of coder that's going to be able to get that processing right; it's going to be someone who doesn't understand string processing and just blindly concatenates substrings, resulting in fragile insecure code.
It's the Lure Of Strings. Throwing string segments around looks easy and fools naïve coders into thinking they understand what they're doing. But experience shows the results are almost always wrong in some corner (or not-so-corner) case, often with potential security implications. This is why we say eval is evil. This is why we say regex-for-HTML is evil. This is why we push SQL parameterisation. Yes, you can get all these things right with manual string processing... but unless you already understand why we say those things, chances are you won't.
eval() and exec() can promote lazy programming. More importantly it indicates the code being executed may not have been written at design time therefore not tested. In other words, how do you test dynamically generated code? Especially across browsers.
Security aside, eval and exec are often marked as undesirable because of the complexity they induce. When you see a eval call you often don't know what's really going on behind it, because it acts on data that's usually in a variable. This makes code harder to read.
Invoking the full power of the interpreter is a heavy weapon that should be only reserved for very tricky cases. In most cases, however, it's best avoided and simpler tools should be employed.
That said, like all generalizations, be wary of this one. In some cases, exec and eval can be valuable. But you must have a very good reason to use them. See this post for one acceptable use.
In contrast to what most answers are saying here, exec is actually part of the recipe for building super-complete decorators in Python, as you can duplicate everything about the decorated function exactly, producing the same signature for the purposes of documentation and such. It's key to the functionality of the widely used decorator module (http://pypi.python.org/pypi/decorator/). Other cases where exec/eval are essential is when constructing any kind of "interpreted Python" type of application, such as a Python-parsed template language (like Mako or Jinja).
So it's not like the presence of these functions are an immediate sign of an "insecure" application or library. Using them in the naive javascripty way to evaluate incoming JSON or something, yes that's very insecure. But as always, its all in the way you use it and these are very essential functions.
I have used eval() in the past (and still do from time-to-time) for massaging data during quick and dirty operations. It is part of the toolkit that can be used for getting a job done, but should NEVER be used for anything you plan to use in production such as any command-line tools or scripts, because of all the reasons mentioned in the other answers.
You cannot trust your users--ever--to do the right thing. In most cases they will, but you have to expect them to do all of the things you never thought of and find all of the bugs you never expected. This is precisely where eval() goes from being a tool to a liability.
A perfect example of this would be using Django, when constructing a QuerySet. The parameters passed to a query accepts keyword arguments, that look something like this:
results = Foo.objects.filter(whatever__contains='pizza')
If you're programmatically assigning arguments, you might think to do something like this:
results = eval("Foo.objects.filter(%s__%s=%s)" % (field, matcher, value))
But there is always a better way that doesn't use eval(), which is passing a dictionary by reference:
results = Foo.objects.filter( **{'%s__%s' % (field, matcher): value} )
By doing it this way, it's not only faster performance-wise, but also safer and more Pythonic.
Moral of the story?
Use of eval() is ok for small tasks, tests, and truly temporary things, but bad for permanent usage because there is almost certainly always a better way to do it!
Allowing these function in a context where they might run user input is a security issue, and sanitizers that actually work are hard to write.
Same reason you shouldn't login as root: it's too easy to shoot yourself in the foot.
Don't try to do the following on your computer:
s = "import shutil; shutil.rmtree('/nonexisting')"
eval(s)
Now assume somebody can control s from a web application, for example.
Reason #1: One security flaw (ie. programming errors... and we can't claim those can be avoided) and you've just given the user access to the shell of the server.
Try this in the interactive interpreter and see what happens:
>>> import sys
>>> eval('{"name" : %s}' % ("sys.exit(1)"))
Of course, this is a corner case, but it can be tricky to prevent things like this.
So I recently ran into a framework (for a chat bot) that was very clever.
It used a combination of things to make it extremely dynamic. Most of these things I already know how to replicate. Yet there was something that really caught my eye, and made me really wonder.
How do you obtain the comment?
def foo():
'''My function comment'''
return 'foo!'
In this framework: It would pull the comment, and use it as it's help.
So for example we say !help foo
It would return My function comment
It really boggles my mind, since I always thought comments weren't kept in memory. So I have to assume it's using some kind of inspection on it's own file. I'm just very curious on how this works, and if anyone has any libraries that would help with this, please let me know.
Edit: for anyone wanting to look at the framework; here is the link
That's not a comment - comments are lines that start with #
This is a docstring.
You can access the docstring using foo.__doc__
The help function would thus be
def help(thing)
return thing.__doc__
When you type !help foo behind the scenes the framework calls help(foo).
You can access it with .__doc__
I've recently started working at a company doing work in Python, and in their code they have a class which defines a handful of functions that do nothing, and return nothing. Code that is pretty much exactly
...
...
def foo(self):
return
I'm really confused as to why anyone would do that, and my manager is not around for me to ask. Would one do this for the sake of abstraction for child classes? A signal that the function will be overridden in the future? The class I'm looking at in particular inherits from a base class that does not contain any of the functions that are returning nothing, so I know that at least this class isn't doing some kind of weird function overriding.
Sometimes, if a class is meant to be used interchangeably with another class in the API, it can make sense to provide functions that don't do much (or anything). Depending on the API though, I would typically expect these functions to return something like NotImplemented.
Or, maybe somebody didn't get enough sleep the night before and forgot what they were typing ... or got called away to a meeting without finishing what they were working on ...
Ultimately, nobody can know the actual reason without having a good knowledge of the code you're working with. Basically -- I'd wait for your boss or a co-worker to come around and ask.
If the functions have meaningful names, then it could be a skeleton for future intended functionality.
I would like to know if there is a way of writing the below module code without having to add another indentation level the whole module code.
# module code
if not condition:
# rest of the module code (big)
I am looking for something like this:
# module code
if condition:
# here I need something like a `return`
# rest of the module code (big)
Note, I do not want to throw an Exception, the import should pass normally.
I don't know of any solution to that, but I guess you could put all your code in an internal module and import that if the condition is not met.
I know of no way to do this. The only thing I could imagine that would work would be return but that needs to be inside a function.
It's super hard to say without knowing what your higher-level goal is. (For instance, what is the condition? Why does it matter? Are you DEAD SURE you're not having an X-Y problem here? Can't you just tell us what your overall goal is?) It's also really hard to say without knowing how the module is going to be called. (As a script from the command line? By being imported by another module?) And it would help a lot to know (a) why you're trying to avoid indentation (WWII is over, and we don't need to ration spaces any more; or, to put it more kindly, Python is a language that uses indentation as a SYNTACTIC FEATURE, so saying "I can't use this syntactic feature" strikes many people as a weird constraint. It's like giving up if-then tests: you might theoretically be able to work around that constraint, possibly, sometimes, but why are you going into the boxing ring with your hands tied behind your back?), and (b) why you can't throw an exception (no, really: are you TOTALLY SURE you ABSOLUTELY CANNOT THROW ANY EXCEPTIONS AT ALL?).
As it is, all you've really done is ask a "how do I do X, given conditions A, B, and C?" question, without indicating why you want to do X, or why conditions A, B, and C exist, or even whether you're 100% sure they exist and cannot be worked around.
If what you're really saying is "I don't want to hit {TAB} 40 times while writing a function," then the real problem is that you need a better text editor. If what you're really saying is "I happen to find indentation to be aesthetically unpleasant," then you should think about (a) what the other side of the argument is; that is, why people Python's use of indentation as syntax to be useful; (b) whether your own aesthetic preferences in this regard are more important than the reasons you've come up with in (a); and (c) whether, given these things, Python is the right tool for you personally to be using to accomplish whatever your own larger-scale goal is. (It's OK to not like indentation as a syntactic feature; but this is so basic to Python that being philosophically opposed to it to an extent that rules it out is a strong indication that maybe Python is not the ideal language for you to accomplish your programming goals in.) If what you're really saying is that you would benefit from factoring code that needs to be run under two different sets of circumstances into two modules, then it would benefit you to refactor. If what you're saying is that you've got spaghetti code that winds up being totally impossible to refactor, then that's really the first problem to be addressed, before you try to abort module imports.
I have a block of code that basically intializes several classes, but they are placed in a sequential order, as later ones reference early ones.
For some reason the last one initializes before the first one...it seems to me there is some sort of threading going on. What I need to know is how can I stop it from doing this?
Is there some way to make a class init do something similar to sending a return value?
Or maybe I could use the class in an if statement of some sort to check if the class has already been initialized?
I'm a bit new to Python and am migrating from C, so I'm still getting used to the little differences like naming conventions.
Python upto 3.0 has a global lock, so everything is running in a single thread and in sequence.
My guess is that some side effect initializes the last class from a different place than you expect. Throw an exception in __init__ of that last class to see where it gets called.
Spaces vs. Tabs issue...ugh. >.>
Well, atleast it works now. I admit that I kind of miss the braces from C instead of forced-indentation. It's quite handy as a prototyping language though. Maybe I'll grow to love it more when I get a better grasp of it.