Who wants to see something really ugly?

Posted on Tuesday, 6 July 2010

I think it should be abundantly clear from my postings here that I'm not a very good programmer, and this means I give myself a lot of free rope to do some very stupid things.

I'm in constant need of debugging information and in Terminator particularly where we have lots of objects all interacting and reparenting all the time. We've had a simple dbg() method for a long time, but I was getting very bored of typing out dbg('Class::method:: Some message about %d' % foo), so I decided to see what could be done about inferring the Class and method parts of the message.

It turns out that python is very good at introspecting its own runtime, so back in January, armed with my own stupidity and some help from various folks on the Internet, I came up with the following:

# set this to true to enable debugging output
DEBUG = False
# set this to true to additionally list filenames in debugging
# list of classes to show debugging for. empty list means show all classes
# list of methods to show debugging for. empty list means show all methods

def dbg(log = ""):
"""Print a message if debugging is enabled"""
stackitem = inspect.stack()[1]
parent_frame = stackitem[0]
method = parent_frame.f_code.co_name
names, varargs, keywords, local_vars = inspect.getargvalues(parent_frame)
self_name = names[0]
classname = local_vars[self_name].__class__.__name__
except IndexError:
classname = "noclass"
line = stackitem[2]
filename = parent_frame.f_code.co_filename
extra = " (%s:%s)" % (filename, line)
extra = ""
if DEBUGCLASSES != [] and classname not in DEBUGCLASSES:
if DEBUGMETHODS != [] and method not in DEBUGMETHODS:
print >> sys.stderr, "%s::%s: %s%s" % (classname, method, log, extra)
except IOError:

How's about that for shockingly bad? ;)
It also adds a really impressive amount of overhead to the execution time.
I added the DEBUGCLASSES and DEBUGMETHODS lists so I could cut down on the huge amount of output - these are hooked up to command line options, so you can do something like "terminator -d --debug-classes=Terminal" and only receive debugging messages from the Terminal module.

I'm not exactly sure what I hope to gain from this post, other than ridicule on the Internet, but maybe, just maybe, someone will pop up and point out how stupid I am in a way that turns this into a 2 line, low-overhead function :D


  1. Hint: you need automated tests. :)

  2. Jamu: I don't disagree - you and Rob keep bashing me about this and you're both quite right.
    What I lack is the knowledge of how to go about doing them. It's fine for you guys, you're professional developers who can afford to take the time to experiment and learn and find out the best ways of doing things.

    I need one of you to either show me or write a "how a dummy can go from zero knowledge about testing to a useful set of tests for a simple project, with lots of examples" howto ;)

    (I hope that doesn't sound too whiney, I don't actually expect people to give up their time for my nonsense, I just meant to say that I refuse to invest the time in bootstrapping the knowledge of automated testing, I just want to leech off the hard work of others. I mean stand on the shoulders of giants ;)

  3. To add some more context to my comment - it is because I'm lazy, but also I'm not really a programmer. So much work has been done on testing and I'd really like to be able to benefit from the work of people far far better than me at this and I suspect others would benefit from this too.

    Perhaps I'm being silly and there are already lots of simple guides out there, in which case I'll gladly accept a URL :D

  4. Here's a URL that could be useful: http://docs.python.org/library/unittest.html

  5. Have you heard about the logging module? I'm not exactly sure about how it may tackle your problem, but I found it very useful some time ago when writing my backup solution.