Howto MACRO in python ?

Richie Hindle richie at entrian.com
Tue Aug 12 12:16:31 EDT 2003


[Bill]
> I'm trying to implement some kind of tracing mechanism which will
> announce every function entrance in Run-Time.

Python has built-in support for this kind of thing, without needing to
modify your code at all:

----------------------------- bill-1.py -----------------------------

import sys

def test1():
    print "Hello",

def test2():
    print "world!"

def trace(frame, event, arg):
    if event == 'call':
        print frame.f_code.co_name
    return trace

sys.settrace(trace)
test1()
test2()

--------------------------- end bill-1.py ---------------------------

That gives the following output:

test1
Hello test2
world!

Other values for 'event' are 'line', 'exception' and 'return' - see
http://www.python.org/doc/current/lib/debugger-hooks.html

Your "debug level" feature is not built-in, but you could implement it
something like this, which is hideous but the best I can do at short
notice.  8-)

----------------------------- bill-2.py -----------------------------

import sys

# Trace any functions with a DEBUG_LEVEL above this value.
TRACE_ABOVE = 50

def test1():
    DEBUG_LEVEL = 10
    print "Hello",

def test2():
    """With a docstring."""
    DEBUG_LEVEL = 100
    print "world!"

def test3():
    print "Goodbye."

thisCode = None
firstLineSeen = False
def trace(frame, event, arg):
    # Find the DEBUG_LEVEL if there is one, by skipping the first line of
    # the function.
    global thisCode, firstLineSeen
    if event == 'call':
        thisCode = frame.f_code
        firstLineSeen = False
    elif event == 'line':
        if not firstLineSeen:
            firstLineSeen = True
        else:
            # Now on the second line; trace any calls with a DEBUG_LEVEL
            # greater than TRACE_ABOVE.
            level = frame.f_locals.get('DEBUG_LEVEL', -1)
            if level > TRACE_ABOVE:
                print frame.f_code.co_name
    return trace

sys.settrace(trace)
test1()
test2()
test3()

--------------------------- end bill-2.py ---------------------------

Output:

Hello test2
world!
Goodbye.

You need the 'DEBUG_LEVEL = 10' as the first statement in the function -
of course that defeats the whole object of using sys.settrace in the first
place, but it was a fun exercise.  8-)

Anyone know how I could retrieve function attributes from within a trace
function?  It would be neater.

-- 
Richie Hindle
richie at entrian.com






More information about the Python-list mailing list