python: the dangers of assert

I ran into a piece of code that looked like this:

import threading

class A(threading.Thread):
    def run(self):
        self.foo()

    def foo(self):
        assert(threading.currentThread() != self, "Blah?")
        print threading.currentThread() == self

a = A()
a.start()
a.foo()
a.join()

In the original code, there was no a.foo() invocation, because that would have triggered the assertion. Or so it was thought. I added it for my own edification.

The intention was for the foo() method to be callable only from within the running thread. In my quick test above, a.foo() should have failed.

There were two problems with that piece of code. First, it was not failing. Second, in python 2.6 you get a warning whenever you use assert with paranthesis. This is very deliberate, since assert is not a function. Using paranthesis will simply pass a tuple to the assert construct, and the tuple will always evaluate to True.

Very dutifully, I removed the paranthesis, and moved on to do some other things (and I even forgot I did it). A few days later, a coworker reported problems with the code.

As it turned out, the assert was hiding a very old bug – the condition should have checked for equality, not inequality. But since the condition _and_ the error message were paranthesized, the code passed no matter what you did. Removing the warning uncovered the problem, probably 3 years later.

2 thoughts on “python: the dangers of assert

  1. misa

    I tried to use blockquote but that was not the right tag. I fixed the formatting – if this is what you meant.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>