[Python-Dev] Adding a builtins parameter to eval(), exec() and __import__().

Mark Shannon mark at hotpy.org
Wed Mar 7 16:33:20 CET 2012


I propose adding an optional (keyword-only?) 3rd parameter, "builtins"
to exec(), eval(), __import__() and any other functions that take
locals and globals as parameters.

Currently, Python code is evaluated in a context of three name spaces; 
locals(), globals() and builtins.
However, eval & exec only take 2 (optional) namespaces as parameters; 
locals and globals, so access to builtins is poorly defined.

The reason I am proposing this here rather than on python-ideas is that
treating the triple of [locals, globals, builtins] as a single
"execution context" can be implemented in a really nice way.

Internally, the execution context of [locals, globals, builtins]
can be treated a single immutable object (custom object or tuple)
Treating it as immutable means that it can be copied merely by taking a 
reference. A nice trick in the implementation is to make a NULL locals
mean "fast" locals for function contexts. Frames, could then acquire 
their globals and builtins by a single reference copy from the function 
object, rather than searching globals for a '__builtins__'
to find the builtins.

A unified execution context will speed up all calls
(to Python functions) as frame allocation and deallocation would be faster.
I used this implementation in my original HotPy VM, and it worked well.

It should also help with sandboxing, as it would make it easier to
analyse and thus control access to builtins, since the execution context
of all code would be easier to determine.

Currently, it is impossible to allow one function access to sensitive 
functions like open(), while denying it to others, as any code can then
get the builtins of another function via f.__globals__['builtins__'].
Separating builtins from globals could solve this.

Cheers,
Mark.


More information about the Python-Dev mailing list