For code:
#!/usr/bin/python
src = """
print '!!!'
import os
"""
obj = compile(src, '', 'exec')
eval(obj, {'__builtins__': False})
I get output:
!!!
Traceback (most recent call last):
File "./test.py", line 9, in <module>
eval(obj, {'__builtins__': False})
File "", line 3, in <module>
ImportError: __import__ not found
Both 'print' and 'import' are language construct. Why does 'eval' restrict using of 'import' but doesn't restrict 'print'?
P.S. I'm using python 2.6
UPDATE: Question is not "Why does import not work?" but "Why does print work?" Are there some architecture restrictions or something else?
The __import__
method is invoked by the import
keyword: python.org
If you want to be able to import a module you need to leave the __import__
method in the builtins:
src = """
print '!!!'
import os
"""
obj = compile(src, '', 'exec')
eval(obj, {'__builtins__': {'__import__':__builtins__.__import__}})
In your eval
the call to import
is made successfully however import
makes use of the __import__
method in builtins which you have made unavailable in your exec
. This is the reason why you are seeing
ImportError: __import__ not found
print
doesn't depend on any builtins so works OK.
You could pass just __import__
from builtins with something like:
eval(obj, {'__builtins__' : {'__import__' :__builtins__.__import__}})
print works because you specified 'exec'
to the compile
function call.
import
calls the global/builtin __import__
function; if there isn't one to be found, import
fails.
print
does not rely on any globals to do its work. That is why print
works in your example, even though you do not use the available __builtins__
.