En Sun, 07 Sep 2008 14:00:48 -0300, Patrick Maupin <[EMAIL PROTECTED]> escribió:

> __builtins__ in 2.5.2 doesn't seem to behave like I remember it did
> the last time I did some custom stuff with it, a very long time ago.
>
> This isn't surprising, because of ongoing optimization, but it's hard
> to google for '__builtins__' so I didn't really find any documentation
> on the current CPython behavior, which in some cases seems quite
> strange to me.
>
> The documentation node at http://docs.python.org/ref/naming.html has a
> "here be dragons" note on __builtins__, which is nice as far as it
> goes, but doesn't provide any help for people wanting to abuse the
> current CPython implementation.  Additionally, the sentence
> immediately above the note, "__builtins__ can be set to a user-created
> dictionary to create a weak form of restricted execution" not only
> contradicts the note, but in some cases appears not to be true.
>
> When the code below is run, either standalone or by importing it, the
> builtins used are different depending on whether exec is used with
> globals() or with a copy of globals().  Any explanations for this
> behavior would be much appreciated.

Python takes some shortcuts when dealing with builtins. I'll just describe what 
happens (I won't say whether it is "right" or "wrong"). 
The exec statement, when given a string source, compiles it and eventually 
calls PyEval_EvalCodeEx, which creates a new frame using PyFrame_New and 
finally executes it.
A frame object contains a pointer to the previous frame, the code to be 
executed, a pointer to the current globals *and* a separate pointer to the 
current builtins. 
Inside PyFrame_New, there is a shortcut: if the new frame and the previous one 
share the same globals, then the previous builtins are copied into the new 
frame. Only if the globals differ the builtins are searched in globals. From 
frameobject.c: /* If we share the globals, we share the builtins. Save a lookup 
and a call. */ 
It is this assumption that fails in your code.

If you want to execute some code with modified builtins, do not change 
__builtins__ in the *calling* code, but in the globals that you pass to the 
exec call. That appears to be the most logical approach, and the way the 
developers appear to have expected.

-- 
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to