sys.settrace 'call' event behavior
R. Bernstein
rocky at panix.com
Thu Dec 11 05:06:31 EST 2008
On Jun 21, 8:47 am, Michal Kwiatkowski <constant.b... at gmail.com> wrote:
> I'm building a tool to trace all function calls usingsys.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 functioncalldiffers 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):
> ifevent== '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 syssys.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.htmlsays thatcallevent
> happens when "a function is called (or some other code block
> entered)."
>
> [2]http://docs.python.org/ref/types.html#l2h-145
>
> Cheers,
> mk
Perhaps you could filter based on the type of the frame.f_code.co_name ?
e.g. or type(eval(frame.f_code.co_name))
(Sorry for the delayed reply - I don't generally read the newsgroup
and stumbled across this looking for something else. But I noticed no
replies, so...)
More information about the Python-list
mailing list