Fuzzyman wrote: > Fuzzyman wrote: > > Hello all, > > > > I'm trying to extract the code object from a function, and exec it > > without explicitly passing parameters. > > > > The code object 'knows' it expects to receive paramaters. It's > > 'arg_count' attribute is readonly. > > > > How can I set the arg_count to 0, or pass parameters to the code object > > when I exec it ? > > > > Ok, so now I'm getting somewhere, without really knowing what I'm > doing. Using the CodeType I can create a new code object with identical > attributes, except an 'argcount' of 0. > > It doesn't quite work, so I probably need to set some of the attributes > *differently*. > > The code I use is : > > >>> def f(x): > ... print x > ... > >>> c = f.func_code > >>> CodeType = type(c) > >>> a = CodeType(0, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code, > ... c.co_consts, c.co_names, c.co_varnames, c.co_filename, > c.co_name, > ... c.co_firstlineno, c.co_lnotab, c.co_freevars, c.co_cellvars) > >>> a > <code object f at 01C707A0, file "<input>", line 1> > >>> exec a > Traceback (most recent call last): > File "<input>", line 1, in ? > File "<input>", line 2, in f > UnboundLocalError: local variable 'x' referenced before assignment > > (the first argument, 0, becomes the 'arg_count' attribute) > > So the code object is still creating a local scope, and knows that x is > a local variable. ('co_nlocals' and 'co_varnames' ?). > > I'd like to construct the code object so that it takes the parameters > from the enclosing scope (the context I pass into exec I guess), > without clobbering any local variables that may be defined in the code > object. > > Anyone got any clues ? >
*Damn* I've extracted the code object and told it that it has no arguments. Executing the code object results in the function object ! The code object is obviously the code object for the function definition. *sigh* I was hoping I could get to the code object for the *body* of the function. Looks like that won't be possible without dis-assembling the bytecode or other tricks even more hackish than what I've already done. For the record, the code I was using was : x = 3 def f(x): print x CodeType = type(f.func_code) def convert_function(f): code = f.func_code nlocals = max(code.co_nlocals - code.co_argcount, 0) newCode = CodeType(0, nlocals, code.co_stacksize, code.co_flags, code.co_code, code.co_consts, code.co_names, code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno, code.co_lnotab, code.co_freevars, code.co_cellvars) return newCode print convert_function(f) exec convert_function(f) Fuzzyman http://www.voidspace.org.uk/python/index.shtml -- http://mail.python.org/mailman/listinfo/python-list