Guido van Rossum wrote: > On Thu, Mar 8, 2012 at 4:33 PM, Nick Coghlan <ncoghlan at gmail.com> wrote: >> On Fri, Mar 9, 2012 at 3:31 AM, Guido van Rossum <guido at 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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4