Peter Waller wrote: > Dear Pythoners, > > I know this will probably be perceived as 'evil voodoo', and fair > enough: it probably is. I guess it is unpythonic. > > .. but I want to know how to do it anyway - mostly for my own > interest.
Well, if you're really just asking out of curiosity, it should be sufficient to tell you that this is not possible. > [...] we have to add this > snippet before the Get() function returns: > > from ctypes import pythonapi, py_object, c_int > pythonapi.PyFrame_LocalsToFast( py_object( frame ), 1 ) > > This copies back the names into the code object, and works fine.. that > is, if the names already exist within the code object. > > def MyFunction(): > a = None > Get("a") > print a # Works > Get("b") > print b # Name error, b is undefined The answer to why this doesn't work lies in the disassembly of that function: 0 LOAD_CONST 0 (0) 3 STORE_FAST 0 (0) 6 LOAD_GLOBAL 1 (1) 9 LOAD_CONST 1 (1) 12 CALL_FUNCTION 1 15 POP_TOP 16 LOAD_FAST 0 (0) <- This is a 19 PRINT_ITEM 20 PRINT_NEWLINE 21 LOAD_GLOBAL 1 (1) 24 LOAD_CONST 2 (2) 27 CALL_FUNCTION 1 30 POP_TOP 31 LOAD_GLOBAL 2 (2) <- This is b 34 PRINT_ITEM 35 PRINT_NEWLINE 36 LOAD_CONST 0 (0) 39 RETURN_VALUE Since you have an assignment to the name a, a is recognized as a local name at compile time. b is not recognized as a local name at compile time, so even if you inject a value for b into the locals dictionary, the byte code still looks up the value as a global name. > Is there any way for Get() to define a new variable within > MyFunction's code object? Or is there any programmatic way to, at > runtime, insert new names into functions? Not without making fundamental changes to Python itself. The fact that this isn't possible is a feature, in my opinion. I like the fact that I can call a function and be *absolutely certain* that it's not going to pollute my local namespace. Hope this helps, -- Carsten Haese http://informixdb.sourceforge.net -- http://mail.python.org/mailman/listinfo/python-list