This is more or less what I had in mind. Two things have been
bothering me:
(A) The argument order for exec/eval is globals, locals. Since I only
dare add new optional arguments at the end, the order would become
globals, locals, builtins, which is different from the search order
(locals, globals, builtins).
(B) Extending every function object in the world with a builtins slot
is doable but somewhat inefficient. (I'm doing just this for doc
strings, coding it at this very moment...)
I think that we can safely assume that two functions using the same
set of globals will also be using the same set of builtins (though not
the reverse). Therefore an alternative would be to bury the
information on what set of builtins to use inside the globals -- e.g.,
have an optional slot __builtins__ in the dictionary of globals to
point to the dictionary of builtins. As you propose, this can be
copied into the current frame by eval_code. (The presence of this slot
can also be used to indicate that certain backdoor operations are
disallowed.)
BTW if you get to coding this, I'd like to receive your mods
a.s.a.p. -- the way things are going, they may well end up being
incorporated in Python 1.2!
--Guido van Rossum, CWI, Amsterdam <mailto:Guido.van.Rossum@cwi.nl>
<http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>