H
harold fellermann
Hi all,
I am trying to write a script that prints out the signatures
of each function call that occurs during the execution of
a second script which is invoked by my program. i.e. if the
inspected program is 'foo.py':
def bar(x,y,z=None) : pass
bar(1,"a",bar)
bar(2,int)
the output of my script should be:
foo.bar(int,str,function)
foo.bar(int,type,NoneType)
I thought I go for sys.settrace() and achieved the following:
import sys
import types
def tracefunc(frame,event,arg) :
if event is 'call' : return trace_call(frame,event,arg)
else : return None
def trace_call(frame,event,arg) :
code = frame.f_code
scope = frame.f_locals
try :
print code.co_name+"("+",".join(
[ str(type(scope[var])).split("'")[1]
for var in code.co_varnames
]
)+")"
except KeyError : pass
return None
if __name__ == "__main__" :
prog = sys.argv[1]
sys.argv.pop(0)
sys.settrace(tracefunc)
__import__(prog)
the output of the above example is:
bar(int,str,function)
bar(int,type,NoneType)
which is pretty close, but I need / would like to improve several
things,
but have no idea how to do it:
1. I would like to have not only the name of the functions and type
arguments
but their full package/module/class-path, e.g.
xml.dom.pulldom.PullDOM.clear
However, I cannot find a way from the frame object to the function
object
where I could find the information.
2. The KeyError in my code is raised by the "from XXX import" statement:
"from distutils import setup" results in
File "tracetest.py", line 28, in ?
__import__(prog)
File "/Volumes/space/Users/harold/uni/pace/dpd/setup.py", line 1,
in ?
from distutils.core import setup, Extension
File "tracetest.py", line 5, in tracefunc
if event is 'call' : return trace_call(frame,event,arg)
File "tracetest.py", line 12, in trace_call
print code.co_name+"("+",".join(
KeyError: 'setup'
does anyone know how I can circumvent this?
3. Is there any way to set the __name__ attribute for the inspected
script to
"__main__", so that tracing is really transparent?
4. finally, does a functionality like this already exist in the library
or
did anyone of you come up with an implementation?
thanks,
- harold -
I am trying to write a script that prints out the signatures
of each function call that occurs during the execution of
a second script which is invoked by my program. i.e. if the
inspected program is 'foo.py':
def bar(x,y,z=None) : pass
bar(1,"a",bar)
bar(2,int)
the output of my script should be:
foo.bar(int,str,function)
foo.bar(int,type,NoneType)
I thought I go for sys.settrace() and achieved the following:
import sys
import types
def tracefunc(frame,event,arg) :
if event is 'call' : return trace_call(frame,event,arg)
else : return None
def trace_call(frame,event,arg) :
code = frame.f_code
scope = frame.f_locals
try :
print code.co_name+"("+",".join(
[ str(type(scope[var])).split("'")[1]
for var in code.co_varnames
]
)+")"
except KeyError : pass
return None
if __name__ == "__main__" :
prog = sys.argv[1]
sys.argv.pop(0)
sys.settrace(tracefunc)
__import__(prog)
the output of the above example is:
bar(int,str,function)
bar(int,type,NoneType)
which is pretty close, but I need / would like to improve several
things,
but have no idea how to do it:
1. I would like to have not only the name of the functions and type
arguments
but their full package/module/class-path, e.g.
xml.dom.pulldom.PullDOM.clear
However, I cannot find a way from the frame object to the function
object
where I could find the information.
2. The KeyError in my code is raised by the "from XXX import" statement:
"from distutils import setup" results in
File "tracetest.py", line 28, in ?
__import__(prog)
File "/Volumes/space/Users/harold/uni/pace/dpd/setup.py", line 1,
in ?
from distutils.core import setup, Extension
File "tracetest.py", line 5, in tracefunc
if event is 'call' : return trace_call(frame,event,arg)
File "tracetest.py", line 12, in trace_call
print code.co_name+"("+",".join(
KeyError: 'setup'
does anyone know how I can circumvent this?
3. Is there any way to set the __name__ attribute for the inspected
script to
"__main__", so that tracing is really transparent?
4. finally, does a functionality like this already exist in the library
or
did anyone of you come up with an implementation?
thanks,
- harold -