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

Guido van Rossum guido at python.org
Thu Mar 8 18:31:29 CET 2012


On Thu, Mar 8, 2012 at 5:57 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On Thu, Mar 8, 2012 at 11:40 PM, Mark Shannon <mark at hotpy.org> wrote:
>> Other code will use whatever builtins they were given at __import__.
>
> Then they're not builtins - they're module-specific chained globals.
> The thing that makes the builtins special is *who else* can see them
> (i.e. all the other code in the process). If you replace
> builtins.open, you replace if for everyone (that hasn't either
> shadowed it or cached a reference to the original).

Looks like you two are talking about different things. There is only
one 'builtins' *module*.

But the __builtins__ that are actually used by any particular piece of
code is *not* taken by importing builtins. It is taken from what the
globals store under the key __builtins__.

This is a feature that was added specifically for sandboxing purposes,
but I believe it has found other uses too.

>> The key point is that every piece of code already inherits locals, globals
>> and builtins from somewhere else.
>> We can already control locals (by which parameters are passed in) and
>> globals via exec, eval, __import__, and runpy (any others?)
>> but we can't control builtins.
>
> Correct - because controlling builtins is the domain of sandboxes.

Incorrect (unless I misunderstand the context) -- when you control the
globals you control the __builtins__ set there.

>> One last point is that this is a low-impact change. All code using eval,
>> etc. will continue to work as before.
>> It also may speed things up a little.
>
> Passing in a ChainMap instance as the globals when you want to include
> an additional namespace in the lookup chain is even lower impact.
>
> A reference implementation and concrete use cases might change my
> mind, but for now, I'm just seeing a horrendously complicated approach
> with huge implications for the runtime data model semantics for
> something that 3.3 already supports in a much simpler fashion.

I can't say I'm completely following the discussion. It's not clear
whether what I just explained was already implicit in the coversation
or is new information.

In any case, the locals / globals / builtins chain is a
simplification; there are also any number of intermediate scopes
(between locals and globals) from which "nonlocal" variables may be
used. Like optimized function globals, these don't use a dict lookup
at all, they are determined by compile-time analysis.

-- 
--Guido van Rossum (python.org/~guido)


More information about the Python-Dev mailing list