Functions and code objects

Fuzzyman fuzzyman at gmail.com
Thu Jul 27 08:48:58 EDT 2006


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




More information about the Python-list mailing list