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