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 ? The attributes mean (from http://pyref.infogami.com/type-code ) : * co_name gives the function name * co_argcount is the number of positional arguments (including arguments with default values) * co_nlocals is the number of local variables used by the function (including arguments) * co_varnames is a tuple containing the names of the local variables (starting with the argument names) * co_cellvars is a tuple containing the names of local variables that are referenced by nested functions * co_freevars is a tuple containing the names of free variables * co_code is a string representing the sequence of bytecode instructions * co_consts is a tuple containing the literals used by the bytecode * co_names is a tuple containing the names used by the bytecode * co_filename is the filename from which the code was compiled * co_firstlineno is the first line number of the function * co_lnotab is a string encoding the mapping from byte code offsets to line numbers (for details see the source code of the interpreter) * co_stacksize is the required stack size (including local variables) * co_flags is an integer encoding a number of flags for the interpreter. In case anyone wonders, this is purely an experiment in creating 'annoymous code blocks'. :-) What is a 'free variable' ? 'cell_vars' also looks interesting, but probably better not to mess with it :-) (I guess it is only relevant for functions defined in the code block) Fuzzyman http://www.voidspace.org.uk/python/index.shtml -- http://mail.python.org/mailman/listinfo/python-list