Guido van Rossum wrote:
On Thu, Mar 8, 2012 at 4:33 PM, Nick Coghlan <ncogh...@gmail.com> wrote:
On Fri, Mar 9, 2012 at 3:31 AM, Guido van Rossum <gu...@python.org> wrote:
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.
Agreed, but swapping out builtins for a different namespace is still
the exception rather than the rule. My Impression of Mark's proposal
was that this approach would become the *preferred* way of doing
things, and that's the part I don't like at a conceptual level.

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.
And this is where I don't like the idea at a practical level. We
already have a way to swap in a different set of builtins for a
certain execution context (i.e. set "__builtins__" in the global
namespace) for a small chunk of code, as well as allowing
collections.ChainMap to insert additional namespaces into the name
lookup path.

This proposal suggests adding an additional mapping argument to every
API that currently accepts a locals and/or globals mapping, thus
achieving... well, nothing substantial, as far as I can tell (aside
from a lot of pointless churn in a bunch of APIs, not all of which are
under our direct control).

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.
Acknowledged, but code executed via the exec API with both locals and
globals passed in is actually one of the few places where that lookup
chain survives in its original form (module level class definitions
being the other).

Now, rereading Mark's original message, a simpler proposal of having
*function objects* do an early lookup of
"self.__globals__['__builtins__']" at creation time and caching that
somewhere such that the frame objects can get hold of it (rather than
having to do the lookup every time the function gets called or a
builtin gets referenced) might be a nice micro-optimisation. It's the
gratuitous API changes that I'm objecting to, not the underlying idea
of binding the reference to the builtins namespace earlier in the
function definition process. I'd even be OK with leaving the default
builtins reference *out* of the globals namespace in favour of storing
a hidden reference on the frame objects.

Agreed on the gratuitous API changes. I'd like to hear Mark's response.

C API or Python API?

The Python API would be changed, but in a backwards compatible way.
exec, eval and __import__ would all gain an optional (keyword-only?)
"builtins" parameter.

I see no reason to change any of the C API functions.
New functions taking an extra parameter could be added,
but it wouldn't be a requirement.

Cheers,
Mark




_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to