Trace dynamically compiled code?

Ziga Seilnacht ziga.seilnacht at gmail.com
Tue Mar 14 12:45:08 EST 2006


Ed Leafe wrote:
> Hi,
>
> 	Thanks to the help of many on this list, I've been able to take code
> that is created by the user in my app and add it to an object as an
> instance method. The technique used is roughly:

Just some notes about your code:

> nm = "myMethod"
> code = """def myMethod(self):
>     print "Line 1"
>     print "My Value is %s" % self.Value
>     return
> """
> compCode = compile(code, "", "exec")
> exec compCode

Try not using bare exec statements, since they pollute the local scope.
In your example you could use:

compCode = compile(code, "", "exec")
d = {}
exec compCode in d
func = d[nm]

See http://docs.python.org/ref/exec.html for details.

> exec "self.%s = %s.__get__(self)" % (nm, nm)

You don't need dynamic execution here; you can simply use
setattr and the new module:

import new
method = new.instancemethod(func, self)
setattr(self, nm, method)

and yes, I remember that I was the one who suggested you
the __get__ hack.

> 	This is working great, but now I'm wondering if there is a way to
> enable pdb tracing of the code as it executes? When tracing "normal"
> code, pdb will show you the name of the script being executed, the
> line number and the source code for the line about to be executed.
> But when stepping through code compiled dynamically as above, the
> current line's source code is not available to pdb, and thus does not
> display.
>
> 	Does anyone know a way to compile the dynamic code so that pdb can
> 'see' the source? I suppose I could write it all out to a bunch of
> temp files, but that would be terribly messy. Are there any neater
> solutions?

You should check py lib: http://codespeak.net/py/current/doc/ ,
specifically the py.code "module". Then you can modify the
function from above:

import inspect
f = inspect.currentframe()
lineno = f.f_lineno - 5 # or some other constant
filename = f.f_code.co_filename

import py
co = py.code.Code(func)
new_code = co.new(co_lineno=lineno, co_filename=filename)
new_func = new.function(new_code, func.func_globals, nm,
                        func.func_defaults, func.func_closure)


> -- Ed Leafe
> -- http://leafe.com
> -- http://dabodev.com

Ziga Seilnacht




More information about the Python-list mailing list