[Python-ideas] History on proposals for Macros?

Nathaniel Smith njs at pobox.com
Thu Apr 2 00:17:55 CEST 2015


On Apr 1, 2015 3:02 PM, "Andrew Barnert" <abarnert at yahoo.com.dmarc.invalid>
wrote:
>
> On Wednesday, April 1, 2015 12:40 PM, Ron Adam <ron3200 at gmail.com> wrote:
> > When exec is given a code object, it call's PyEval_EvalCodeEx in
> > ceval.c directly with local and global dictionaries.  (That should
answer
> > some of your comments as to why I uses the dictionary.)
>
> Yes, and running the block of code directly with the local and global
dictionaries is exactly what you want it to do, so why are you telling it
not to do that?
>
> For example:
>
>
>     def macro():
>         x += 1
>     code = fix_code(macro.__code__)
>
>     def f(code_obj):
>         x = 1
>         loc = locals()
>         eval(code_obj)
>         return loc['x']
>
> (Or, if you prefer, use "run_code_obj" instead of "eval".)
>
> The problem here is that if you just "return x" at the end instead of
"return loc['x']", you will likely see 1 instead of 2. It's the same
problem you get if you "exec('x += 1')", exactly as described in the docs.
>
> That happens because f was compiled to look up x by index in the
LOAD_FAST locals array, instead of by name in the locals dict, but your
modified code objects mutate only the dict, not the array. That's the big
problem you need to solve. Adding more layers of indirection doesn't get
you any closer to fixing it.

You can propagate changes to the dict back to the array by calling the c
api function PyFrame_LocalsToDict. It's pretty easy to do via ctypes, see
e.g.

http://pydev.blogspot.com/2014/02/changing-locals-of-frame-frameflocals.html?m=1

I guess you could append some byte code to do this to your modified
function bodies.

-n
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150401/5027d526/attachment-0001.html>


More information about the Python-ideas mailing list