quick search:
 

Basically very useful debug function

Submitted by: peterbe
Last Edited: 2005-07-27

Category: Product Development

Average rating is: 0.0 out of 5 (0 ratings)

Description:
Here's a debug() script that I use instead in most of my product code. It's more less an improvement from the basic 'print' function. With this function you can indent the output, see where it was called and disable it globally with the DEBUG variable (see code).

Source (Text):
import inspect, os, sys
DEBUG = int(os.environ.get('DEBUG_MYPRODUCT', 0))

##
## Debugging
##

def ObserverProxy(method_names):
    class Proxy:
        def __init__(self):
            self._observers = []
        def add_observer(self, observer):
            self._observers.append(observer)
        def remove_observer(self, observer):
            self._observers.remove(observer)

    def create_method_proxy(method_name):
        def method_proxy(self, *args, **kwargs):
            for observer in self._observers:
                getattr(observer, method_name)(*args, **kwargs)
        return method_proxy

    for method_name in method_names:
        setattr(Proxy, method_name, create_method_proxy(method_name))

    return Proxy()


debugobserver = ObserverProxy(["write", "close"])
debugobserver.add_observer(sys.stdout)
#debugobserver.add_observer(open('myproduct-debug.log','a'))



def debug(s, tabs=0, steps=(1,), f=False):
    if DEBUG or f:
        inspect_dbg = []
        if type(steps)==type(1):
            steps = range(1, steps+1)
        for i in steps:
            try:
                #caller_module = inspect.stack()[i][1]
                caller_method = inspect.stack()[i][3]
                caller_method_line = inspect.stack()[i][2]
            except IndexError:
                break
            inspect_dbg.append("%s:%s"%(caller_method, caller_method_line))
        out = "\t"*tabs + "%s (%s)"%(s, ", ".join(inspect_dbg))
        print >>debugobserver, out

Explanation:
You might want to use it differently in your particular environment but this will give you some ideas. For example, look at the way 'debugobserver' accepts any objects that have a 'write' method.

Usage of this (installing you have to figure out yourself :)

class MyProduct(...)
....def foo(self, x):
........debug("We're calling foo() with %r" % x)
........if True:
............debug("Definitely true", 1) # shows outout 1 tab indented
........debug("how is this called?", steps=5)

class MyProduct:
....def foo(self, x):
........debug("We're calling foo() with %r" % x)
........if True:
............debug("Definitely true", 1)
........debug("how is this called?", steps=3)

....def bar1(self):
........self.bar2("anything")

....def bar2(self, x):
........self.foo(x)

m = MyProduct()
m.bar1()

And the outcome of this is:
We're calling foo() with 'anything' (foo:52)
Definitely true (foo:54)
how is this called? (foo:55, bar2:61, bar1:58)

(the numbers mean which line in the code from which they're being called)


Comments:

No Comments