By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,291 Members | 1,185 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,291 IT Pros & Developers. It's quick & easy.

sys.settrace 'call' event behavior

P: n/a
I'm building a tool to trace all function calls using sys.settrace
function from the standard library. One of the awkward behaviors of
this facility is that the class definitions are reported as 'call'
events.[1] Since I don't want to catch class definitions, only
function calls, I'm looking for a way to differentiate between those
two. So far I have only vague clues about how to do that.

At the bottom of this mail is a simple script that prints all
attributes (except for the bytecode) of the traced code. In the sample
code Bar class is defined and foo function is called after that. The
following trace output is reported:

Bar, 0, 0, (), (), (), (None,), ('__name__', '__module__', 'None'),
foo.py, 21, , 1, 66
foo, 0, 0, (), (), (), (None,), (), foo.py, 25, , 1, 67

Class definition and function call differs on four attributes. Two of
them, co_name and co_firstlineno are not very helpful. Other two are
co_names and co_flags. The latter differs only by the CO_OPTIMIZED
flag, which is for "internal use only"[2]. So we're left with
co_names, which "is a tuple containing the names used by the
bytecode". Is that helpful in distinguishing between class definitions
and function calls? Do you have any other ideas on how to tell them
apart?

Source of the sample script I used follows.

def trace(frame, event, arg):
if event == 'call':
print ', '.join(map(str, [frame.f_code.co_name,
frame.f_code.co_argcount,
frame.f_code.co_nlocals,
frame.f_code.co_varnames,
frame.f_code.co_cellvars,
frame.f_code.co_freevars,
frame.f_code.co_consts,
frame.f_code.co_names,
frame.f_code.co_filename,
frame.f_code.co_firstlineno,
frame.f_code.co_lnotab,
frame.f_code.co_stacksize,
frame.f_code.co_flags]))
return trace

import sys
sys.settrace(trace)

class Bar(object):
None
pass

def foo():
pass

foo()

[1] It is strange for me, but documented properly.
http://docs.python.org/lib/debugger-hooks.html says that call event
happens when "a function is called (or some other code block
entered)."

[2] http://docs.python.org/ref/types.html#l2h-145

Cheers,
mk
Jun 27 '08 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.